永远不要使用 addslashes 函数来转义您要发送到 mysql 的值。至少使用 mysql_real_escape_string 或 pg_escape,如果您还没有使用预处理查询。
请记住,单引号不是唯一可能破坏您的 sql 查询的特殊字符。并且引号是 addslashes 唯一关心的内容。
(PHP 4, PHP 5, PHP 7, PHP 8)
addslashes — 用斜杠引用字符串
返回一个字符串,在需要转义的字符前添加反斜杠。这些字符是
'
)"
)\
)addslashes() 的一个用例是在要由 PHP 求值的字符串中转义上述字符
<?php
$str = "O'Reilly?";
eval("echo '" . addslashes($str) . "';");
?>
addslashes() 有时被错误地用于尝试防止SQL 注入。相反,应该使用特定于数据库的转义函数和/或预处理语句。
字符串
要转义的字符串。
返回转义后的字符串。
示例 #1 addslashes() 示例
<?php
$str = "Is your name O'Reilly?";
// 输出:Is your name O\'Reilly?
echo addslashes($str);
?>
永远不要使用 addslashes 函数来转义您要发送到 mysql 的值。至少使用 mysql_real_escape_string 或 pg_escape,如果您还没有使用预处理查询。
请记住,单引号不是唯一可能破坏您的 sql 查询的特殊字符。并且引号是 addslashes 唯一关心的内容。
Addslashes *永远*不是正确的答案,它的(滥)用可能导致安全漏洞!
如果您需要转义 HTML,则(不幸的是)
<?php
echo htmlentities($html, ENT_QUOTES|ENT_SUBSTITUTE|ENT_DISALLOWED);
?>
如果您需要引用 shell 参数,则
<?php
$cmd.= " --file=" . escapeshellarg($arg);
?>
如果您需要引用 SQL 字符串,则
<?php
$sql.= "WHERE col = '".$mysqli->real_escape_string($str)."'";
?>
或
<?php
$sql.= "WHERE col = " . $pdo->quote($str);
?>
如果您需要在 javascript/json 字符串中引用,则
<?php
let str = <?=json_encode($str, JSON_THROW_ON_ERROR);?>;
?>
如果您需要在 xpath 中引用字符串,则
<?php
// 基于 https://stackoverflow.com/a/1352556/1067003
function xpath_quote(string $value):string{
if(false===strpos($value,'"')){
return '"'.$value.'"';
}
if(false===strpos($value,'\'')){
return '\''.$value.'\'';
}
// 如果该值同时包含单引号和双引号,则构造一个
// 表达式,将所有非双引号子字符串与
// 引号连接起来,例如:
//
// concat("'foo'", '"', "bar")
$sb='concat(';
$substrings=explode('"',$value);
for($i=0;$i<count($substrings);++$i){
$needComma=($i>0);
if($substrings[$i]!==''){
if($i>0){
$sb.=', ';
}
$sb.='"'.$substrings[$i].'"';
$needComma=true;
}
if($i < (count($substrings) -1)){
if($needComma){
$sb.=', ';
}
$sb.="'\"'";
}
}
$sb.=')';
return $sb;
}
$xp->query('/catalog/items/item[title='.xpath_quote($var).']');
?>
如果您需要在 CSS 中引用字符串,则
<?php
// CSS 转义代码取自 Zend Framework ( https://github.com/zendframework/zf2/blob/master/library/Zend/Escaper/Escaper.php )
function css_escape_string($string)
{
$cssMatcher = function ($matches) {
$chr = $matches[0];
if (strlen($chr) == 1) {
$ord = ord($chr);
} else {
$chr = mb_convert_encoding($chr, 'UTF-16BE', 'UTF-8'); // $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8');
$ord = hexdec(bin2hex($chr));
}
return sprintf('\\%X ', $ord);
};
$originalEncoding = mb_detect_encoding($string);
if ($originalEncoding === false) {
$originalEncoding = 'UTF-8';
}
;
$string = mb_convert_encoding($string, 'UTF-8', $originalEncoding); // $this->toUtf8($string);
// throw new Exception('mb_convert_encoding(\''.$string.'\',\'UTF-8\',\''.$originalEncoding.'\');');
if ($string === '' || ctype_digit($string)) {
return $string;
}
$result = preg_replace_callback('/[^a-z0-9]/iSu', /*$this->*/$cssMatcher, $string);
// var_dump($result);
return mb_convert_encoding($result, $originalEncoding, 'UTF-8'); // $this->fromUtf8($result);
}
?>
- 但从不使用 addslashes。
要将 PHP 变量输出到 Javascript,请使用 json_encode()。
<?php
$var = "He said \"Hello O'Reilly\" & disappeared.\nNext line...";
echo "alert(".json_encode($var).");\n";
?>
输出
alert("He said \"Hello O'Reilly\" & disappeared.\nNext line...") ;
addslashes 不会使您的输入对数据库查询安全!它只根据 PHP 的定义进行转义,而不是根据数据库驱动程序的定义进行转义。任何使用此函数转义字符串以用于数据库的操作都可能是错误的 - 应根据您的底层数据库使用 mysql_real_escape_string、pg_escape_string 等,因为每个数据库都有不同的转义要求。特别是,MySQL 需要转义 \n、\r 和 \x1a,而 addslashes 不会这样做。因此,依赖 addslashes 完全不是一个好主意,并且可能使您的代码容易受到安全风险的攻击。我真的不明白这个函数应该做什么。
注意在输入到 serialize() 函数时使用 addslashes()。serialize() 使用其长度存储字符串;长度必须与存储的字符串匹配,否则 unserialize() 将失败。
如果您序列化 addslashes() 的结果并将其存储在数据库中,则可能会出现这种不匹配的情况;某些数据库(肯定包括 PostgreSQL)会自动从 SELECT 结果中的“特殊”字符中删除反斜杠,导致返回的字符串比序列化时的字符串短。
换句话说,请执行以下操作...
<?php
$string="O'Reilly";
$ser=serialize($string); # 安全 -- 不会计算反斜杠
$result=addslashes($ser);
?>
...而不是这样...
<?php
$string="O'Reilly";
$add=addslashes($string); # 风险!-- 将计算反斜杠
$result=serialize($add);
?>
在这两种情况下,都会在“O'Reilly”中的撇号后添加一个反斜杠;只有在第二种情况下,反斜杠才会包含在 serialize() 记录的字符串长度中。
[注意维护人员:您可以选择将此注释链接到 serialize() 以及 addslashes()。我将避免自己进行这种交叉发布...]
如果您只想像在 PHP 中通常那样引用字符串(例如,在返回 Ajax 结果时、在 json 字符串值内或在使用参数构建 URL 时),请不要使用 addslashes(您不希望同时转义 " 和 ')。相反,只需使用此函数
<?php
function Quote($Str) // 仅双引号
{
$Str=str_replace('"','\"',$Str);
return '"'.$Str.'"';
} // Quote
?>
轻松修改此内容以获取单引号函数。
在创建要转义的字符串时,请注意使用双引号还是单引号
$test = 'This is one line\r\nand this is another\r\nand this line has\ta tab';
echo $test;
echo "\r\n\r\n";
echo addslashes($test);
$test = "This is one line\r\nand this is another\r\nand this line has\ta tab";
echo $test;
echo "\r\n\r\n";
echo addslashes($test);