我想关闭 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')
,但没有效果。
如何关闭魔术引号?
我想关闭 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')
,但没有效果。
如何关闭魔术引号?
根据手册,您通常可以在共享主机上安装自定义 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 );
}
虽然我不能说为什么 php_flag 给你500 Internal Server Error
s,但我会指出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);
}
?>
这将解决创建本地 php.ini 文件时出现“找不到类 'PDO'”的问题。
如果您不能使用 htaccess 文件关闭魔术引号(由于 Pete Bailey 已经给出的原因),只需:
添加行
magic_quotes_gpc = 关闭
magic_quotes_runtime = 关闭
magic_quotes_sybase = 关闭
extension=pdo.so
extension=pdo_mysql.so
将其保存到执行脚本的目录中。
更新:如果您只想拥有新 php.ini 文件的一份副本,则将此行添加到您的根 .htaccess 文件中:
SetEnv PHPRC /path/to/site/root/public_html/php.ini
显然,您需要将 ini 文件移动到它不存在的这个位置。
希望这可以节省我刚刚花费的 2 个小时!
.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。
======================================== 我的解决方案========= ===================(将您的 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(); ?>
如果您运行的是 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);
}
处理键、值和多维数组。
如果您的托管服务提供商使用 cpanel,您可以尝试将 php.ini 复制到您的 Web 目录并使用 magic_quotes_gpc = off 进行编辑
我知道我回答这个问题迟了,但我阅读了大部分答案,虽然很多都很棒,但只有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 所说的话。
不同的托管服务提供商对此有不同的程序,所以我会在他们的论坛上询问或提交支持请求。
如果你不能关闭它们,你总是可以使用这样的东西,无论魔术引号是打开还是关闭,它都会转义输入:
//using mysqli
public function escapeString($stringToBeEscaped) {
return $this->getConnection()->real_escape_string(stripslashes($stringToBeEscaped));
}
如果您删除 AddType 行,它会起作用吗?我不太清楚为什么这与关闭魔术引号有关。
如果 PHP 没有在 mod_php 下运行,htaccess 将无法工作。它可以作为 CGI 工作吗?
这确实适合您的托管公司。
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 );
}
它更具防御性。
怎么样$_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);
}
如果你不能关闭它,我通常会这样做:
get_magic_quotes_gpc() ? $_POST['username'] : mysql_real_escape_string($_POST['username']);
它将以其适当的格式放入数据库中。