Szukam alternatywy mysql_real_escape_string()
dla SQL Server. Czy addslashes()
moja najlepsza opcja, czy jest inna alternatywna funkcja, której można użyć?
Przydałaby się również alternatywa dla mysql_error()
.
Szukam alternatywy mysql_real_escape_string()
dla SQL Server. Czy addslashes()
moja najlepsza opcja, czy jest inna alternatywna funkcja, której można użyć?
Przydałaby się również alternatywa dla mysql_error()
.
Odpowiedzi:
addslashes()
nie jest w pełni adekwatna, ale pakiet mssql PHP nie zapewnia żadnej przyzwoitej alternatywy. Brzydkim, ale w pełni ogólnym rozwiązaniem jest kodowanie danych jako szesnastkowy bajt bajtowy, tj
$unpacked = unpack('H*hex', $data);
mssql_query('
INSERT INTO sometable (somecolumn)
VALUES (0x' . $unpacked['hex'] . ')
');
W skrócie, byłoby to:
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()
odpowiednik jest 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.
uważam, że ta metoda może być poprawna tylko wtedy, gdy działa z każdym typem danych MSSQL.
mssql_escape()
zwróconej funkcji nie robi tego za mnie. Tekst wyświetlany po dokonaniu wyboru wygląda tak, że jest 0x4a2761696d65206269656e206c652063686f636f6c6174
nieczytelny.
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;
}
Część kodu została wyrwana z CodeIgniter. Działa dobrze i jest czystym rozwiązaniem.
EDYCJA: istnieje wiele problemów z powyższym fragmentem kodu. Nie używaj tego bez czytania komentarzy, aby wiedzieć, co to jest. Jeszcze lepiej, proszę, w ogóle tego nie używaj. Sparametryzowane zapytania to Twoi przyjaciele: http://php.net/manual/en/pdo.prepared-statements.php
preg_replace
? Czy to nie str_replace
wystarczy?
empty($value)
powróci true
nie tylko ''
, ale także null
, 0
a '0'
! We wszystkich tych przypadkach zwróciłbyś pusty ciąg.
Dlaczego miałbyś zawracać sobie głowę ucieczką przed czymkolwiek, skoro możesz używać parametrów w zapytaniu ?!
sqlsrv_query(
$connection,
'UPDATE some_table SET some_field = ? WHERE other_field = ?',
array($_REQUEST['some_field'], $_REQUEST['id'])
)
Działa poprawnie w zaznaczeniach, usuwaniu i aktualizacjach, niezależnie od tego, czy parametry wartości są, null
czy nie. Kieruj się zasadą - nie łącz SQL, a zawsze będziesz bezpieczny, a Twoje zapytania będą czytane znacznie lepiej.
Możesz zajrzeć do Biblioteki PDO . Możesz używać przygotowanych instrukcji z PDO, które automatycznie usuwają wszelkie złe znaki w łańcuchach, jeśli poprawnie wykonasz przygotowane instrukcje. Myślę, że to tylko dla PHP 5.
Innym sposobem obsługi pojedynczych i podwójnych cudzysłowów jest:
function mssql_escape($str)
{
if(get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
return str_replace("'", "''", $str);
}
Aby uniknąć apostrofów i cudzysłowów, musisz je podwoić:
$value = 'This is a quote, "I said, 'Hi'"';
$value = str_replace( "'", "''", $value );
$value = str_replace( '"', '""', $value );
$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";
itp...
i przypisanie: znak ucieczki w Microsoft SQL Server 2000
Po wielu godzinach zmagań się z tym, znalazłem rozwiązanie, które wydaje się prawie najlepsze.
Odpowiedź Chaosa dotycząca konwersji wartości na ciąg szesnastkowy nie działa z każdym typem danych, szczególnie z kolumnami z datą i godziną.
Używam PHP PDO::quote()
, ale ponieważ pochodzi z PHP, PDO::quote()
nie jest obsługiwany przez MS SQL Server i zwraca FALSE
. Rozwiązaniem do jego działania było pobranie niektórych pakietów Microsoft:
Następnie możesz połączyć się w PHP z PDO używając DSN, jak w poniższym przykładzie:
sqlsrv:Server=192.168.0.25; Database=My_Database;
Używanie parametrów UID
i PWD
w DSN nie zadziałało, więc nazwa użytkownika i hasło są przekazywane jako drugi i trzeci parametr w konstruktorze PDO podczas tworzenia połączenia. Teraz możesz używać PHP PDO::quote()
. Cieszyć się.
Odpowiedź od 2009-02-22T121000 od użytkownika chaos nie pasuje do wszystkich zapytań.
Na przykład „UTWÓRZ LOGIN [0x6f6c6f6c6f] Z WINDOWS” da ci wyjątek.
PS: spójrz na sterownik SQL Server dla PHP, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx i funkcję sqlsrv_prepare, która może wiązać parametry.
PSS: Co również nie pomogło w powyższym zapytaniu;)
Ostrzeżenie: ta funkcja została USUNIĘTA w PHP 7.0.0.
http://php.net/manual/en/function.mssql-query.php
Każdy, kto nadal używa tych funkcji mssql_ *, powinien pamiętać, że zostały one usunięte z PHP w wersji 7.0.0. Oznacza to, że w końcu będziesz musiał przepisać kod modelu, aby użyć biblioteki PDO, sqlsrv_ * itd. Jeśli szukasz czegoś z metodą „cytowania / ucieczki”, polecam PDO.
Alternatywy dla tej funkcji to: PDO :: query (), sqlsrv_query () i odbc_exec ()
Jeśli używasz PDO, możesz użyć tej PDO::quote
metody.
W celu konwersji, aby uzyskać wartości szesnastkowe w SQL z powrotem do ASCII, oto rozwiązanie, które otrzymałem (używając funkcji od chaosu użytkownika do kodowania na szesnastkowy)
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);
Lepiej jest też unikać słów zastrzeżonych SQL. Na przykład:
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;
}
Używam tego jako alternatywy dla 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));
Można toczyć własną wersję mysql_real_escape_string
(i poprawić na nim) za pomocą następującego wyrażenia regularnego: [\000\010\011\012\015\032\042\047\134\140]
. To zajmuje się następującymi znakami: null, backspace, tabulator poziomy, nowa linia, powrót karetki, zamiana, podwójny cudzysłów, pojedynczy cudzysłów, ukośnik odwrotny, akcent słaby. Backspace i tabulator poziomy nie są obsługiwane przez mysql_real_escape_string
.