php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #48290 auto escape for variables in double quoted sql string
Submitted: 2009-05-15 05:49 UTC Modified: 2010-03-22 19:30 UTC
Votes:1418
Avg. Score:5.0 ± 0.1
Reproduced:1416 of 1416 (100.0%)
Same Version:1416 (100.0%)
Same OS:1416 (100.0%)
From: kexianbin at diyism dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.3.3 OS: Irrelevant
Private report: No CVE-ID: None
 [2009-05-15 05:49 UTC] kexianbin at diyism dot com
Description:
------------
Provide a function to get variables from caller scope.

I knew ticket 47454, 40339, 34210 are similar,
but this is indeed a useful function that was overlooked.

Reproduce code:
---------------
Currently:

$name="myname";
$value="lk,jdsk'jlkjdf";
function safe($sql)
         {$sql=strtr($sql, array('"'=>'\"', '\\'=>'\\\\'));
          return 'return "'.preg_replace(array('/\{#(.*?)\}/'), array('".addslashes($\1)."'), $sql).'";';
         }
$sql="insert into z_test (name, value) values ('{$name}', '{#value}')";
mysql_query(eval(safe($sql)));

If we have function get_caller_vars() in caller's scope:
(similar to get_defined_vars() in current scope)

$name="myname";
$value="lk,jdsk'jlkjdf";
function mysql_query_safe($sql)
         {extract(get_caller_vars());
          $sql=strtr($sql, array('"'=>'\"', '\\'=>'\\\\'));
          return 'return "'.preg_replace(array('/\{#(.*?)\}/'), array('".addslashes($\1)."'), $sql).'";';
          $sql=eval($sql);
          mysql_query($sql);
         }
$sql="insert into z_test (name, value) values ('{$name}', '{#value}')";
mysql_query_safe($sql);

Expected result:
----------------
We have a function to get variables in caller scope.

Actual result:
--------------
No such function.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-05-15 06:08 UTC] kexianbin at diyism dot com
You will say to use PDO, but these code is so ugly:

$sql=$pdo->prepare("select *
                    from sem_SearchChangeShow
                    where Keyword=:Keyword
                          and BatchNum=:BatchNum
                          and OldChannelID=:ApvChannelID_old
                          and OldCategoryID=:ApvCategoryID_old
                  ");
$sql->execute(array(':Keyword'=>$v['Keyword'],
                    ':BatchNum'=>$v['BatchNum'],
                    ':ApvChannelID_old'=>$v['ApvChannelID_old'],
                    ':ApvCategoryID_old'=>$v['ApvCategoryID_old']
                   )
             );
$tmp=$sql->fetch(PDO::FETCH_ASSOC);
 [2009-08-10 11:26 UTC] kexianbin at diyism dot com
Maybe currently i could write like this:

$sql=eval(safe(
     "insert into z_test (name, value) values ('{$name}', '{#value}')"
     ));
mysql_query($sql);
 [2009-08-10 12:18 UTC] kexianbin at diyism dot com
Or i could write like this:

$_='addslashes';

$sql="insert into z_test (name, value) values ('{$name}', '{$_($value)}')";
mysql_query($sql);
 [2009-08-10 12:26 UTC] kexianbin at diyism dot com
For the most convenience of we php programmers,
maybe we should make a patch to the variable parsing module of double quoted strings in the php engine,
to parse variables, while add slashes to them for such formats: "{#variable_name}",

for example:
<?
$name="myname";
$value="my'value";
echo "insert into z_test (name, value) values ('{$name}', '{#value}')";
?>
we should get:
insert into z_test (name, value) values ('myname', 'my\'value')
 [2009-08-10 13:14 UTC] jani@php.net
Will never happen. You should start using MySQLi and prepared statements.
 [2009-08-10 13:15 UTC] jani@php.net
Or PDO.. :)
 [2009-08-11 02:41 UTC] kexianbin at diyism dot com
Why set this as bogus?

Why don't you realize that the advantage of PHP is right the incredible convenience for web programmers?!

