當(dāng)我們在處理由客戶端傳來的數(shù)據(jù)時,為了防止SQL注入攻擊及其他安全問題,需要對這些數(shù)據(jù)進行轉(zhuǎn)義并處理。php提供了 addcslashes 和 addslashes函數(shù),功能都是對字符串中的特殊字符進行轉(zhuǎn)義。而在實際使用中,由于addslashes轉(zhuǎn)義的字符集合不完整,所以一些較為少見的特殊字符并沒有被轉(zhuǎn)義,因此建議使用 addcslashes 或者其他安全的方式進行防注。
addslashes 函數(shù)用于將字符串中一些特殊字符加上反斜線,以便于安全地執(zhí)行 MySQL 語句。不過需要注意的是,addslashes 函數(shù)僅僅是針對單引號、雙引號、反斜線和 NUL 這四個字符進行轉(zhuǎn)義,對于一些其他的特殊字符如 \x00、\x1a則無法轉(zhuǎn)義,因此在進行應(yīng)用時需要特別注意。以下是一個示例:
$str = "張三'"; echo addslashes($str); // 輸出:張三\'
而當(dāng)要轉(zhuǎn)義的字符串中含有像回車符、換行符這樣的ASCII字符,我們需要用 addcslashes 函數(shù)進行處理,因為addslashes 不會轉(zhuǎn)義這些字符。
$str = "張三\n"; echo addslashes($str); // 輸出:張三\ echo addcslashes($str, "\0..\37!@\177..\377"); // 輸出:張三\n
在使用一些框架、ORM 工具,甚至是自己編寫的代碼時,很多時候可能是使用的都是 ORM::escape 方法自動轉(zhuǎn)義數(shù)據(jù)。例如,ThinkPHP 中定義轉(zhuǎn)義方法為:escape,而 Laravel 是通過 QueryBuilder 或 Model Eloquent 內(nèi)部完成轉(zhuǎn)義操作。
use Illuminate\Support\Facades\DB; $user = DB::table('users')->where('name', '=', "Bob'")->get();
使用Query Builder 或 ORM 框架操作數(shù)據(jù)庫時,這些工具一般都會自動地處理數(shù)據(jù)轉(zhuǎn)義的問題。不過,在有些時候,我們需要進行數(shù)據(jù)的轉(zhuǎn)義操作,處理一些敏感字符。此時,依舊可以使用addcslashes 或 addslashes ,不過建議使用其他更加安全的函數(shù)代替。
除了手動對字符串進行轉(zhuǎn)義之外,php 7 之后標(biāo)準(zhǔn)庫中新增了一個類 Filter ,其中的 addslashes 函數(shù)和之前的 addcslashes 類似,可以一次性地對多個字符串進行轉(zhuǎn)義。
use FilterIterator; class EscapeIterator extends FilterIterator { public function current() { return addslashes(parent::current()); } public function accept() { return is_string(parent::current()); } } $array = ['1', '2\n', '3\'']; $it = new EscapeIterator(new ArrayIterator($array)); foreach ($it as $key =>$val) { echo $key . ' =>' . $val . "\n"; }
總之,php 中的轉(zhuǎn)義操作對于保證程序的安全性是至關(guān)重要的,因此我們需要選擇合適的方法進行轉(zhuǎn)義。