如何在共享主机上关闭魔术引号?

时间:2009-02-05 17:47:56

标签: php magic-quotes-gpc

我想关闭PHP的魔术引号。我无法访问php.ini。

当我尝试将php_flag magic_quotes_gpc off添加到我的.htaccess文件时,出现500内部服务器错误。这就是我的.htaccess文件:

AddType x-mapp-php5 .php
php_flag magic_quotes_gpc off

然后我尝试使用ini_set('magic_quotes_gpc', 'O'),但这没有效果。

如何关闭魔法引号?

13 个答案:

答案 0 :(得分:42)

根据the manual,您通常可以在共享主机上安装自定义php.ini,其中未使用mod_php,因此php_value指令会导致错误。对于suexec / FastCGI设置,在任何情况下都有一个每个网站空间php.ini是很常见的。

-

我认为O(大写字母o)不是设置ini标志的有效值。您需要使用true / false,1/0或“on”/“off”值。

ini_set( 'magic_quotes_gpc', 0 );   // doesn't work

修改

检查list of ini settings后,我发现magic_quotes_gpc是PHP_INI_PERDIR设置(在4.2.3之后),这意味着您无法使用ini_set()更改它(仅{{1}可以使用PHP_INI_ALL

更改设置

这意味着您必须使用.htaccess文件来执行此操作 - 或者 - 实现脚本以反转魔术引号的效果。像这样的东西

ini_set()

答案 1 :(得分:30)

虽然我不能说为什么php_flag会给你500 Internal Server Error,但我会指出PHP manual有一个例子来检测是否有魔术引号并且在运行时将其从超全局中删除。与其他发布的不同,这个是递归的,并且会正确地从数组中删除引号:

更新:我今天注意到PHP手册中有以下代码的新版本,它使用了对超级全局变量的引用。

旧版本:

<?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);
}
?>

新版本:

<?php
if (get_magic_quotes_gpc()) {
    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][stripslashes($k)] = $v;
                $process[] = &$process[$key][stripslashes($k)];
            } else {
                $process[$key][stripslashes($k)] = stripslashes($v);
            }
        }
    }
    unset($process);
}
?>

答案 2 :(得分:20)

这将解决在创建本地php.ini文件时“找不到”类'PDO'的问题。

如果你不能使用htaccess文件关闭魔术引号(由于Pete Bailey已经给出的原因):

  1. 创建文本文件
  2. 将其重命名为'php.ini'
  3. 添加行

    magic_quotes_gpc =关闭 magic_quotes_runtime =关闭 magic_quotes_sybase =关

    延长= pdo.so
    延长= pdo_mysql.so

  4. 将其保存到执行脚本的目录中。

  5. 更新:如果您只想拥有新php.ini文件的一个副本,请将此行添加到根.htaccess文件中:

    SetEnv PHPRC /path/to/site/root/public_html/php.ini
    

    显然你需要将ini文件移动到它的位置。

    希望拯救某人2个小时才能把它带走!

答案 3 :(得分:10)

.htaccess文件中的php_flag和php_value在技术上是正确的 - 但是对于仅作为Apache模块安装的PHP。在共享主机上,您几乎永远不会找到这样的设置;由于与安全相关的原因(保持服务器邻居不在文件中)以及phpsuexec以'你'而不是apache用户运行脚本的方式,PHP作为CGI运行。

因此,Apache正确地给你一个服务器错误:除非加载PHP模块,否则它不知道php_flag的含义。 CGI二进制文件是Apache的一个外部程序,你不能在Apache中配置它。

现在有了好消息:您可以设置每个目录配置,并在其中放置一个名为“ php.ini ”的文件,并使用与系统主php中相同的语法设置您的说明。 INI。 PHP manual列出了所有可设置的指令:您可以设置标记为PHP_INI_PERDIR或PHP_INI_ALL的指令,而只有系统管理员可以在服务器范围的php.ini中设置标记为PHP_INI_SYSTEM的指令。

请注意,这样的php.ini指令不会被子目录继承,你必须给它们自己的php.ini。

答案 4 :(得分:5)

======================== ===============我的解决方案============================ (将您的php.ini重命名为php5.ini)

并在顶部(!)添加以下内容:

magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
extension=pdo.so
extension=pdo_mysql.so

然后在.htaccess中,添加它(在顶部):

SetEnv PHPRC /home/your_path/to/public_html/php5.ini

P.S。正确更改/home/your_path/to/(您可以通过从典型的.php文件执行<?php phpinfo(); ?>命令来查看该路径。)

答案 5 :(得分:2)

如果你正在运行PHP 5.3+,那么就可以把它放在页面的最顶层:

if (get_magic_quotes_gpc() === 1)
{
    $_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
    $_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
    $_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
    $_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true);
}

处理键,值和多维数组。

答案 6 :(得分:1)

如果您的托管服务提供商使用cpanel, 您可以尝试将php.ini复制到您的Web目录中 并使用magic_quotes_gpc = off

进行编辑

答案 7 :(得分:1)

我知道我迟到了回答这个问题,但是我读了大部分答案,虽然很多很好,但只有djn actually explained why你得到了这个500 Internal Server Error

虽然他的解释是100%正确的,但这是一个很好的例子,说明为什么你应该总是用<IfModule>包裹它们。虽然这不能解决无法在.htaccess中设置这些标记的实际问题,但它至少会阻止500错误

<IfModule mod_php5.c>
    # put all of your php_flags here, for example:
    php_flag magic_quotes_gpc off
</IfModule>

或者对于旧版本,它将是<IfModule mod_php.c>等。

我试图养成这样做的习惯,以避免任何这样的500错误。之后,只需应用what Peter Bailey said

答案 8 :(得分:0)

不同的托管服务提供商有不同的程序,所以我会在他们的论坛上提出或提出支持请求。

如果你无法关闭它们,你总是可以使用这样的东西来逃避输入,无论魔法引号是打开还是关闭:

//using mysqli

public function escapeString($stringToBeEscaped) {

    return $this->getConnection()->real_escape_string(stripslashes($stringToBeEscaped));
}

答案 9 :(得分:0)

  1. 如果删除AddType行,它是否有效?我不太清楚为什么这与关闭魔术引号有关。

  2. 如果PHP没有在mod_php下运行,htaccess将无效。它是否作为CGI工作?

  3. 这是您的托管公司真的。

答案 10 :(得分:0)

BaileyP的回答已经很好了,但我会改用这个条件:

if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() === 1){
  $_POST = array_map( 'stripslashes', $_POST );
  $_GET = array_map( 'stripslashes', $_GET );
  $_COOKIE = array_map( 'stripslashes', $_COOKIE );
}

更具防御性。

答案 11 :(得分:0)

$_SERVER怎么样?

if (get_magic_quotes_gpc() === 1) {

    $_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
    $_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
    $_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
    $_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true); 
    $_SERVER = json_decode( stripslashes(json_encode($_SERVER,JSON_HEX_APOS)), true); 
}

答案 12 :(得分:-1)

如果你不能把它关掉,这就是我通常做的事情:

get_magic_quotes_gpc() ? $_POST['username'] : mysql_real_escape_string($_POST['username']);

它将以适当的格式放入数据库中。