For example, 'substr' is of the best design in all these languages: java, sql, javascript, python, ruby, etc,
...substr($aStr,index_start,length(>=0)/index_after_end(<0))...
that is just the right PHP tradition.

I know PDO and prepared statements is ok,
but those method is really trivial and by no means intuitive.

Why don't you just make a little change to the variable parsing function of the double quoted strings to save we programmers a very enormous time wasting?

In fact, we have no way to reduce the code if we adopt PDO and prepared statements, obviously every variable name apears twice(even apears as a question mark):
$sql=$pdo->prepare("select *
                    from sem_SearchChangeShow
                    where Keyword=:Keyword
                          and BatchNum=:BatchNum
                          and OldChannelID=:ApvChannelID_old
                          and OldCategoryID=:ApvCategoryID_old
                  ");
$sql->execute(array(':Keyword'=>$v['Keyword'],
                    ':BatchNum'=>$v['BatchNum'],
                    ':ApvChannelID_old'=>$v['ApvChannelID_old'],
                    ':ApvCategoryID_old'=>$v['ApvCategoryID_old']
                   )
             );
$tmp=$sql->fetch(PDO::FETCH_ASSOC);
 [2009-11-10 04:12 UTC] kexianbin at diyism dot com
Try to reopen it.
 [2009-11-10 04:23 UTC] kexianbin at diyism dot com
Update expected version to 5.3.2
 [2009-11-10 04:34 UTC] rasmus@php.net
This is not going to happen.
 [2009-11-10 05:10 UTC] kexianbin at diyism dot com
Rasmus,

Why not have a think about adding addslash function to double-quoted strings?
That maybe the simplest solution for variables replacement in sql query string.

With the addslash function in double-quoted strings, we could code like this:
$rs=$pdo->query("select *
                   from sem_SearchChangeShow
                   where Keyword={#Keyword}
                         and BatchNum={#BatchNum}
                         and OldChannelID={#ApvChannelID_old}
                         and OldCategoryID={#ApvCategoryID_old}
                 ");
$data=$rs->fetch(PDO::FETCH_ASSOC);

But, without it, we have to code like these:
$sql=$pdo->prepare("select *
                   from sem_SearchChangeShow
                   where Keyword=:Keyword
                         and BatchNum=:BatchNum
                         and OldChannelID=:ApvChannelID_old
                         and OldCategoryID=:ApvCategoryID_old
                 ");
$sql->execute(array(':Keyword'=>$Keyword,
                   ':BatchNum'=>$BatchNum,
                   ':ApvChannelID_old'=>$ApvChannelID_old,
                   ':ApvCategoryID_old'=>$ApvCategoryID_old
                  )
            );
$data=$sql->fetch(PDO::FETCH_ASSOC);

Please don't set the feature request to "won't fix".
 [2009-11-10 05:17 UTC] kexianbin at diyism dot com
Rasmus, I insist that the feature request should be reopen, leave it here until some day somebody may make it realized.
 [2009-11-10 05:33 UTC] rasmus@php.net
Stop re-opening this please.  Escaping needs to be db-specific since different dbs use different escape chars.  Therefore it cannot be done generically at the language level.
 [2009-11-10 05:35 UTC] kexianbin at diyism dot com
OK, maybe there is another solution.
 [2009-11-10 07:11 UTC] kexianbin at diyism dot com
Rasmus,

Similar to this in php.ini file:

//Use Sybase-style magic quotes (escape ' with '' instead of \').
magic_quotes_sybase = Off

we could add "double_quotes_escape_for_db = mysql" into php.ini.
 [2009-11-10 07:18 UTC] kexianbin at diyism dot com
I still wanna reopen this request very much,

If anybody could realize this that will give PHP a special advantage over other languages.
 [2009-11-10 07:45 UTC] rasmus@php.net
We are trying to get rid of features like addslashes, not make more similar ones.
 [2009-11-10 09:39 UTC] kexianbin at diyism dot com
Must have a solution in the world.

If we can't build the auto escape for double quotes sql string,
we can build get_caller_vars to realize the simpler auto escape of double quotes sql string.
 [2009-11-10 09:51 UTC] kexianbin at diyism dot com
Changed the title.
 [2009-11-10 09:53 UTC] kexianbin at diyism dot com
Changed the title to "auto escape for variables in double quotes sql string".
 [2009-11-10 09:54 UTC] kexianbin at diyism dot com
auto escape for variables in double quoted sql string
 [2009-11-10 10:21 UTC] derick@php.net
Stop spamming this bug system, you use prepared statements in this case.
 [2009-11-11 01:52 UTC] kexianbin at diyism dot com
Derick,

The problem is right in prepared statements:
$sql=$pdo->prepare("select *
                    from sem_SearchChangeShow
                    where Keyword=:Keyword
                          and BatchNum=:BatchNum
                          and OldChannelID=:ApvChannelID_old
                          and OldCategoryID=:ApvCategoryID_old
                  ");
$sql->execute(array(':Keyword'=>$Keyword,
                    ':BatchNum'=>$BatchNum,
                    ':ApvChannelID_old'=>$ApvChannelID_old,
                    ':ApvCategoryID_old'=>$ApvCategoryID_old
                   )
             );
$data=$sql->fetch(PDO::FETCH_ASSOC);

We need not preparation similar to other languages,
we need immediate escape and parse for varialbles in query strings:
$rs=$pdo->query("select *
                 from sem_SearchChangeShow
                 where Keyword={#Keyword}
                       and BatchNum={#BatchNum}
                       and OldChannelID={#ApvChannelID_old}
                       and OldCategoryID={#ApvCategoryID_old}
               ");
$data=$rs->fetch(PDO::FETCH_ASSOC);
 [2009-11-19 07:07 UTC] kexianbin at diyism dot com
Rasmus,

We really should to get rid of sql string auto escape in data of POST, GET, COOKIE etc,
instead, we put off the sql string auto escape right before the sql string to be executed.
 [2009-11-19 07:12 UTC] kexianbin at diyism dot com
For matching preciseness,
we could only support the format: "...{#BatchId}...",
not to support this format: "...#BatchId...".
 [2009-11-19 07:12 UTC] rasmus@php.net
We did get rid of it.
 [2009-11-27 01:53 UTC] kexianbin at diyism dot com
Rasmus,

Another way,

similar to reserved word 'global' to inherit variables from global scope, why can't we add a reserved word 'inherit' to inherit varialbes from parent scope?

I think it's very useful since it's a great advantage now aday in javascript communities.

Malcolm
 [2009-12-16 08:52 UTC] kexianbin at diyism dot com
I think to realize auto escape for double quoted strings is easier than to inherit variables from parent scope.
 [2009-12-16 10:41 UTC] derick@php.net
.
 [2010-03-22 10:29 UTC] kexianbin at diyism dot com
-Status: Bogus +Status: Open -Package: Feature/Change Request +Package: *General Issues -PHP Version: 5.3.2 +PHP Version: 5.3.3
 [2010-03-22 10:29 UTC] kexianbin at diyism dot com
,
 [2010-03-22 10:30 UTC] kexianbin at diyism dot com
,
 [2010-03-22 10:30 UTC] kexianbin at diyism dot com
,
 [2010-03-22 10:39 UTC] johannes@php.net
-Status: Open +Status: Bogus
 [2010-03-22 10:39 UTC] johannes@php.net
As others told you: This feature won't be implemented.
 [2010-03-22 19:30 UTC] kexianbin at diyism dot com
function safe_query($scope, $sql)
         {extract($scope);
          $sql=strtr($sql, array('"'=>'\"', '\\'=>'\\\\'));
          $sql=eval('return "'.preg_replace(array('/\{#(.*?)\}/'), array('".addslashes($\1)."'), $sql).'";');
          mysql_query($sql);
         }
safe_query(get_defined_vars(),
           "insert into z_test (name, value) values ('{$name}', '{#value}')"
          );
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri May 03 19:01:32 2024 UTC