Estou procurando uma alternativa mysql_real_escape_string()para o SQL Server. É a addslashes()minha melhor opção ou existe outra função alternativa que pode ser usada?
Uma alternativa para mysql_error()também seria útil.
Estou procurando uma alternativa mysql_real_escape_string()para o SQL Server. É a addslashes()minha melhor opção ou existe outra função alternativa que pode ser usada?
Uma alternativa para mysql_error()também seria útil.
Respostas:
addslashes()não é totalmente adequado, mas o pacote mssql do PHP não oferece nenhuma alternativa decente. A solução feia, mas totalmente geral, é codificar os dados como um bytestring hexadecimal, ou seja,
$unpacked = unpack('H*hex', $data);
mssql_query('
INSERT INTO sometable (somecolumn)
VALUES (0x' . $unpacked['hex'] . ')
');
Abstrato, isso seria:
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 é 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.acredito que este método pode ser correto apenas se funcionar com todos os tipos de dados MSSQL.
mssql_escape()função retornada não está fazendo isso para mim. A exibição de texto depois de fazer uma seleção fica 0x4a2761696d65206269656e206c652063686f636f6c6174assim ilegível.
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 do código aqui foi roubado do CodeIgniter. Funciona bem e é uma solução limpa.
EDIT: Existem muitos problemas com esse trecho de código acima. Por favor, não use isso sem ler os comentários para saber o que são. Melhor ainda, por favor, não use isso. As consultas parametrizadas são seus amigos: http://php.net/manual/en/pdo.prepared-statements.php
preg_replace? Não é o str_replacesuficiente?
empty($value)vai voltar truenão só para '', mas também para null, 0e '0'! Você retornaria uma string vazia em todos esses casos.
Por que você se incomodaria em escapar de qualquer coisa quando você pode usar parâmetros em sua consulta ?!
sqlsrv_query(
$connection,
'UPDATE some_table SET some_field = ? WHERE other_field = ?',
array($_REQUEST['some_field'], $_REQUEST['id'])
)
Ele funciona bem em seleções, exclusões e atualizações, independentemente de seus parâmetros de valores serem nullou não. Faça uma questão de princípio - Não concatene SQL e você estará sempre seguro e suas consultas serão lidas muito melhor.
Você pode dar uma olhada na Biblioteca PDO . Você pode usar instruções preparadas com PDO, que automaticamente escapará de quaisquer caracteres inválidos em suas strings se você fizer as instruções preparadas corretamente. Isso é apenas para PHP 5, eu acho.
Outra maneira de lidar com aspas simples e duplas é:
function mssql_escape($str)
{
if(get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
return str_replace("'", "''", $str);
}
Para escapar das aspas simples e duplas, você precisa dobrá-las:
$value = 'This is a quote, "I said, 'Hi'"';
$value = str_replace( "'", "''", $value );
$value = str_replace( '"', '""', $value );
$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";
etc ...
e atribuição: caractere de escape no Microsoft SQL Server 2000
Depois de lutar com isso por horas, eu encontrei uma solução que parece quase a melhor.
A resposta do caos de converter valores em hexstring não funciona com todos os tipos de dados, especificamente com colunas datetime.
Eu uso PHP's PDO::quote(), mas como vem com PHP, PDO::quote()não tem suporte para MS SQL Server e retorna FALSE. A solução para que funcionasse era baixar alguns pacotes da Microsoft:
Depois disso, você pode se conectar em PHP com PDO usando um DSN como o exemplo a seguir:
sqlsrv:Server=192.168.0.25; Database=My_Database;
O uso dos parâmetros UIDe PWDno DSN não funcionou, então o nome de usuário e a senha são passados como o segundo e o terceiro parâmetros no construtor PDO ao criar a conexão. Agora você pode usar PHP PDO::quote(). Aproveitar.
Uma resposta de 22-02-2009T121000 pelo caos do usuário não se aplica a todas as perguntas.
Por exemplo, "CREATE LOGIN [0x6f6c6f6c6f] FROM WINDOWS" apresentará uma exceção.
PS: veja o driver do SQL Server para PHP, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx e a função sqlsrv_prepare, que pode vincular parâmetros.
PSS: O que também não o ajudou com a consulta acima;)
Aviso: Esta função foi REMOVIDA no PHP 7.0.0.
http://php.net/manual/en/function.mssql-query.php
Para quem ainda usa essas funções mssql_ *, lembre-se de que elas foram removidas do PHP a partir da v7.0.0. Então, isso significa que você eventualmente terá que reescrever seu código de modelo para usar a biblioteca PDO, sqlsrv_ * etc. Se você estiver procurando por algo com um método "citando / escapando", eu recomendaria PDO.
Alternativas para esta função incluem: PDO :: query (), sqlsrv_query () e odbc_exec ()
Se você estiver usando PDO, você pode usar o PDO::quotemétodo.
Para a conversão para obter os valores hexadecimais em SQL de volta para ASCII, aqui está a solução que encontrei (usando a função do caos do usuário para codificar em 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);
É melhor também escapar das palavras reservadas do SQL. Por exemplo:
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;
}
Tenho usado isso como uma 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));
Você poderia rolar sua própria versão mysql_real_escape_string, (e melhorá-lo) com a seguinte expressão regular: [\000\010\011\012\015\032\042\047\134\140]. Isso cuida dos seguintes caracteres: nulo, backspace, tabulação horizontal, nova linha, retorno de carro, substituto, aspas duplas, aspas simples, barra invertida, acento grave. Backspace e tabulação horizontal não são suportados por mysql_real_escape_string.