2015-05-19 14 views
5

Ho il codice che controlla i cookie degli utenti:PHP stringa '==' restituisce false sul stesse stringhe

echo 'prev: ' . $prevCookie; 
echo 'curr: ' . $currentCookie; 
if ((string) $prevCookie == (string)$currentCookie) { 
    echo 'same cookies'; 
} else { 
    echo 'different cookies'; 
} 

In approximatelly 0,1% dei casi sto ottenendo seguente:

// prev: xxx 
// curr: xxx 
// different cookies 

Come quella roba può succedere?

PS. Le stringhe sono tagliate, senza spazi aggiuntivi.

UPDATE

posso fornire con valori reali che vengono memorizzati nel db, ma sono lo stesso: (diretto), (organico), YandexCPC ecc Sarebbe molto facile se potessi per riprodurlo in qualche modo.

+3

Esce 'echo strlen ($ prevCookie);' e 'echo strlen ($ currentCookie);' produce lo stesso risultato? – MonkeyZeus

+5

esegui 'var_dump ($ prevCookie)' e 'var_dump ($ currentCookie)' e pubblica i risultati nella tua domanda –

+4

0,1% del tempo in cui le stringhe non sono le stesse. – AbraCadaver

risposta

3

La mia ipotesi è che le stringhe abbiano alcuni caratteri che non sono visibili.

Si consideri il seguente:

$a = "abc"; 
$b = "abc\0"; 
echo (int)($a == $b); 

Questo eco 0.

Ma, se si echo $a e $b, potrete vedere "abc".


Un'altra possibilità potrebbe essere che si sta leggendo/scrivendo un file utilizzando fopen() senza l'opzione b.

Windows ha una funzione che converte \r e \n in \r\n.

Quando si legge indietro, viene fornito con terminazioni di linea di Windows.

Quando si confronta, i valori sono diversi, poiché \r (in memoria/cookie) non è lo stesso di \r\n (letto dal file).

Quando lo si invia a un browser , viene visualizzato come abc. I browser ignorano gli spazi bianchi nell'output (modificabili con i CSS).


Un'altra cosa potrebbe essere implicita conversione numerica.

Si consideri il seguente codice:

echo '1000000000000000000000000000000000000000000000000' == '1.0E+48'; 

Questo eco 1.Controlla qui: http://sandbox.onlinephpfunctions.com/code/1debf1a505793e3d0fde3b174c26e1f1454ea1e2

L'utilizzo di === risolve questo problema.

Qualcosa di simile potrebbe accadere. Ma questo mostra l'oposite (2 stringhe diverse che non sono uguali rispetto a quella restituisce true).


La fonte e l'ambiente stesso sono sconosciuti.

Come pure i valori ottenuti sono sconosciuti.

Ci sono troppe incognite ...

+0

Penso che questo sia praticamente tutto! Ora ho riprodotto il bug e domani distribuirò i cambiamenti. Quale pensi sia il modo migliore per sfuggire a questo problema? –

+0

@survex Filtra i cookie con 'trim()' prima di confrontarli. Questa funzione rimuove i simboli invisibili più comuni dall'inizio e dalla fine di una stringa. – Havenard

+0

@survex Ci sono molte incognite. Non so dove fosse il '$ prevCookie' memorizzato prima. Non so cosa viene in '$ currentCookie'. Ma la cosa migliore sarebbe quella di 'trim()' e usare 'str_replace (" \ 0 ", '', $ cookie)'. Inoltre, usa '===' invece. –

0

Utilizzare strcmp (maiuscole e minuscole) o strcasecmp (senza distinzione tra maiuscole e minuscole).

Per il confronto delle stringhe, nella maggior parte delle lingue, non è una buona soluzione utilizzare il confronto diretto con le stringhe.

echo 'prev: ' . $prevCookie; 
echo 'curr: ' . $currentCookie; 
if (strcmp($prevCookie,$currentCookie) === 0) { 
    echo 'same cookies'; 
} else { 
    echo 'different cookies'; 
} 
+0

Non vedo come usare 'strcmp()' produrrà un comportamento diverso rispetto all'uso di '=='. – Havenard

+0

Funzionerà! Non va bene confrontare la stringa diretta ... – Victor

+0

Se la funzione esiste significa che l'equals '==' controllerà se la variabile è la stessa, non lo stesso valore. – Victor

0

A volte, quando debuggin l'IDE mostra lo stesso valore, ma per esempio se si sta confrontando un valore globale funzione all'interno e non devi dichiarare il risultato non sarà lo stesso esempio

non funziona

function compare($p){ 
    return $p == $z; 
} 

Lavoreranno

function compare($p){ 
global $z; 
return $p == $z; 
} 
Problemi correlati