【问题标题】:INSERT row from another table using php PDO使用 php PDO 从另一个表插入行
【发布时间】:2015-12-24 05:34:59
【问题描述】:

我是 PDO 和 php 的新手。我想通过发送到下面脚本的链接将一行从一个表移动到另一个表。

LINK "id" 用作 invtable 中的主键,(请参阅下面脚本中的 FROM invtable)

提交-ads-florida.php?id=01820007985

脚本提交-ads-florida.php

<?php
    $host = "localhost";
    $user = "user";
    $password = "pass";
    $database_name = "db";
    $pdo = new PDO("mysql:host=$host;dbname=$database_name", $user, $password, array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    ));

$barCode = $GET['id'];

$query = "INSERT INTO adstable (Brand, Description, Price, Size, Price, Barcode) 
          SELECT Brand, Description, Price, Size, Price, Barcode FROM invtable 
          WHERE Barcode='".$barCode."'";

$pdo->query($query);
?>

问题

通过 GET[id] 删除了额外的括号)。我收到以下错误。

致命错误:在 /home/myaccount/public_html/florida-ave/submit-ads-florida 中出现消息“SQLSTATE[42000] 的未捕获异常“PDOException”:语法错误或访问冲突:1110 列“价格”指定了两次” .php:16 堆栈跟踪:#0 /home/myaccount/public_html/florida-ave/submit-ads-florida.php(16): PDO->query('INSERT INTO flo...') #1 {main}在第 16 行扔进 /home/myaccount/public_html/florida-ave/submit-ads-florida.php

更新

我更正了多个价格条目。没有数据被添加到 adstable 中,我也没有收到任何错误。

【问题讨论】:

  • "INSERT INTO adstable (Brand, Description, Price, Size, Price, Barcode) SELECT Brand, Description, Price, Size, Price, Barcode FROM invtable WHERE Barcode='".$barCode."'"; 你想做什么? INSERT? SELECT?或者呃,INSELECT?
  • 如果我把链接改成?id=1' OR Description LIKE '%'怎么办?这是一个注入漏洞。 $barCode = $GET['id']); 也是一个语法错误:它应该是 $barCode = $GET['id'];(不是括号)。确保打开display_errors并将错误级别设置为E_ALL|E_STRICT
  • @HawasKaPujaari: INSERTSELECT 查询的结果集,这是完全有效的,虽然有点奇怪
  • @CliffT:错误信息很清楚,您的SELECT 语句选择了Price 字段两次:SELECT Brand, Description, &gt;Price&lt;, Size, &gt;Price&lt;
  • @EliasVanOotegem 感谢您指出这一点,我以为我是唯一一个阅读异常消息的人Column 'Price' specified twice

标签: php pdo insert


【解决方案1】:

好的,所以您遇到/遇到的问题是:

  • $barCode = $GET['id']); 应该是 $barCode = $GET['id'];,甚至可能是 $_GET['id'];
  • 您的SELECT 查询选择同一字段两次(SELECT Brand, Description, &gt;Price&lt;, Size, &gt;Price&lt;)
  • 您还要在同一字段中插入两次:INSERT INTO adstable (Brand, Description, &gt;Price&lt;, Size, &gt;Price&lt;
  • 您仍然容易受到注入攻击

让我们来解决问题:

$barCode = isset($_GET['id']) ? $_GET['id'] : null;//avoids undefined index notice

接下来,要在SELECT 查询中使用相同的字段两次,您可以定义一个别名,但您不需要两次相同的字段...

SELET SELECT Brand, Description, Price as price_1, Size, Price as price_2, Barcode FROM

那么,为了防止一级注入攻击,让我们使用准备好的语句,而不是使用 GET 参数调用PDO::query

$stmt = $pdo->prepare('INSERT INTO adstable (Brand, Description, Price, Size, Barcode) 
      SELECT Brand, Description, Price, Size, Barcode FROM invtable 
      WHERE Barcode=:barcode'
);
$stmt->execute([':barcode' => $barCode]);

代码应该是这样的:

$barCode = isset($_GET['id']) ? (int) $_GET['id'] : null;
// check $barCode is valid value, if not, don't bother connecting
if ($barCode) {
    $pdo = new PDO(
        sprintf(
            'mysql:host=%s;dbname=%s;charset=utf8', // add charset here!
            $host,
            $dbName
        ),
        $user, $password,
        [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        ]
    );
    $stmt = $pdo->prepare(
        'INSERT INTO adstable(Brand, Description, Price, Size, Barcode)
         SELECT Brand, Description, Price, Size, Barcode FROM invtable
         WHERE Barcode = :barcode'
    );
    $stmt->execute(
        [
            ':barcode' => $barCode
        ]
    );
}

这应该可以解决问题。但说真的:错误消息告诉你出了什么问题 阅读它们

【讨论】:

  • @RyanVincent:刚刚注意到 OP 在同一个字段中插入。这根本不可能。另外:Price1Price2 是完全相同的字段,因为SELECT 查询也包含相同的错误。
  • 感谢您的帮助、时间和忍受我明显的疏忽。我会消化您的最新评论并回复您。
  • 我将 $database_name 更改为 $dbName ,就像您在代码中所做的那样,并用您的代码替换了 $dbName 之后的代码,它完美运行!!!我还有很多要学习的 php,但我会回到你的示例作为前进的参考。再次感谢您的时间和帮助。
【解决方案2】:

请检查并更正此行:$barCode = $GET['id'];

如果这不是您的解决方案,请告诉我。

【讨论】:

    猜你喜欢
    • 2012-12-05
    • 2016-06-07
    • 2014-09-20
    • 2014-05-06
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    相关资源
    最近更新 更多