Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

This question already has an answer here:

I'm looking for the alternative of mysql_real_escape_string() for SQL Server. Is addslashes() my best option or there is another alternative function that can be used?

Edit: Alternative for mysql_error() would also be useful.

share|improve this question
1  
For me it's not a duplicate question because it concerns the specific MSSQL case that doesn't have a related official PDO – Pierre de LESPINAY Mar 4 at 16:26

marked as duplicate by tereško, PeeHaa, Henry, Anders R. Bystrup, Julius Feb 10 at 8:35

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

7 Answers

up vote 34 down vote accepted

addslashes() isn't fully adequate, but PHP's mssql package doesn't provide any decent alternative. The ugly but fully general solution is encoding the data as a hex bytestring, i.e.

$unpacked = unpack('H*hex', $data);
mssql_query('
    INSERT INTO sometable (somecolumn)
    VALUES (0x' . $unpacked['hex'] . ')
');

Abstracted, that would be:

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() equivalent is mssql_get_last_message().

share|improve this answer
Do you know the equivalent for mysql_insert_id() by any chance? – Click Upvote Feb 22 '09 at 12:20
   
Yeah, you do a SELECT @@IDENTITY. – chaos Feb 22 '09 at 12:24
Chaos, can you please give an example of an 'escape' function which would take a string as argument and return the hex alternative as a result using the method you gave? I'll accept your answer then – Click Upvote Feb 22 '09 at 12:26
1  
Oops, its SELECT SCOPE_IDENTITY()! – Bryan Rehbein Mar 2 '09 at 19:47
3  
@genio: Mmm, great, except it actually is. I don't suppose you'd explain what you consider to be the problem? – chaos Mar 28 '10 at 1:50
show 16 more comments
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;
    }

Some of the code here was ripped off from CodeIgniter. Works well and is a clean solution.

share|improve this answer
1  
Confirmed to work!! Thanks man! – KyleFarris Mar 26 '10 at 21:03
Why do you need the preg_replace? Isn't the str_replace sufficient? – Gabe Mar 26 '10 at 21:05
   
gabe: The preg_replace in this case was to allow me to use the ranges afforded to me in regular expressions character classes. There would be a lot more string replaces in this one otherwise. – genio Mar 26 '10 at 21:07
3  
-1. It is not the responsibility of a quoting function to mangle data -- all it should do is make sure the string is in such a format that it can be added to an SQL statement and survive unmodified. – cHao Jul 15 '10 at 6:38
4  
Sorry, but this is wrong from the first line of code - empty($value) will return true not only for '', but also for null, 0 and '0'! You would return an empty string in all those cases. – Nux Dec 25 '10 at 13:45
show 1 more comment

You could look into the PDO Library. You can use prepared statements with PDO, which will automatically escape any bad characters in your strings if you do the prepared statements correctly. This is for PHP 5 only I think.

share|improve this answer
With some of the halfassed behavior I've seen out of PDO, I'd have to do some serious testing before I trusted it to escape all data correctly. – chaos Feb 22 '09 at 12:11
@Chaos Really ? I'm unaware of this.. do you have a link to an article? – alex Feb 22 '09 at 12:14
What I was thinking of was the trouble this guy on here was having yesterday with PDO. Unrelated transaction stuff, but unimpressive. Combine that with all the history of inadequate data escaping in PHP (php.net telling people to use addslashes()!) and I get very suspicious. – chaos Feb 22 '09 at 12:22
Hmmm.. well hopefully they got the escaping portion correct. – alex Feb 22 '09 at 12:33
1  
I love PDO and tried that first, but the one for MSSQL (on Unix, based on dblib) sometimes fails on me (segmentation fault), that's why I resorted to the mssql_escape defined above. – lapo Sep 6 '11 at 20:58

i know, litle bit late, but answer from 'Feb 22 '09 at 12:10' by chaos isn`t fit all queries. E.g: "CREATE LOGIN [0x6f6c6f6c6f] FROM WINDOWS" will give you exception

p.s. look at mssql driver for php, http://msdn.microsoft.com/library/cc296181%28v=sql.90%29.aspx and sqlsrv_prepare function, which can binds params.

p.s.s. which also didn`t helps you with query above ;)

share|improve this answer

After struggling with this for hours, I've come with a solution that feels almost the rightest.

Chaos' answer of converting values to hexastring doesn't works with every datatype, specifically with datetime columns.

I use PHP's PDO::quote(), but as it comes with PHP, PDO::quote() is not supported for MS SQL Server and returns FALSE. The solution for it to work was download some Microsoft's bundles:

After that you can connect in PHP with PDO using a DSN like the following example:

sqlsrv:Server=192.168.0.25; Database=My_Database;

Using the UID and PWD parameters in the DSN didn't worked, so username and password are passed as the second and third parameters on the PDO constructor when creating the connection. Now you can use PHP's PDO::quote(). Enjoy.

share|improve this answer

In order to escape single- and double-quotes, you have to double them up:

$value = 'This is a quote, "I said, 'Hi'"';

$value = str_replace( "'", "''", $value ); 

$value = str_replace( '"', '""', $value );

$query = "INSERT INTO TableName ( TextFieldName ) VALUES ( '$value' ) ";

etc...

and attribution: Escape Character In Microsoft SQL Server 2000

share|improve this answer

You could roll your own version of mysql_real_escape_string, (and improve upon it) with the following regular expression: [\000\010\011\012\015\032\042\047\134\140]. That takes care of the following characters: null, backspace, horizontal tab, new line, carriage return, substitute, double quote, single quote, backslash, grave accent. Backspace and horizontal tab are not supported by mysql_real_escape_string.

share|improve this answer
-1 Rolling your own is rarely the right answer. – mattbasta Jun 17 '12 at 7:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.