Je recherche l'alternative de mysql_real_escape_string()
SQL Server. Est addslashes()
ma meilleure option ou il y a une autre fonction alternative qui peut être utilisée?
Une alternative pour mysql_error()
serait également utile.
Je recherche l'alternative de mysql_real_escape_string()
SQL Server. Est addslashes()
ma meilleure option ou il y a une autre fonction alternative qui peut être utilisée?
Une alternative pour mysql_error()
serait également utile.
Réponses:
addslashes()
n'est pas tout à fait adéquat, mais le package mssql de PHP ne fournit aucune alternative décente. La solution laide mais tout à fait générale consiste à encoder les données sous forme de chaîne d'octets hexadécimale, c'est-à-dire
$unpacked = unpack('H*hex', $data);
mssql_query('
INSERT INTO sometable (somecolumn)
VALUES (0x' . $unpacked['hex'] . ')
');
Résumé, ce serait:
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'équivalent est 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.
je pense que cette méthode ne peut être correcte que si elle fonctionne avec tous les types de données MSSQL.
mssql_escape()
fonction retournée ne le fait pas pour moi. L'affichage du texte après avoir fait une sélection ressemble à ceci 0x4a2761696d65206269656e206c652063686f636f6c6174
donc illisible.
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;
}
Une partie du code ici a été arrachée à CodeIgniter. Fonctionne bien et est une solution propre.
EDIT: Il y a beaucoup de problèmes avec cet extrait de code ci-dessus. Veuillez ne pas l'utiliser sans lire les commentaires pour savoir de quoi il s'agit. Mieux encore, ne l'utilisez pas du tout. Les requêtes paramétrées sont vos amis: http://php.net/manual/en/pdo.prepared-statements.php
preg_replace
? N'est-ce pas str_replace
suffisant?
empty($value)
retournera true
non seulement pour ''
, mais aussi pour null
, 0
et '0'
! Vous renverriez une chaîne vide dans tous ces cas.
Pourquoi voudriez-vous échapper à quoi que ce soit lorsque vous pouvez utiliser des paramètres dans votre requête?!
sqlsrv_query(
$connection,
'UPDATE some_table SET some_field = ? WHERE other_field = ?',
array($_REQUEST['some_field'], $_REQUEST['id'])
)
Cela fonctionne directement dans les sélections, les suppressions et les mises à jour, que vos paramètres de valeurs soient null
ou non. Faites une question de principe - Ne concaténez pas SQL et vous êtes toujours en sécurité et vos requêtes se lisent beaucoup mieux.
Vous pouvez consulter la bibliothèque PDO . Vous pouvez utiliser des instructions préparées avec PDO, qui échapperont automatiquement à tous les mauvais caractères de vos chaînes si vous exécutez correctement les instructions préparées. C'est pour PHP 5 seulement je pense.
Une autre façon de gérer les guillemets simples et doubles est:
function mssql_escape($str)
{
if(get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
return str_replace("'", "''", $str);
}
Pour éviter les guillemets simples et doubles, vous devez les doubler:
$value = 'This is a quote, "I said, 'Hi'"';
$value = str_replace( "'", "''", $value );
$value = str_replace( '"', '""', $value );
$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";
etc...
et attribution: caractère d'échappement dans Microsoft SQL Server 2000
Après avoir lutté avec cela pendant des heures, j'ai trouvé une solution qui semble presque la meilleure.
La réponse de Chaos concernant la conversion des valeurs en hexstring ne fonctionne pas avec tous les types de données, en particulier avec les colonnes datetime.
J'utilise PHP PDO::quote()
, mais comme il est livré avec PHP, PDO::quote()
n'est pas pris en charge pour MS SQL Server et renvoie FALSE
. La solution pour que cela fonctionne était de télécharger des bundles Microsoft:
Après cela, vous pouvez vous connecter en PHP avec PDO en utilisant un DSN comme l'exemple suivant:
sqlsrv:Server=192.168.0.25; Database=My_Database;
L'utilisation des paramètres UID
et PWD
dans le DSN ne fonctionnait pas, donc le nom d'utilisateur et le mot de passe sont passés comme deuxième et troisième paramètres sur le constructeur PDO lors de la création de la connexion. Vous pouvez maintenant utiliser PHP PDO::quote()
. Prendre plaisir.
Une réponse du 2009-02-22T121000 par chaos d' utilisateur ne convient pas à toutes les requêtes.
Par exemple, "CREATE LOGIN [0x6f6c6f6c6f] FROM WINDOWS" vous donnera une exception.
PS: regardez le pilote SQL Server pour PHP, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx et la fonction sqlsrv_prepare, qui peut lier des paramètres.
PSS: Ce qui ne vous a pas non plus aidé avec la requête ci-dessus;)
Attention: cette fonction a été SUPPRIMÉE dans PHP 7.0.0.
http://php.net/manual/en/function.mssql-query.php
Pour quiconque utilise encore ces fonctions mssql_ *, gardez à l'esprit qu'elles ont été supprimées de PHP à partir de la v7.0.0. Donc, cela signifie que vous devrez éventuellement réécrire le code de votre modèle pour utiliser la bibliothèque PDO, sqlsrv_ * etc. Si vous cherchez quelque chose avec une méthode "citant / échappant", je recommanderais PDO.
Les alternatives à cette fonction incluent: PDO :: query (), sqlsrv_query () et odbc_exec ()
Si vous utilisez PDO, vous pouvez utiliser la PDO::quote
méthode.
Pour que la conversion récupère les valeurs hexadécimales en SQL en ASCII, voici la solution que j'ai obtenue (en utilisant la fonction du chaos utilisateur pour encoder en hexadécimal)
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);
Il est préférable d'échapper également aux mots réservés SQL. Par exemple:
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;
}
Vous pouvez rouler votre propre version de mysql_real_escape_string
(et l' améliorer) avec l'expression régulière suivante: [\000\010\011\012\015\032\042\047\134\140]
. Cela prend en charge les caractères suivants: null, retour arrière, tabulation horizontale, nouvelle ligne, retour chariot, remplacement, guillemet double, guillemet simple, barre oblique inverse, accent grave. L'espace arrière et l'onglet horizontal ne sont pas pris en charge par mysql_real_escape_string
.