Estoy buscando la alternativa de mysql_real_escape_string()
SQL Server. ¿Es addslashes()
mi mejor opción o hay otra función alternativa que se puede utilizar?
mysql_error()
También sería útil una alternativa para .
Estoy buscando la alternativa de mysql_real_escape_string()
SQL Server. ¿Es addslashes()
mi mejor opción o hay otra función alternativa que se puede utilizar?
mysql_error()
También sería útil una alternativa para .
Respuestas:
addslashes()
no es del todo adecuado, pero el paquete mssql de PHP no ofrece ninguna alternativa decente. La solución fea pero completamente general es codificar los datos como una cadena de bytes hexadecimal, es decir
$unpacked = unpack('H*hex', $data);
mssql_query('
INSERT INTO sometable (somecolumn)
VALUES (0x' . $unpacked['hex'] . ')
');
Abstraído, eso sería:
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()
equivalente es 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.
creo que este método puede ser correcto solo si funciona con todos los tipos de datos MSSQL.
mssql_escape()
función devuelta no lo hace por mí. La pantalla de texto después de hacer una selección se ve 0x4a2761696d65206269656e206c652063686f636f6c6174
así, ilegible.
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 código aquí fue extraído de CodeIgniter. Funciona bien y es una solución limpia.
EDITAR: Hay muchos problemas con ese fragmento de código anterior. No use esto sin leer los comentarios para saber cuáles son. Mejor aún, no use esto en absoluto. Las consultas parametrizadas son tus amigos: http://php.net/manual/en/pdo.prepared-statements.php
preg_replace
? ¿No es str_replace
suficiente?
empty($value)
devolverá true
no solo para ''
, sino también para null
, 0
y '0'
! Devolvería una cadena vacía en todos esos casos.
¿Por qué se molestaría en escapar de algo cuando puede utilizar parámetros en su consulta?
sqlsrv_query(
$connection,
'UPDATE some_table SET some_field = ? WHERE other_field = ?',
array($_REQUEST['some_field'], $_REQUEST['id'])
)
Funciona bien en selecciones, eliminaciones, actualizaciones independientemente de si los parámetros de sus valores lo son null
o no. Haga una cuestión de principio: no concatenar SQL y siempre estará seguro y sus consultas se leerán mucho mejor.
Puede buscar en la biblioteca PDO . Puede usar declaraciones preparadas con PDO, que escapará automáticamente de cualquier carácter incorrecto en sus cadenas si hace las declaraciones preparadas correctamente. Esto es solo para PHP 5, creo.
Otra forma de manejar comillas simples y dobles es:
function mssql_escape($str)
{
if(get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
return str_replace("'", "''", $str);
}
Para escapar de las comillas simples y dobles, debe duplicarlas:
$value = 'This is a quote, "I said, 'Hi'"';
$value = str_replace( "'", "''", $value );
$value = str_replace( '"', '""', $value );
$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";
etc ...
y atribución: carácter de escape en Microsoft SQL Server 2000
Después de luchar con esto durante horas, se me ocurrió una solución que se siente casi mejor.
La respuesta de Chaos de convertir valores a cadenas hexadecimales no funciona con todos los tipos de datos, específicamente con columnas de fecha y hora.
Yo uso PHP PDO::quote()
, pero como viene con PHP, PDO::quote()
no es compatible con MS SQL Server y devuelve FALSE
. La solución para que funcionara fue descargar algunos paquetes de Microsoft:
Después de eso, puede conectarse en PHP con PDO usando un DSN como el siguiente ejemplo:
sqlsrv:Server=192.168.0.25; Database=My_Database;
El uso de los parámetros UID
y PWD
en el DSN no funcionó, por lo que el nombre de usuario y la contraseña se pasan como segundo y tercer parámetro en el constructor de PDO al crear la conexión. Ahora puedes usar PHP PDO::quote()
. Disfrutar.
Una respuesta de 2009-02-22T121000 por el caos de usuarios no se ajusta a todas las consultas.
Por ejemplo, "CREATE LOGIN [0x6f6c6f6c6f] FROM WINDOWS" te dará una excepción.
PD: mire el controlador de SQL Server para PHP, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx y la función sqlsrv_prepare, que puede enlazar parámetros.
PSS: que tampoco le ayudó con la consulta anterior;)
Advertencia: esta función fue ELIMINADA en PHP 7.0.0.
http://php.net/manual/en/function.mssql-query.php
Para cualquiera que todavía use estas funciones mssql_ *, tenga en cuenta que se han eliminado de PHP a partir de la v7.0.0. Entonces, eso significa que eventualmente tendrá que reescribir el código de su modelo para usar la biblioteca PDO, sqlsrv_ *, etc. Si está buscando algo con un método de "cotización / escape", recomendaría PDO.
Las alternativas a esta función incluyen: PDO :: query (), sqlsrv_query () y odbc_exec ()
Si está usando PDO, puede usar el PDO::quote
método.
Es mejor escapar también de las palabras reservadas SQL. Por ejemplo:
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;
}
He estado usando esto como una alternativa de 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));
Para que la conversión vuelva a obtener los valores hexadecimales en SQL en ASCII, aquí está la solución que obtuve (usando la función del caos del usuario para codificar en hexadecimal)
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);
Se podría rodar su propia versión de mysql_real_escape_string
, (y mejorarlo) con la siguiente expresión regular: [\000\010\011\012\015\032\042\047\134\140]
. Eso se ocupa de los siguientes caracteres: nulo, retroceso, tabulación horizontal, nueva línea, retorno de carro, sustituto, comillas dobles, comillas simples, barra invertida, acento grave. El retroceso y la pestaña horizontal no son compatibles con mysql_real_escape_string
.