Confronto delle stringhe usando '==' vs. 'strcmp ()'


334

Sembra che l' ===operatore di PHP sia sensibile al maiuscolo / minuscolo. Quindi c'è un motivo per usare strcmp()?

È sicuro fare qualcosa di simile al seguente?

if ($password === $password2) { ... }

10
Cosa c'entra la distinzione tra maiuscole e minuscole strcmp?
kennytm,

1
@KennyTM: distingue tra strcmpmaiuscole e minuscole. In alcune lingue, come VB, il confronto delle stringhe potrebbe non esserlo, e quindi restituirebbe un risultato diverso. Questo non è il caso di PHP, comunque.
cHao,

13
@jie: potresti voler usare ===invece di ==perché '0XAB' == '0xab'è vero.
kennytm,

17
usare === invece di == è importante, perché il confronto di qualsiasi stringa con 0 con == restituirà true, il che è ovviamente falso ...
Karl Adler,

4
@Kenny Anche '0xAB' == '171'
Antimonio

Risposte:


329

Il motivo per usarlo è perché strcmp

restituisce <0 se str1 è inferiore a str2; > 0 se str1 è maggiore di str2 e 0 se sono uguali.

===restituisce solo trueo false, non ti dice quale sia la stringa "maggiore".


9
anche se nel mio caso attuale, non ho bisogno di sapere quale stringa è maggiore :)
Jiew Meng,

155
strcmp con stringhe corrispondenti ha impiegato 0,207852 secondi strcmp con stringhe non corrispondenti ha impiegato 0,215276 secondi === con stringhe corrispondenti ha impiegato 0,067122 secondi === con stringhe non corrispondenti ha impiegato 0,057305 secondi snipplr.com/view/758

3
L'altro utilizzo per strcmp mostra l'ordinamento. Per essere più chiari sull'ordinamento. strcmp () restituisce <0 se stringa1 ordina prima di stringa2,> 0 se stringa2 ordina prima di stringa1 o 0 se sono uguali. Ad esempio $ string_first = "aabo"; $ string_second = "aaao"; echo $ n = strcmp ($ string_first, $ string_second); restituirà maggiore di zero, poiché aaao sta ordinando prima di aabo.
HTML Man

20
Perché questa risposta ottiene il maggior numero di voti? Sto votando perché anche se è la risposta che questa domanda merita ma non la risposta "giusta". La risposta giusta dovrebbe essere "Usa ===" come molte persone hanno già detto in altre risposte.
onur güngör

2
@onur Güngör In realtà, questo non risponde alla domanda del PO, che è So is there any reason to use strcmp() ?, mentre la risposta di Postfuturist non lo fa. Oh, l'inferno ... nessuno risposta sembrò per compilare in una sola volta l' uso di strcmp(), la prestazione di ===, e il cattivo affidabilità di ==per i confronti di stringhe ... quindi il mio ho aggiunto alla lista.
Balmipour,

222

Non si dovrebbe mai usare ==per il confronto delle stringhe. ===va bene

$something = 0;
echo ('password123' == $something) ? 'true' : 'false';

Basta eseguire il codice sopra e vedrai perché.

$something = 0;
echo ('password123' === $something) ? 'true' : 'false';

Ora va un po 'meglio.


19
== non è solo un problema per tipi diversi. A volte darà risultati inaspettati anche se entrambi i lati sono una stringa. Prova '1e3' == '1000'
Antimonio

3
come fa 0 == 'password123'?
Andy Lobel,

24
@AndyLobel PHP costringe 'password123' a un numero usando le sue strane regole di confronto libere poiché l'altro operando è un numero, quella stringa, come la maggior parte, si costringe al numero 0 e PHP restituisce vero per il confronto.
postfuturista il

8
Una rapida var_dump ((int) 'password123'); mi ha aiutato a capire fino in fondo perché è successo ... ** imbarazzato ** ... Mi piace molto l'operatore ===
Carlton,

3
questo perché l'uso di "==" se uno dei due operandi è numerabile, php esegue il cast di entrambi gli operandi su numeri e altro ancora, se una stringa non numerica viene lanciata su numero, assume il valore zero, risultando uguale a zero, quindi il risultato del confronto con un semplice '==' può qualcosa di indesiderato
Luca C.

98

Non utilizzare ==in PHP. Non farà ciò che ti aspetti. Anche se stai confrontando le stringhe con le stringhe, PHP le lancerà implicitamente su float e farà un confronto numerico se appaiono numeriche.

Ad esempio, '1e3' == '1000'restituisce true. Dovresti usare ===invece.


16
Ma puoi solo ===.
Roman Newaza,

11
@Roman sì, ma molti programmatori PHP non sanno che devono farlo. Da qui l'avvertimento.
Antimonio

5
@Antimonio Allora perché non dire loro cosa dovrebbero fare nella tua risposta?
Tim

43

Beh .. secondo questa segnalazione di bug php , puoi persino ottenere 0wned.

<?php 
    $pass = isset($_GET['pass']) ? $_GET['pass'] : '';
    // Query /?pass[]= will authorize user
    //strcmp and strcasecmp both are prone to this hack
    if ( strcasecmp( $pass, '123456' ) == 0 ){
      echo 'You successfully logged in.';
    }
 ?>

Ti dà un avvertimento, ma ignora comunque il confronto.
Dovresti fare ===come suggerito da @postfuturist.


