41

我想关闭 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'),但没有效果。

如何关闭魔术引号?

4

13 回答 13

41

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

--

我不认为 O(大写字母 o)是设置 ini 标志的有效值。您需要使用真/假、1/0 或“开”/“关”值。

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

编辑

检查ini设置列表后,我看到magic_quotes_gpc是一个PHP_INI_PERDIR设置(4.2.3之后),这意味着你不能改变它ini_set()(只有PHP_INI_ALL设置可以改变ini_set()

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

if ( in_array( strtolower( ini_get( 'magic_quotes_gpc' ) ), array( '1', 'on' ) ) )
{
    $_POST = array_map( 'stripslashes', $_POST );
    $_GET = array_map( 'stripslashes', $_GET );
    $_COOKIE = array_map( 'stripslashes', $_COOKIE );
}
于 2009-02-05T17:54:04.667 回答
30

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

更新:我今天注意到 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);
}
?>
于 2009-02-06T13:34:21.477 回答
20

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

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

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

    magic_quotes_gpc = 关闭
    magic_quotes_runtime = 关闭
    magic_quotes_sybase = 关闭
    extension=pdo.so
    extension=pdo_mysql.so

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

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

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

显然,您需要将 ini 文件移动到它不存在的这个位置。

希望这可以节省我刚刚花费的 2 个小时!

于 2012-05-10T12:27:04.303 回答
10

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

因此,Apache 是正确的,给您一个服务器错误:除非加载了 PHP 模块,否则它不知道 php_flag 的含义。CGI 二进制文件对 Apache 来说是一个外部程序,您不能从 Apache 内部对其进行配置。

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

请注意,此类 php.ini 指令不会被子目录继承,您必须为它们提供自己的 php.ini。

于 2009-02-07T01:24:40.437 回答
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

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

于 2013-09-16T18:23:30.680 回答
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);
}

处理键、值和多维数组。

于 2010-01-17T02:50:24.130 回答
1

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

于 2011-07-25T12:07:26.740 回答
1

我知道我回答这个问题迟了,但我阅读了大部分答案,虽然很多都很棒,但只有djn 真正解释了你为什么得到这个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 错误。之后,只需应用Peter Bailey 所说的话。

于 2012-11-19T04:57:21.970 回答
0

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

如果你不能关闭它们,你总是可以使用这样的东西,无论魔术引号是打开还是关闭,它都会转义输入:

//using mysqli

public function escapeString($stringToBeEscaped) {

    return $this->getConnection()->real_escape_string(stripslashes($stringToBeEscaped));
}
于 2009-02-05T17:52:58.960 回答
0
  1. 如果您删除 AddType 行,它会起作用吗?我不太清楚为什么这与关闭魔术引号有关。

  2. 如果 PHP 没有在 mod_php 下运行,htaccess 将无法工作。它可以作为 CGI 工作吗?

这确实适合您的托管公司。

于 2009-02-05T17:54:01.797 回答
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 );
}

它更具防御性。

于 2009-02-06T13:06:23.170 回答
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); 
}
于 2011-04-05T12:57:43.650 回答
-1

如果你不能关闭它,我通常会这样做:

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

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

于 2009-02-05T18:28:40.057 回答