Sto cercando l'alternativa di mysql_real_escape_string()
per SQL Server. È la addslashes()
mia opzione migliore o esiste un'altra funzione alternativa che può essere utilizzata?
mysql_error()
Sarebbe utile anche un'alternativa a .
Sto cercando l'alternativa di mysql_real_escape_string()
per SQL Server. È la addslashes()
mia opzione migliore o esiste un'altra funzione alternativa che può essere utilizzata?
mysql_error()
Sarebbe utile anche un'alternativa a .
Risposte:
addslashes()
non è del tutto adeguato, ma il pacchetto mssql di PHP non fornisce alcuna alternativa decente. La soluzione brutta ma completamente generale è codificare i dati come una stringa esadecimale, ad es
$unpacked = unpack('H*hex', $data);
mssql_query('
INSERT INTO sometable (somecolumn)
VALUES (0x' . $unpacked['hex'] . ')
');
Estratto, sarebbe:
function mssql_escape($data) {
if(is_numeric($data))
return $data;
$unpacked = unpack('H*hex', $data);
return '0x' . $unpacked['hex'];
}
mssql_query('
INSERT INTO sometable (somecolumn)
VALUES (' . mssql_escape($somevalue) . ')
');
mysql_error()
l'equivalente è mssql_get_last_message()
.
SQLSTATE[22007]: Invalid datetime format: 210 [Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting datetime from binary/varbinary string.
credo che questo metodo possa essere corretto solo se funziona con ogni tipo di dati MSSQL.
mssql_escape()
funzione restituita non lo fa per me. Il display di testo dopo aver effettuato una selezione sembra 0x4a2761696d65206269656e206c652063686f636f6c6174
così illeggibile.
function ms_escape_string($data) {
if ( !isset($data) or empty($data) ) return '';
if ( is_numeric($data) ) return $data;
$non_displayables = array(
'/%0[0-8bcef]/', // url encoded 00-08, 11, 12, 14, 15
'/%1[0-9a-f]/', // url encoded 16-31
'/[\x00-\x08]/', // 00-08
'/\x0b/', // 11
'/\x0c/', // 12
'/[\x0e-\x1f]/' // 14-31
);
foreach ( $non_displayables as $regex )
$data = preg_replace( $regex, '', $data );
$data = str_replace("'", "''", $data );
return $data;
}
Parte del codice qui è stato strappato da CodeIgniter. Funziona bene ed è una soluzione pulita.
EDIT: ci sono molti problemi con lo snippet di codice sopra. Per favore, non usarlo senza leggere i commenti per sapere cosa sono. Meglio ancora, per favore non usarlo affatto. Le query parametrizzate sono tuoi amici: http://php.net/manual/en/pdo.prepared-statements.php
preg_replace
? Non è str_replace
sufficiente?
empty($value)
restituirà true
non solo per ''
, ma anche per null
, 0
e '0'
! Restituiresti una stringa vuota in tutti questi casi.
Perché dovresti preoccuparti di sfuggire a qualcosa quando puoi usare i parametri nella tua query ?!
sqlsrv_query(
$connection,
'UPDATE some_table SET some_field = ? WHERE other_field = ?',
array($_REQUEST['some_field'], $_REQUEST['id'])
)
Funziona correttamente in seleziona, elimina, aggiorna indipendentemente dal fatto che i parametri dei valori siano null
o meno. È una questione di principio: non concatenare SQL e sarai sempre al sicuro e le tue query si leggeranno molto meglio.
Potresti esaminare la libreria PDO . È possibile utilizzare istruzioni preparate con PDO, che eseguiranno automaticamente l'escape di eventuali caratteri errati nelle stringhe se si eseguono correttamente le istruzioni preparate. Questo è solo per PHP 5 credo.
Un altro modo per gestire virgolette singole e doppie è:
function mssql_escape($str)
{
if(get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
return str_replace("'", "''", $str);
}
Per evitare virgolette singole e doppie, devi raddoppiarle:
$value = 'This is a quote, "I said, 'Hi'"';
$value = str_replace( "'", "''", $value );
$value = str_replace( '"', '""', $value );
$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";
eccetera...
e attribuzione: carattere di fuga in Microsoft SQL Server 2000
Dopo aver lottato per ore con questo, ho trovato una soluzione che sembra quasi la migliore.
La risposta di Chaos di convertire i valori in hexstring non funziona con tutti i tipi di dati, in particolare con le colonne datetime.
Uso PHP PDO::quote()
, ma poiché viene fornito con PHP, PDO::quote()
non è supportato per MS SQL Server e restituisce FALSE
. La soluzione per farlo funzionare era scaricare alcuni bundle Microsoft:
Dopodiché puoi connetterti in PHP con PDO utilizzando un DSN come il seguente esempio:
sqlsrv:Server=192.168.0.25; Database=My_Database;
L'utilizzo dei parametri UID
e PWD
nel DSN non ha funzionato, quindi nome utente e password vengono passati come secondo e terzo parametro sul costruttore PDO durante la creazione della connessione. Ora puoi usare PHP PDO::quote()
. Godere.
Una risposta del 22-02-2009T121000 dal caos degli utenti non si adatta a tutte le domande.
Ad esempio, "CREATE LOGIN [0x6f6c6f6c6f] FROM WINDOWS" darà un'eccezione.
PS: guarda il driver SQL Server per PHP, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx e la funzione sqlsrv_prepare, che può associare i parametri.
PSS: anche questo non ti ha aiutato con la query sopra;)
Attenzione: questa funzione è stata RIMOSSA in PHP 7.0.0.
http://php.net/manual/en/function.mssql-query.php
Per chiunque utilizzi ancora queste funzioni mssql_ *, tieni presente che sono state rimosse da PHP a partire dalla v7.0.0. Quindi, ciò significa che alla fine dovrai riscrivere il codice del modello per utilizzare la libreria PDO, sqlsrv_ * ecc. Se stai cercando qualcosa con un metodo "quoting / escaping", consiglierei PDO.
Le alternative a questa funzione includono: PDO :: query (), sqlsrv_query () e odbc_exec ()
Se stai usando PDO, puoi usare il PDO::quote
metodo.
Affinché la conversione ritorni i valori esadecimali in SQL in ASCII, ecco la soluzione che ho ottenuto su questo (usando la funzione da caos utente per codificare in esadecimale)
function hexEncode($data) {
if(is_numeric($data))
return $data;
$unpacked = unpack('H*hex', $data);
return '0x' . $unpacked['hex'];
}
function hexDecode($hex) {
$str = '';
for ($i=0; $i<strlen($hex); $i += 2)
$str .= chr(hexdec(substr($hex, $i, 2)));
return $str;
}
$stringHex = hexEncode('Test String');
var_dump($stringHex);
$stringAscii = hexDecode($stringHex);
var_dump($stringAscii);
È meglio evitare anche le parole riservate SQL. Per esempio:
function ms_escape_string($data) {
if (!isset($data) or empty($data))
return '';
if (is_numeric($data))
return $data;
$non_displayables = array(
'/%0[0-8bcef]/', // URL encoded 00-08, 11, 12, 14, 15
'/%1[0-9a-f]/', // url encoded 16-31
'/[\x00-\x08]/', // 00-08
'/\x0b/', // 11
'/\x0c/', // 12
'/[\x0e-\x1f]/', // 14-31
'/\27/'
);
foreach ($non_displayables as $regex)
$data = preg_replace( $regex, '', $data);
$reemplazar = array('"', "'", '=');
$data = str_replace($reemplazar, "*", $data);
return $data;
}
L'ho usato come alternativa a mysql_real_escape_string()
:
function htmlsan($htmlsanitize){
return $htmlsanitize = htmlspecialchars($htmlsanitize, ENT_QUOTES, 'UTF-8');
}
$data = "Whatever the value's is";
$data = stripslashes(htmlsan($data));
Si potrebbe rotolare la propria versione di mysql_real_escape_string
, (e migliorare su di essa), con la seguente espressione regolare: [\000\010\011\012\015\032\042\047\134\140]
. Ciò si occupa dei seguenti caratteri: null, backspace, tabulazione orizzontale, nuova riga, ritorno a capo, sostituto, virgolette doppie, virgolette singole, barra rovesciata, accento grave. Backspace e tabulazione orizzontale non sono supportati da mysql_real_escape_string
.