逸出字元:html、mysql、postgresql、json、php

來源:互聯網
上載者:User

結論:

1、使用php magic_quotes_gpc是錯誤的。從PHP 5.4.0 起已刪除此功能。http://www.php.net/manual/zh/function.get-magic-quotes-gpc.php

2、使用php addslashes是錯誤的。因為它不對應mysql或pgsql。PHP官方強烈建議使用對應mysql的mysqli_real_escape_string()和對應PostgreSQL的pg_escape_string()。http://php.net/manual/en/function.addslashes.php

3、儲存到資料庫之前使用htmlspecialchars是錯誤的。應直接儲存到資料庫。通過API提供給手機app看,C++不需要轉義HTML。通過web看時,才需要轉義。見。

4、使用php mysql_escape_string是錯誤的,已廢棄,應使用mysqli::real_escape_string。http://php.net/manual/en/function.mysql-escape-string.php

5、資料入庫前根據不同資料庫進行不同的轉義,這放在dao層。controller、model都不應該知道。

錯誤的轉義方式:

正確的轉義方式:

 

詳細分析如下。

為什麼要轉義:

1、字元與保留字衝突,比如HTML中的小與號<用於標籤

2、ASCII字元集中沒有此字元,比如HTML中以前經常寫成&copy;

第2種情況現在已經無需考慮,因為 Windows 從 XP 開始、Linux 從 GNU glibc 2.2 開始,作業系統都支援Unicode字元集了,目前開發程式主流是使用Unicode的utf-8編碼。

本文只討論第1種情況。

需要轉義的內容:

  需要轉義 不需要轉義的字元(常見錯誤)
HTML <、& >
mysql 換行、斷行符號等 換頁、空格、<、>、&
postgresql 換頁、換行、斷行符號等  
JSON "、\和控制字元  

PHP常見轉義方法:

  轉義範圍
不應使用addslashes 單引號'、雙引號"、反斜線\與 NUL
htmlspecialchars &、'、"、<、>
不應使用mysql_escape_string 對應mysql 4
mysqli::real_escape_string 對應mysql 5+
pg_escape_string 對應PostgreSQL
php PDO::quote 自動判斷資料庫是Mysql還是PostgreSQL等
PDO::prepare() 自動判斷資料庫是Mysql還是PostgreSQL等

對字串"hello world\fjim\n\r"進行轉義,結果如下:

mysqli::real_escape_string

View Code

<?php$mysqli = new mysqli('localhost', 'root', '1', 'test');$a = "hello world\fjim\n\r";var_dump($mysqli->real_escape_string($a));$sql = "INSERT INTO user VALUES ('2','lucy','". $mysqli->real_escape_string($a) . '\');';var_dump($sql);$mysqli->query($sql);?>

PDO::quote mysql 與 mysqli::real_escape_string 結果一樣。

View Code

<?php$dsn = 'mysql:dbname=test;host=localhost';$user = 'root';$password = '1';$dbh = new PDO($dsn, $user, $password);$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);$a = "hello world\fjim\n\r";var_dump($dbh->quote($a));$sql = "INSERT INTO user VALUES ('2','lucy',". $dbh->quote($a) . ');';var_dump($sql);$stmt = $dbh->query($sql);exit;?>

 

 

pg_escape_string

View Code

<?php$db = pg_connect("host=localhost port=5432 dbname=test user=root password=1");$a = "hello world\fjim\n\r";var_dump(pg_escape_string($a));$sql = "INSERT INTO schema1.user VALUES ('2','lucy','". pg_escape_string($a) . '\');';var_dump($sql);pg_query($db, $sql);exit;?>

PDO::quote pgsql 與pg_escape_string 結果相同。

View Code

<?php$dsn = 'pgsql:host=localhost;port=5432;dbname=test;user=root;password=1';$dbh = new PDO($dsn);$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);$a = "hello world\fjim\n\r";var_dump($dbh->quote($a));//$stmt = $dbh->query('SELECT "id","name","desc" FROM schema1."user"');//$sql = "INSERT INTO schema1.user VALUES ('1','jim','hello world\fjim\n\r');";$sql = "INSERT INTO schema1.user VALUES ('2','lucy',". $dbh->quote($a) . ');';var_dump($sql);$stmt = $dbh->query($sql);exit;?>

 

 

 

HTML:

HTML標籤使用小與號<開頭,所以需要轉義。而大與號>不用轉義。官方文檔:http://www.w3.org/TR/xhtml1/#h-4.8

 

mysql:

官方文檔:http://dev.mysql.com/doc/refman/5.1/zh/language-structure.html#string-syntax

mysql在預設的空sql-mode下,value的string使用單引號'或雙引號"引起來,官方文檔:http://dev.mysql.com/doc/refman/5.1/zh/language-structure.html#string-syntax

mysql在預設的空sql-mode下,識別符(庫、表、索引、列和別名)使用反勾號`引起來,官方文檔:http://dev.mysql.com/doc/refman/5.1/zh/language-structure.html#legal-names

mysql在ANSI_QUOTES sql-mode下,value的string使用單引號'引起來,官方文檔:http://dev.mysql.com/doc/refman/5.1/zh/language-structure.html#string-syntax

mysql在ANSI_QUOTES sql-mode下,識別符(庫、表、索引、列和別名)使用雙引號"或反勾號`引起來,http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#server-sql-mode

這裡以預設的空sql-mode為例。

如果string使用雙引號引起來,那麼string中的單引號無需轉義。如果string使用單引號引起來,那麼string中的雙引號無需轉義。

使用musqldump匯出sql就會看到,mysql的string使用單引號'引起來,而雙引號一定被轉義。

比如INSERT INTO `asdf` VALUES ('a\"b'); 和 INSERT INTO `asdf` VALUES ('a"b'); 結果是一樣的。

 

postgresql:

官方文檔:http://wiki.postgresql.org/wiki/9.1%E7%AC%AC%E5%9B%9B%E7%AB%A0#C.E8.AF.AD.E8.A8.80.E4.B8.AD.E7.9A.84.E8.BD.AC.E6.84.8F.E5.AD.97.E7.AC.A6.E4.B8.B2.E5.B8.B8.E9.87.8F.28String_Constants_with_C-style_Escapes.29

value的string使用單引號'引起來或者不引。

識別符(列名等)使用雙引號"引起來或者不引。

 

JSON:

官方文檔:http://www.json.org/json-zh.html

JSON的string,必須使用雙引號"引起來,不能使用單引號'引起來。如果字串中出現雙引號,需要轉義,比如{"name" : "John \"Cliff\" Barxter"}。

 

參考資料:

http://www.ibm.com/developerworks/cn/linux/i18n/unicode/linuni/

http://msdn.microsoft.com/zh-cn/magazine/cc163490.aspx

採用支援 Unicode 的單原始碼庫使開發時間得以縮短,Unicode 為 Microsoft 帶來的好處是顯而易見的。就 Windows 2000 來說,在發布英文產品後需要花費幾個月的時間來準備其語言版本。而對於 Windows XP,這一周期已縮短為幾周時間。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.