【问题标题】:How to save quotes in MySQL database如何在 MySQL 数据库中保存引号
【发布时间】:2011-10-15 14:03:59
【问题描述】:

每当我在我的 PHP 表单域中添加单引号 (') 或双引号 (") 时,它都会以 " / ' 的形式保存在我的 MySQL 数据库中。如何保存“真实的”“引号" 在我的数据库中?

我试图通过 PDO 建立一个安全的 Mysql 连接来防止这种情况发生,但它似乎无法正常工作。

所以这是我的代码的重要部分:

    $insert_hello = filter_var($_POST['hello'], FILTER_SANITIZE_STRING);
    $dbh->query("SET NAMES 'utf8'");
    $stmt = $dbh->prepare("INSERT INTO testtable (data) VALUES (:hello)");
    $stmt->bindParam(':hello', $insert_hello, PDO::PARAM_STR);      
    $stmt->execute();

一些背景信息:

服务器在 PHP v5.2.12-0 上运行。

DBStorage 引擎是 InnoDB,其客户端、连接、结果和系统字符集设置为 utf8。

DB 字段的排序规则设置为 utf8_unicode_ci。

通过 .htaccess 禁用魔术引号。

提前致谢!

亲切的问候, 杰伦

【问题讨论】:

  • 在我看来,您正在使用 filter_var 进行转换。如果要存储原始字符串,为什么要过滤?
  • 嘿!我想你是对的 Le Dorfier。 filter_var 是不必要的,并且确实是将引号转换为十六进制代码的那个。取出它时,这会使我的脚本容易受到注入吗?
  • le dorfier 是对的,我没用过PDO,不过貌似SQL转义应该是$stmt->bindParam(...),所以没必要filter_var()...先改一下试试转到$inset_hello = $_POST['hello'];,看看在发布一些包含单引号的文本时会发生什么..
  • @Jroen, “当取出它时,这会使我的脚本容易受到注入吗?”,不,因为 PDO 应该为您清理数据。如果没有,则更改 DBAL:P

标签: php mysql utf-8 pdo quotes


【解决方案1】:

好的,只是为了形式化正确答案:

问题是由filter_var() 将一些字符转换为 HTML 实体引起的。无需手动清理数据,因为 PDO 会为您完成。

你可以写这样的东西,应该可以正常工作:

$dbh->query("SET NAMES 'utf8'");
$stmt = $dbh->prepare("INSERT INTO testtable (data) VALUES (:hello)");
$stmt->bindParam(':hello', $_POST['hello'], PDO::PARAM_STR);      
$stmt->execute();

【讨论】:

    【解决方案2】:

    最好的办法是保持原样并在阅读时进行 html 解码。

    【讨论】:

    • 对不起弗朗西斯,没办法。我不想这样,因为我将在我的 CRM 数据库中使用这些字段中的数据。 (不解码)
    • 不,这绝对是不是最好的主意。只是一个非常丑陋的解决方法。
    【解决方案3】:

    您可以使用 php 函数$decoded_insert_hello = html_entity_decode($insert_hello, ENT_QUOTES) 来执行此操作。

    http://www.php.net/manual/en/function.html-entity-decode.php

    【讨论】:

    • 根据这个家伙的说法(见:bit.ly/iFr2uz),应该不需要解码。他说:“使用参数化查询的美妙之处(和强大)在于底层驱动程序会为您处理引用和转义(同时也有助于防止 SQL 注入),底层驱动程序将适当地引用和转义参数值,以便插入正确的数据(即 Brian 的数据)。
    • 这是两个完全不同的东西。您的数据库只存储文本字符串,它不知道字符串来自何处或以任何方式对其进行转换。它只是按照您提供的方式存储它们,只转义任何可能混淆数据库或使您暴露于注入攻击的特殊字符。您正在传入一个 html 编码的字符串,并且您实际上想将其转换为一个普通的 ascii 字符串,数据库不会为您执行此操作:这就像传入一个法语字符串并要求您的数据库将其翻译成英文在存储之前 - 你必须先自己做。
    • (cont) 一旦将字符串传递给数据库引擎,它将转义在 sql 中具有任何意义的任何字符,但它对 html 格式或哪些字符在 html 中具有意义一无所知. (希望我说清楚,解释有点啰嗦)。
    【解决方案4】:

    这就是我的数据作为 API 响应的样子,我想将其存储在 MYSQL 数据库中。它包含引号、HTML 代码等。

    例子:-

    {
    
    rewardName: "Cabela's eGiftCard $25.00",
    
    shortDescription: '<p>adidas gift cards can be redeemed in over 150 adidas Sport Performance, adidas Originals, or adidas Outlet stores in the US, as well as online at&nbsp;<a href="http://adidas.com/">adidas.com</a>.</p>
    
    terms: '<p>adidas Gift Cards may be redeemed for merchandise on&nbsp;<a href="http://adidas.com/">adidas.com</a>&nbsp;and in adidas Sport Performance, adidas Originals, and adidas Outlet stores in the United States.'
    
    }
    

    解决方案

    CREATE TABLE `brand` (
    `reward_name` varchar(2048),
    `short_description` varchar(2048),
    `terms` varchar(2048),  
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
    

    插入时,在后面跟着JSON.stringify()

        let brandDetails= {
        rewardName: JSON.stringify(obj.rewardName),  
        shortDescription: JSON.stringify(obj.shortDescription),
        term: JSON.stringify(obj.term),
         }
    

    上面是 JSON 对象,下面是向 MySQL 插入数据的 SQL Query。

    let query = `INSERT INTO brand (reward_name, short_description, terms) 
    VALUES (${brandDetails.rewardName}, 
    (${brandDetails.shortDescription}, ${brandDetails.terms})`;
    

    成功了……

    如果没有任何效果,试试这个:

    var res = str.replace(/'/g, "\\'");
    var res = res.replace(/"/g, "\\\"");
    

    它将 \ 转义字符添加到所有出现的 ' 和 "

    不确定它是否是解决问题的正确/专业方法

    我猜它会起作用,但在实际内容中,每个单引号和双引号都将替换为 \ 字符

    【讨论】:

      猜你喜欢
      • 2016-08-13
      • 2018-03-12
      • 1970-01-01
      • 2014-04-13
      • 1970-01-01
      • 2018-12-07
      • 2019-04-14
      • 1970-01-01
      • 2012-05-28
      相关资源
      最近更新 更多