2024 年日本 PHP 研討會

addslashes

(PHP 4, PHP 5, PHP 7, PHP 8)

addslashes使用反斜線將字串加上引號

說明

addslashes(字串 $string): 字串

傳回一個字串,其中在需要跳脫的字元前加上了反斜線。這些字元是

  • 單引號 (')
  • 雙引號 (")
  • 反斜線 (\)
  • NUL(NUL 位元組)

addslashes() 的一個使用案例是在要由 PHP 評估的字串中跳脫上述字元

<?php
$str
= "O'Reilly?";
eval(
"echo '" . addslashes($str) . "';");
?>

addslashes() 有時會被錯誤地用於嘗試防止 SQL 注入。應該使用資料庫專用的跳脫函式和/或預備語句。

參數

string(字串)

要跳脫的字串。

回傳值

返回跳脫後的字串。

範例

範例 #1 一個 addslashes() 的範例

<?php
$str
= "Is your name O'Reilly?";

// 輸出:Is your name O\'Reilly?
echo addslashes($str);
?>

參見

新增註釋

使用者貢獻的註釋 7 則註釋

roysimke at microsoftsfirstmailprovider dot com
14 年前
永遠不要使用 addslashes 函式來跳脫要傳送到 mysql 的值。請至少使用 mysql_real_escape_string 或 pg_escape,如果您尚未使用預備查詢的話。

請記住,單引號不是唯一可以破壞 SQL 查詢的特殊字元。而引號是 addslashes 唯一關心的東西。
divinity76 at gmail dot com
2 年前
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);
}

?>

- 但從未加入反斜線。
svenr at selfhtml dot org
13 年前
要將 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...") ;
unsafed
19 年前
addslashes 並**不會**讓你的輸入資料在資料庫查詢中變得安全!它只會根據 PHP 的定義進行跳脫字元,而不是根據你的資料庫驅動程式定義。任何使用此函式來跳脫用於資料庫的字串都可能是錯誤的 - 應該根據你使用的資料庫使用 mysql_real_escape_string、pg_escape_string 等,因為每個資料庫都有不同的跳脫需求。尤其 MySQL 要求跳脫 \n、\r 和 \x1a,而 addslashes 並**沒有**這樣做。因此,依賴 addslashes 並不是個好主意,而且可能會使你的程式碼容易受到安全風險。我真的不明白這個函式應該做什麼。
hoskerr at nukote dot com
22 年前
在將輸入傳遞給 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()。我會避免自己進行這樣的交叉發佈...]
David Spector
11 年前
如果您只想像在 PHP 中通常那樣引用字串(例如,在返回 Ajax 結果時,在 json 字串值內部,或在使用參數構建 URL 時),請不要使用 addslashes(您不希望 " 和 ' 同時被跳脫)。請改用以下函式

<?php
function Quote($Str) // 僅使用雙引號
{
$Str=str_replace('"','\"',$Str);
return
'"'.$Str.'"';
}
// Quote
?>

稍微修改一下就可以得到一個使用單引號的函式。
stuart at horuskol dot co dot uk
15 年前
在建立要跳脫的字串時,請注意使用雙引號還是單引號

$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 = "這是一行\r\n這是另一行\r\n這一行有個\t定位點";

echo $test;
echo "\r\n\r\n";
echo addslashes($test);
To Top