5
Wow +1. Citazione dal link: "È stato stabilito un comportamento per la funzione che riceve il tipo errato di argomento (i) per restituire null". È sorprendente considerando che il manuale dice solo questo: "Restituisce <0 se str1 è minore di str2;> 0 se str1 è maggiore di str2 e 0 se sono uguali". Null non è menzionato come una possibilità, tuttavia su pagine come la pagina man substr è menzionato. sospiro
Gerry

Ma lo stesso succede quando il metodo del modulo è post ...?
3lokh,

@NikhilGeorge Sì, la funzione in questione qui è strcmp. Non importa con quali input vengono confrontati.
Ajith,

Mentre la segnalazione di bug dice che andava bene restituire null, questo non è corretto. Tutte le versioni ufficiali di PHP da PHP 4.3 a PHP 7.3 non restituiscono null da queste funzioni. Sospetto che potrebbe essere stata una versione alpha o beta e, indipendentemente dal fatto che il bug che si sta chiudendo non sia valido, è stato risolto. Vedere 3v4l.org/Zq8tM per i dettagli, che mostrano che influenza HHVM 3.11 - 3.19.
Timo Tijhof,

33

Ricorda sempre, quando confronti le stringhe, dovresti usare l' ===operatore (confronto rigoroso) e non l' == operatore (confronto libero).


8
In realtà, penso che sia sicuro dire che dovresti usare ===quando paragoni qualcosa .
rink.attendant.6

22

Riassumendo tutte le risposte:

  • ==è una cattiva idea per i confronti di stringhe.
    Ti darà risultati "sorprendenti" in molti casi. Non fidarti.

  • === va bene e ti darà le migliori prestazioni.

  • strcmp() deve essere utilizzato se è necessario determinare quale stringa è "maggiore", in genere per le operazioni di ordinamento.


20

L'uso ==potrebbe essere pericoloso.

Si noti che lancerebbe la variabile su un altro tipo di dati se i due differiscono.

Esempi:

  • echo (1 == '1') ? 'true' : 'false';
  • echo (1 == true) ? 'true' : 'false';

Come puoi vedere, questi due sono di diversi tipi, ma il risultato è trueche potrebbe non essere quello che il tuo codice si aspetta.

L'uso ===, tuttavia, è raccomandato poiché il test mostra che è un po 'più veloce di strcmp()e la sua alternativa insensibile al maiuscolo / minuscolo strcasecmp().

Googling veloce urla questo confronto di velocità: http://snipplr.com/view/758/


1
A volte li lancia in un tipo diverso anche se hanno già lo stesso tipo.
Antimonio

anche quando si confrontavano due stringhe che rappresentavano un numero intero come "012" == "12"php, il tipo di entrambe le stringhe veniva cambiato in intero 12 == 12e quindi restituito true.
Vai al



4

È possibile utilizzare strcmp()se si desidera ordinare / confrontare le stringhe lessicograficamente . Se vuoi solo verificare l'uguaglianza, allora ==va bene.


1
Come in usort . In effetti, è praticamente progettato per l'ordinamento.
Charles,

@Charles Grazie. Wikipedia mi ha fatto brillare gli occhi.
cbednarski,

1
Per essere più chiari sull'ordinamento. strcmp () restituisce <0 se stringa1 ordina prima di stringa2,> 0 se stringa2 ordina prima di stringa1 o 0 se sono uguali. Ad esempio $ string_first = "aabo"; $ string_second = "aaao"; echo $ n = strcmp ($ string_first, $ string_second); restituirà maggiore di zero, poiché aaao sta ordinando prima di aabo.
HTML Man

@postfuturist Sono sicuro che sia un errore di battitura e intendevano dire ===.
ash

4

Inoltre, la funzione può aiutare nell'ordinamento. Per essere più chiari sull'ordinamento. strcmp () restituisce meno di 0 se stringa1 ordina prima di stringa2, maggiore di 0 se stringa2 ordina prima di stringa1 o 0 se sono uguali. Per esempio

$first_string = "aabo";
$second_string = "aaao";
echo $n = strcmp($first_string,$second_string);

La funzione restituirà maggiore di zero, poiché aaao sta ordinando prima di aabo.


0

PHP Invece di utilizzare l'ordinamento alfabetico, utilizzare il valore ASCII del carattere per effettuare il confronto. Le lettere minuscole hanno un valore ASCII più elevato rispetto alle maiuscole. È meglio usare l'operatore di identità === per fare questo tipo di confronto. strcmp () è una funzione per eseguire confronti binari di stringhe sicure. Prende due stringhe come argomenti e restituisce <0 se str1 è minore di str2; > 0 se str1 è maggiore di str2 e 0 se sono uguali. C'è anche un case-insensitive versione denominata strcasecmp () che converte prima stringhe di lettere minuscole e poi li confronta.


0

if ($password === $password2) { ... }non è una cosa sicura da fare quando si confrontano password o hash di password in cui uno degli ingressi è controllato dall'utente.
In tal caso crea un oracolo temporale che consente a un utente malintenzionato di ricavare l'hash della password effettiva dalle differenze di tempo di esecuzione.
Utilizzare if (hash_equals($password, $password2)) { ... }invece, poiché hash_equals esegue il "confronto di stringhe sicure con attacco a tempo".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.