【问题标题】:how to insert serialized data into database?如何将序列化的数据插入数据库?
【发布时间】:2010-11-15 09:59:38
【问题描述】:

这是我的代码-

$things = serialize($_POST['things']);
echo $things;

require 'database.php';

$q = "INSERT INTO tblslider(src) values($things)";
mysql_query($q, $link);

if($result)
{
echo "Slider saved successfully.";
}

输出-
a:4:{i:0;s:10:"651603.jpg";i:1;s:11:"7184512.jpg";i:2;s:11:"3659637.jpg";i:3;s:10:"569839.jpg";}v

这意味着我正在正确获取记录,但为什么它没有保存在数据库中??

【问题讨论】:

  • 您打算将什么确切插入数据库?您说您正在“正确获取记录”,这表明您很高兴将 $things 的值写入数据库。 但是,这与以下几个答案中的 cmets 不匹配。请详细说明您的问题。
  • @jensgram:如果他懒得接受前面问题的答案,他也懒得去详细说明

标签: php mysql serialization


【解决方案1】:

你忘记了$things周围的引号:

$q = "INSERT INTO tblslider(src) values('" . mysql_real_escape_string($things) . "')";

mysql_real_escape_string() 真的是你应该永远做的最少

与@sanders mentions 一样,您应该始终输出完整的查询(通过print_r()var_dump())作为调试的第一步。


我更喜欢构建这样的查询来增强可读性:

$q = sprintf(
         'INSERT INTO tblslider(src) VALUES ("%s")',
         mysql_real_escape_string($things)
     );

也就是说,每当我绝对必须自己建造和逃脱它们时。你真的应该看看PDO


编辑
此线程中的评论表明 OP 实际上想要将 651603.jpg,7184512.jpg,3659637.jpg,569839.jpg 插入数据库。在这种情况下,implode() 可以是 used(前提是 $_POST['things'] 包含要插入的项目!):

$q = sprintf(
         'INSERT INTO tblslider(src) VALUES ("%s")',
         mysql_real_escape_string(implode(',', $_POST['things']))
     );

请注意,我在这里直接使用$_POST['things']。没有serialize()。 (不过,我直到现在才意识到这个错误。)

【讨论】:

  • var_dump($q) id 给出这个值 INSERT INTO tblslider(src) values(a:4:{i:0;s:10:"651603.jpg";i:1;s:11: "7184512.jpg";i:2;s:11:"3659637.jpg";i:3;s:10:"569839.jpg";})" v
  • 应该是 insert tblname(src) values(122.jpg, 5646.jpg.....) 好像插入查询是错误的
  • @ppp 查看更新 - 以及我对您对@sanders 回答的评论的回复。
  • 在输入您的代码Parse error: syntax error, unexpected T_VARIABLE in D:\Hosting\6448289\html\admin\setSlider.php on line 13 第 13 行是 mysql_real_es 后出现此错误...
  • @ppp 是的,我在implode() 通话中忘记了逗号。应该是mysql_real_escape_string(implode(',', $_POST['things'])) - 查看更新的答案。
【解决方案2】:

这个问题已经很老了,但我觉得是时候来点死灵术了。 @jensgram 接受的答案没有错,但是说mysql_real_escape_string 是您可以做的最少,这意味着有一个更好的解决方案。嗯,有。

PHP 数据对象

PDOs。这些坏男孩为您的数据库访问提供了一个抽象层,因此它可以与许多其他数据库一起工作,而不仅仅是 MySQL,并且可以在多次运行相同的查询时提高性能。但这不是你需要它们的原因。

安全

逃避东西很难。要么是在特定的上下文中如何做到这一点晦涩难懂,要么你只是忘记了去做。最糟糕的是,你不会因为忘记它而出现任何错误,而是像什么都没发生一样继续前进。而您只是为互联网安全状况不佳做出了贡献。

如果正确使用 PDO(例如,没有字符串连接),将确保您在构建数据库查询时不会弄乱正确转义的内容。

你会想读这个:(The only proper) PDO tutorial

基本上,您可以在替换其中的任何参数之前准备一条 sql 语句。 SQL 语法将得到修复,不会被错误/无转义或恶意伪造请求破坏。

那么如何做到这一点

首先你需要一个连接,就像在常规的 mysql 驱动程序中一样。

$host = '127.0.0.1';
$db   = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];
$pdo = new PDO($dsn, $user, $pass, $opt);

如您所见,有设置、错误模式、获取模式。值得一读每个设置的作用,但现在保持原样。最后,您有了可以使用的 $pdo 变量。

$query = "INSERT INTO tblslider(src) VALUES (?)";
$stmt = $pdo->prepare($query); 

此时我们得到了我们的声明。目前还没有任何来自外部来源的信息,这是一个 INSERT 语句。

$things = serialize($_POST['things'])
$stmt->execute([ $things ]); //execute

还有其他方法可以将 ?-s 绑定到参数,为了清楚起见,您也可以使用命名参数,但现在就足够了。

就是这样:没有花哨的转义,但也没有 SQL 注入的可能性。

【讨论】:

    【解决方案3】:

    通常,我将序列化然后 base64_encode 以消除意外并“标准化”输入。例如:

    $things = base64_encode(serialize($_POST['things']));
    $insert_query = "INSERT INTO...";
    

    然后,当您想抓住它时,只需将过程反向即可。

    $query_result = mysql_query("SELECT FROM ...");
    $row = mysql_fetch_assoc($query_result);
    $retrieved_value = unserialize(base64_decode($row['src']);
    

    【讨论】:

      【解决方案4】:

      您正在向数据库写入一个字符串,所以不要忘记在查询中添加引号:

      $q = "INSERT INTO tblslider(src) values('$things')";
      

      还要确保过滤字符串以避免 SQL 注入攻击。

      【讨论】:

        【解决方案5】:

        mysql_query(...) 之前放置一个var_dump($q)
        然后您可以检查您的查询。

        【讨论】:

        • var_dump($q) id 给出这个值 INSERT INTO tblslider(src) values(a:4:{i:0;s:10:"651603.jpg";i:1;s:11: "7184512.jpg";i:2;s:11:"3659637.jpg";i:3;s:10:"569839.jpg";})" v
        • 应该是 insert tblname(src) values(122.jpg, 5646.jpg.....) 好像插入查询是错误的
        • @ppp 在这种情况下,我认为您误解了serialize() 的作用。请查看implode()
        猜你喜欢
        • 1970-01-01
        • 2016-12-28
        • 2013-06-20
        • 2016-04-30
        • 1970-01-01
        • 2011-08-06
        • 2012-12-20
        • 2015-12-09
        • 2019-10-25
        相关资源
        最近更新 更多