天狼晓月 发表于 2014-1-10 14:40:31

PHP探秘(一)--魔术引用(1)

魔术引号(Magic Quote)是一个自动将进入 PHP 脚本的数据进行转义的过程。最好在编码时不要转义而在运行时根据需要而转义。 Magic Quotes are depreciated and going to be removed in PHP6.
If you still want your code to be portable, no warnings etc, as of PHP52 you can use the following code.

<?php
foreach ($_GET as $key => &$val) $val = filter_input(INPUT_GET, $key);

foreach ($_POST as $key => &$val) $val = filter_input(INPUT_POST, $key);
?>

The above will retrieve an-escaped GETs and POSTs regardless system settings. It can also be used for $_COOKIES and others.

什么是魔术引号

当打开时,所有的 \'(单引号),"(双引号),\\(反斜线)和 NULL 字符都会被自动加上一个反斜线进行转义。这和 addslashes() 作用完全相同。

一共有三个魔术引号指令:

    magic_quotes_gpc 影响到 HTTP 请求数据(GET,POST 和 COOKIE)。不能在运行时改变。在 PHP 中默认值为 on。 参见 get_magic_quotes_gpc()。
    magic_quotes_runtime 如果打开的话,大部份从外部来源取得数据并返回的函数,包括从数据库和文本文件,所返回的数据都会被反斜线转义。该选项可在运行的时改变,在 PHP 中的默认值为 off。 参见 set_magic_quotes_runtime() 和 get_magic_quotes_runtime()。
    magic_quotes_sybase 如果打开的话,将会使用单引号对单引号进行转义而非反斜线。此选项会完全覆盖 magic_quotes_gpc。如果同时打开两个选项的话,单引号将会被转义成 \'\'。而双引号、反斜线 和 NULL 字符将不会进行转义。 如何取得其值参见 ini_get()。



为什么要用魔术引号

    对初学者很有用 魔术引号在 PHP 中用来实现避免初学者的代码更危险。尽管 SQL 注入在魔术引号打开的情况下仍然有可能实现,但起

码系统的风险减少很多了。
    方便使用 当向数据库中插入数据时,魔术引号所做的就是自动对所有的 GET、POST、COOKIE 数据运用 addslashes() 函数。


为什么不用魔术引号

    可移植性 编程时认为其打开或并闭都会影响到移植性。可以用 get_magic_quotes_gpc() 来检查是否打开,并据此编程。
    性能 由于并不是每一段被转义的数据都要插入数据库的,如果所有进入 PHP 的数据都被转义的话,那么会对程序的执行效率产生一定

的影响。在运行时调用转义函数(如 addslashes())更有效率。 尽管 php.ini-dist 默认打开了这个选项,但是 php.ini-recommended 默

认却关闭了它,主要是出于性能的考虑。
    不便 由于不是所有数据都需要转义,在不需要转义的地方看到转义的数据就很烦。比如说通过表单发送邮件,结果看到一大堆的 \\\'。

针对这个问题,可以使用 stripslashes() 函数处理。



This is what I use to handle magic quotes

<?php

if (get_magic_quotes_gpc()) {
    function strip_array($var) {
      return is_array($var)? array_map("strip_array", $var):stripslashes($var);
    }

    $_POST = strip_array($_POST);
    $_SESSION = strip_array($_SESSION);
    $_GET = strip_array($_GET);
}

?>


关闭魔术引号

magic_quotes_gpc 指令只能在系统级关闭,不能在运行时。也就是说不能用 ini_set()。




Example #1 在服务器端关闭魔术引号

下面是一个通过 php.ini 文件把这些选项设为 Off 的范例。更多信息请参见本手册的怎样修改配置设定。

; Magic quotes
;

; Magic quotes for incoming GET/POST/Cookie data.
magic_quotes_gpc = Off

; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
magic_quotes_runtime = Off

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

如果不能修改服务器端的配置文件,使用 .htaccess 也可以。范例如下:

php_flag magic_quotes_gpc Off

为了能写出移植性较强的代码(可以运行于任何环境),例如不能修改服务器配置的情况,下面的例子可以在运行时关闭 magic_quotes_gpc

。但是这样做比较低效,适当的修改配置才是更好的办法。

Example #2 在运行时关闭魔术引号
<?php
if (get_magic_quotes_gpc()) {
    function stripslashes_deep($value)
    {
      $value = is_array($value) ?
                  array_map(\'stripslashes_deep\', $value) :
                  stripslashes($value);

      return $value;
    }

    $_POST = array_map(\'stripslashes_deep\', $_POST);
    $_GET = array_map(\'stripslashes_deep\', $_GET);
    $_COOKIE = array_map(\'stripslashes_deep\', $_COOKIE);
    $_REQUEST = array_map(\'stripslashes_deep\', $_REQUEST);
}
?>
页: [1]
查看完整版本: PHP探秘(一)--魔术引用(1)