PHP PDO - 使用bindParam插入INSTO不起作用

时间:2017-08-11 11:08:54

标签: php mysql pdo

我坚持使用这段代码:

$fruit_object = new fruit(1234, 'apple', 'red apple');    

try {
    $dbh = new PDO('mysql:host=localhost;charset=utf8;dbname=database', 'user', 'password');
    $exc = $dbh->prepare("INSERT INTO fruit( type, name) VALUES (:type, :name);");                               
    //$exc->bindParam(':id',   $fruit_object->id,   PDO::PARAM_INT);
    $exc->bindParam(':type', $fruit_object->type, PDO::PARAM_STR);
    $exc->bindParam(':name', $fruit_object->name, PDO::PARAM_STR);
    $exc->execute();
    $dbh = null;
    $exc = null;
} catch (PDOException $e) {
    //this function just do an echo with static content
    $this->error_database($e);
    $dbh = null;
    $exc = null;
    die();
}

我已经使用PDO从我的数据库中选择了东西,但是使用INSERTING东西,它不起作用。用户只能访问INSERT东西 - 我已经在我的后端成功尝试过了。

所以这是错误:

Fatal error: Uncaught Error: Cannot access private property fruit_object::$type

这是我的fruit_object类:

<?php


class fruit
{
private $id;
private $type;
private $name;

function __construct($id, $type, $name)
{
    $this->id = $id;
    $this->type = $type;
    $this->name = $name;

}

function __toString()
{
    return $this->name;
}
}

对于马丁:

INSERT INTO fruit (id, type, name) VALUES (DEFAULT, 'apple', 'red apple');

我的数据库在MySQL服务器上运行 - 这是原因吗?我是否必须使用问号(?)?

谢谢路易斯

3 个答案:

答案 0 :(得分:2)

您缺少准备和半结肠的右括号

$exc = $dbh->prepare("INSERT INTO fruit(id, type, name) VALUES (:id, :type, :name)");

如果不起作用,则添加此行以检查错误

print_r($exc->errorInfo());

答案 1 :(得分:2)

回答问题1:

PHP PDO - 使用bindParam INSERT INTO不起作用

  

如果您在自动增量字段中插入ID并且已经插入,则会导致MySQL错误(重复A_I字段值) - Martin

  

是的,我知道,我在我的真实陈述中使用了DEFAULT关键字。 - louis12356

  

解释;什么是默认关键字? - 马丁

  

有一个SQL关键字'DEFAULT'可以自动计算ID。 - louis12356

您应为自动增量(id)列提供值。它看起来像是通过 PDO变量提供 MySQL指令从不工作。这是因为PDO使用预备语句,因此变量永远不会是变量,永远不能是指令

MySQL中的Default关键字是MySQL程序的指令。该指令将被忽略,不仅因为它被禁止,而且因为您将STRING值传递给PDO INSERT,声称它应该是INT

 $exc->bindParam(':id',   $fruit_object->id,   PDO::PARAM_INT);

如果$fruit_object->id == "DEFAULT"这不是一个整数;因此PDO不会运行查询。

解决方案

无需插入自动增量值,忽略它们:

try {
    $dbh = new PDO('mysql:host=localhost;charset=utf8;dbname=database', 'user', 'password');
    $exc = $dbh->prepare("INSERT INTO fruit( type, name) VALUES ( :type, :name);");                               
    // $exc->bindParam(':id',   $fruit_object->id,   PDO::PARAM_INT);
    $exc->bindParam(':type', $fruit_object->type, PDO::PARAM_STR);
    $exc->bindParam(':name', $fruit_object->name, PDO::PARAM_STR);
    $exc->execute();
    $dbh = null;
    $exc = null;
}

您尝试运行的示例:

 INSERT INTO fruit (id, type, name) VALUES (DEFAULT, 'apple', 'red apple');

但由于PDO的安全限制(忽略String / Int数据类型问题),实际运行的是:

INSERT INTO fruit (id, type, name) 
     VALUES ( <int var> "DEFAULT", <str var> "apple", <str var> "red apple"); 

所以你试图将字符串变量“Default”插入MySQL中的整数列

回答问题2:

 Fatal error: Uncaught Error: Cannot access private property fruit_object::$type

这是因为您的类将此类型的值设置为Private而不是Public,这意味着该值无法在类外显示(这略微过于简化,但时间紧迫了我!)

您需要做的是:

  • 将您的值可访问性设置为public
  • ,在您的课程中构建setter and getter methods,以便您可以根据需要随时拨出这些私人值(哦matron !! )。

所以:

class fruit
{
    private $id;
    private $type;
    private $name;

    /***
     * Getter
     ***/ 
    function getType()
    {
        return $this->type;
    }

    /***
     * Setter
     ***/
    function setType($value){
         $this->type = $value;
    }
}

然后在你的PDO中:

$exc->bindParam(':type', $fruit_object->getType(), PDO::PARAM_STR);

这会将您的值输出到脚本。

如果您想要一种更简单的方法,只需将private $name;替换为public $name;,然后可以从类外部访问命名变量值:

 $exc->bindParam(':name', $fruit_object->name, PDO::PARAM_STR);

答案 2 :(得分:0)

如果你使用(?)将是下一个代码

$exc = $dbh->prepare("INSERT INTO fruit(id, type, name) VALUES (?, ?, ?)");                               
$exc->bindParam(1,   $fruit_object->id,   PDO::PARAM_INT);
$exc->bindParam(2, $fruit_object->type, PDO::PARAM_STR);
$exc->bindParam(3, $fruit_object->name, PDO::PARAM_STR);
$exc->execute();