【问题标题】:PDO Named parameters inside JSONJSON 中的 PDO 命名参数
【发布时间】:2018-01-06 02:34:59
【问题描述】:

我的数据应该在 JSON 格式的字符串中进行转义,因此我使用 PDO 的命名参数和 PDO::Prepare 来绑定它们。 因为带有撇号的 JSON 在 MySQL 查询中会导致错误,所以我必须在它周围使用单引号 - 尽管这会导致 PDO::Prepare 忽略 JSON 中的命名参数,所以它会因SQLSTATE[HY093]: Invalid parameter number: parameter was not defined 而失败。

任何想法如何解决这个问题?

function send($_data) {
  global $_SESSION;
  global $dbApi;

  #These are temporary debug variables:
  $_SESSION['room_id'] = 1;
  $id = 124;

  $json  = '"' . $id . '": {"user_id": ":email","data": ":data"}';
  $query  = "UPDATE `room_index` " . 
            "SET `data` = JSON_ARRAY_INSERT(`data`, '$[0]', '" . $json . "') " .
            "WHERE `id` = :room_id";

  $dbApi->query($query, array(':email' => $_SESSION['email'],
                              ':data' => $_data,
                              ':room_id' => $_SESSION['room_id']));
}

稍微解释一下代码,:email ($_SESSION['email']) 不一定是参数,但这样更简洁。主要问题是:data ($_data) - 即用户通过 JS 直接从textarea 输入。

$dbApi 是一个具有正确query 函数的类,如下所示:

function query($_query, $_params = array()) {
  global $_DB; # <- Database connection object

  $query = $_DB->prepare($_query);

  if (! $query)
    echo $_DB->errorInfo();
  try {
    $query->execute($_params);
  } catch (PDOException $e) {
    die( $e->getMessage() );
  }

  return $query;
}

【问题讨论】:

  • @LawrenceCherone 正如你所看到的,我正在使用 JSON_ARRAY_INSERT,它将这个 JSON 插入到 {} 中,据我所知,它是有效的。而且我很确定为什么您认为我的:data 参数不存在,它无效并且不会被替换,这就是整个问题,但是它就在那里,就像:email 一样在那里。
  • 你不能像这样使用 JSON_ARRAY_INSERT。编辑您的问题,询问如何做您需要的事情。老实说,我不知道它应该是什么。您是要覆盖整个数据还是什么?
  • @YourCommonSense 谢谢,你让我研究了不同的插入,显然 JSON_INSERT 更适合我的情况。我还设法使用 JSON_OBJECT 修复了代码,从而消除了对引号的需求。
  • 请注意,这里的内容完全是一团糟。我只希望在您的新解决方案中正确使用参数
  • @YourCommonSense 我也希望如此:D 我会尽快发布答案 - 我的意思是,它可以正常工作并生成有效的 JSON,所以我可能做得对。直接来自 MySQL:{"124": {"user_id": "email@email.com", "data": "asdfasdf"}, "125": {"user_id": "email@email.com", "data": "textofanothermessage"}, "126": {"user_id": "email@email.com", "data": "message3"}},这就是我想要做的。

标签: php mysql json pdo prepared-statement


【解决方案1】:

代码有 2 个问题。

1。 JSON_INSERT 更合适。

当我将命名对象插入另一个对象(顶级文档)时,JSON_INSERT 立即提供了这样的语法

2。使用 JSON_OBJECT 而不是手动编写 JSON 语法

由于我的主要问题是,PDO 不会替换单引号或双引号参数,因此解决方案是使用 JSON_OBJECT,它不需要双引号,因为它们稍后会自动生成(我的假设) - 但在 PDO 替换之后变量,并在它们周围放置单引号。

新的、经过测试的代码输出有效的 JSON:

#Temporary, to avoid other unrelated issues
$_SESSION['room_id'] = 1;
$_SESSION['email'] = 'email@email.com';
$id = 123;

$json  = 'JSON_OBJECT("user_id", :email, "data", :data)';
$query  = "UPDATE `room_index` " . 
          "SET `data` = JSON_INSERT(`data`, :id, $json) " .
          "WHERE `id` = :room_id";

$dbApi->query($query, [':id' => "$." . $id,
                       ':email' => $_SESSION['email'],
                       ':data' => $_data,
                       ':room_id' => $_SESSION['room_id']]);

【讨论】:

  • 作为奖励,JSON 中的双引号不会像以前那样转义 - 使其更具可读性和更易于使用。
  • @YourCommonSense 我不确定您所说的不当是什么意思(您可能会说我对 PDO 并不完全熟悉)...唯一的变量应该是静态的$json,它就在那里只是为了可读性。
  • 我的错误我忽略了它。
  • @YourCommonSense 不用担心 :) 你几乎让我信服了 :D 另外,即使我愿意,我也不能将 $json 变量写为参数,因为它里面的参数不会不会被替换。
  • @YourCommonSense 另外感谢,您的第一条评论让我再次查找 JSON_ARRAY_INSERT,并注意另一个功能 - 引导我找到我的解决方案。
猜你喜欢
  • 2010-09-27
  • 2014-03-13
  • 2015-09-23
  • 2017-01-21
  • 2011-11-07
  • 2011-01-26
相关资源
最近更新 更多