关于addslashes()和stripslashes()

来源:互联网 发布:mysql alter修改表数据 编辑:程序博客网 时间:2024/06/08 13:17
当我们往数据库插入数据时,

如从页面表单获取书名插入数据库的语句:

$book_name = $_POST["book_name"];$query = "insert into books values('".$book_name."')";

看似没有问题,但是当$book_name的值为《I'm your dady》时,就会出现问题了,这条插入数据库语句对单引号敏感。
那就把原insert语句的单引号改成双引号就可以了?
是的,双引号内包含单引号是可以的。但是,如果插入的$book_name值里面有双引号时又行不通了。
所设计的程序语句是固定的,但是用户所插入的值却不是固定的,所以就需要灵活地对引号这些特殊字符进行转义后在插入数据库。
所以就有了addslashes()函数。


addslashes(string $str)
该函数将返回一个字符串,返回的字符串为了数据库查询语句等的需要在某些字符前加上了反斜线。这些字符是单引号(')、双引号(")、反斜线(\)与 NUL(NULL 字符)。

$str = "You're a boy\girl.";echo $str.'<br/>';  //输出结果:You're a boy\girl.echo addslashes($str);  //输出结果:You\'re a boy\\girl.已对特殊字符进行了转义,便于插入数据库,但数据库中保留的还是You're a boy\girl.下面会讲到


但是PHP手册强烈建议使用 DBMS 指定的转义函数 (比如 MySQL 是 mysqli_real_escape_string(),PostgreSQL 是 pg_escape_string()),但是如果你使用的 DBMS 没有一个转义函数,并且使用 \ 来转义特殊字符,就可以使用addslashes()函数。

mysqli_real_escape_string()用法:

$mysqli = new mysqli('localhost','root','','test');if($mysqli->connect_errno){    die('Connect Error:'.$mysqli->connect_error);}$str = "You're a boy\girl.";$str= $mysqli->real_escape_string($str);echo $str; //输出结果:You\'re a boy\\girl.

因为每次插入数据库都要对原始数据进行转义相关操作,所以PHP引入了 magic_quotes_gpc,它默认为开启状态on,也就是对所有GET,POST,COOKIE数据都被addslashes()了(ps:这就可以猜出那个gpc代表的意思就是GET,POST,COOKIE)。不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes(),因为这样会导致双层转义。 遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。 

$str = "You're a boy\girl.";if(!get_magic_quotes_gpc()){//这种写法就避免了双层转义    $str = addslashes($str);}echo $str;

PHP更新日志:在PHP版本5.4.0 get_magic_quotes_gpc()始终返回FALSE,因为这个魔术引号功能已经从PHP中移除了。


stripslashes()
先说一下这个函数,它返回一个去除转义反斜线后的字符串(\' 转换为 ' 等等)。双反斜线(\\)被转换为单个反斜线(\)。 
我们总以为既然数据插入数据库要添加转义符号,那从数据库中取出的数据也要去除其转义符号,才能还原其本来的模样。
这其实是错误的。
我们用addslashes()或是real_escape_string()来对数据进行转义后加入数据库。但是数据库中保留的数据还是原本的模样,而非添加了转义符号后的。


我做了以下的测试,往test数据库中的one表插入一条语句:

$mysqli = new mysqli('localhost','root','','test');if($mysqli->connect_errno){    die('Connect Error:'.$mysqli->connect_error);}$str = "You're a boy\girl.";$str= $mysqli->real_escape_string($str);//$str = addslashes($str);//echo $str.'<br\>';//输出后的$str为:You\'re a boy\\girl.$query = "insert into one values('1','".$str."')";$result = $mysqli -> query($query);if ($result){    echo $mysqli -> affected_rows." line inserted into database";}else{    echo "an error has occured. The item was not added.";}$mysqli ->close();



我们都以为数据库中保存的$str是这样的:You\'re a boy\\girl.
但结果呢?并不是:


为什么会这样:


(这是stackoverflow上的一个回答)
博主英语渣,所以理解了个大概:转义后的数据会经过一个类似MYSQL-adapter功能的东西处理,然后把原始数据插入数据库后,数据库中的数据并不会保留你后来添加的转义字符。
综上所述,当把数据从数据库取出时,并不需要加stripslashes()来去除转义字符,因为本来就没有。

0 0
原创粉丝点击