• 转义字符:html、mysql、postgresql、json、php


    结论:

    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_stringhttp://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,这一周期已缩短为几周时间。

  • 相关阅读:
    实验楼挑战赛(1)-实现不可修改字典
    python django前端界面实现数据库数据excel导出
    python2中range和xrange的异同
    python的json模块的dumps,loads,dump,load方法介绍
    ajax500错误
    伪元素小tips
    使用css3制作蚂蚁线
    chardet坑——比蜗牛还慢
    Flask的socket.error:10053
    chrome插件开发-消息机制中的bug与解决方案
  • 原文地址:https://www.cnblogs.com/sink_cup/p/escapes_special_characters.html
Copyright © 2020-2023  润新知