安全
在线手册:中文 英文
PHP手册

魔术引号

Table of Contents

Warning

This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.

魔术引号(Magic Quote)是一个自动将进入 PHP 脚本的数据进行转义的过程。最好在编码时不要转义而在运行时根据需要而转义。


安全
在线手册:中文 英文
PHP手册
PHP手册 - N: 魔术引号

用户评论:

cHao (14-Mar-2011 04:38)

The very reason magic quotes are deprecated is that a one-size-fits-all approach to escaping/quoting is wrongheaded and downright dangerous.  Different types of content have different special chars and different ways of escaping them, and what works in one tends to have side effects elsewhere.  Any sample code, here or anywhere else, that pretends to work like magic quotes --or does a similar conversion for HTML, SQL, or anything else for that matter -- is similarly wrongheaded and similarly dangerous.

Magic quotes are not for security.  They never have been.  It's a convenience thing -- they exist so a PHP noob can fumble along and eventually write some mysql queries that kinda work, without having to learn about escaping/quoting data properly.  They prevent a few accidental syntax errors, as is their job.  But they won't stop a malicious and semi-knowledgeable attacker from trashing the PHP noob's database.  And that poor noob may never even know how or why his database is now gone, because magic quotes (or his spiffy "i'm gonna escape everything" function) gave him a false sense of security.  He never had to learn how to really handle untrusted input.

Data should be escaped where you need it escaped, and for the domain in which it will be used.  (mysql_real_escape_string -- NOT addslashes! -- for MySQL (and that's only unless you have a clue and use prepared statements), htmlentities or htmlspecialchars for HTML, etc.)  Anything else is doomed to failure.

shazdeh1358 at yahoo dot com (29-Jan-2011 01:41)

for those who want an automatic sanitization of GET, POST, COOKIE, etc variables:

the code escapes ALL vars! That is, it effectively prevents SQL injection and XSS attaks. It lifts the need for 'magic_quotes_gpc = On' directive.

However it treats all variables as text and does not do type-cheking. So it is suitable only for making SQL queries or displaying html content.

the following code can be included in all pages which need html and sql sanitization.

<?php

// escaping and slashing all POST and GET variables. you may add $_COOKIE and $_REQUEST if you want them sanitized.
array_walk_recursive($_POST, 'sanitizeVariables');
array_walk_recursive($_GET, 'sanitizeVariables');

// sanitization
function sanitizeVariables(&$item, $key)
{
    if (!
is_array($item))
    {
       
// undoing 'magic_quotes_gpc = On' directive
       
if (get_magic_quotes_gpc())
           
$item = stripcslashes($item);
       
       
$item = sanitizeText($item);
    }
}

// does the actual 'html' and 'sql' sanitization. customize if you want.
function sanitizeText($text)
{
   
$text = str_replace("<", "&lt;", $text);
   
$text = str_replace(">", "&gt;", $text);
   
$text = str_replace("\"", "&quot;", $text);
   
$text = str_replace("'", "&#039;", $text);
   
   
// it is recommended to replace 'addslashes' with 'mysql_real_escape_string' or whatever db specific fucntion used for escaping. However 'mysql_real_escape_string' is slower because it has to connect to mysql.
   
$text = addslashes($text);

    return
$text;
}

// export POST variables as GLOBALS. remove if you want
foreach (array_keys($_POST) as $ehsanKey)
   
$GLOBALS[$ehsanKey] = $_POST[$ehsanKey];

// export GET variables as GLOBALS. remove if you want
foreach (array_keys($_GET) as $ehsanKey)
{
   
$GLOBALS[$ehsanKey] = $_GET[$ehsanKey];
}

// preventing the key used above for iteration from getting into globals (in case  'register_globals = On')
unset($ehsanKey);

// the reverse function of 'sanitizeText'. you may use it in pages which need the original data (e.g. for an HTML editor)
function unsanitizeText($text)
{
   
$text stripcslashes($text);

   
$text = str_replace("&#039;", "'", $text);
   
$text = str_replace("&gt;", ">", $text);
   
$text = str_replace("&quot;", "\"", $text);   
   
$text = str_replace("&lt;", "<", $text);
   
    return
$text;
}
?>