【问题标题】:PDO: Making an execute statement dynamic...but not workingPDO:使执行语句动态...但不起作用
【发布时间】:2014-06-10 01:40:09
【问题描述】:

这应该很容易...但我想不通。如果下面的执行语句在插入查询的末尾起作用.....

     $query->execute(array($this->visible_password, 
                           $this->hashed_password, 
                           $this->temp_hashed_password, 
                           $this->first_name, 
                           $this->last_name, 
                           $this->position, 
                           $this->location, 
                           $this->city, 
                           $this->email, 
                           $this->country, 
                           $this->institution, 
                           $this->interests, 
                           $this->profile_comment));

       $result =  join(", ", array_values($place_holder));
       echo $result;

给予

$this->visible_password, $this->hashed_pa​​ssword, $this->temp_hashed_pa​​ssword, $this->email, $this->first_name, $this->last_name, $this->position, $this->location , $this->city, $this->country, $this->institution, $this->interests, $this->profile_comment

那为什么这不起作用.....

     $query->execute(array($result))

占位符上的 var_dump 给出...

   array(13) { 

 [0]=> string(26) "$this->visible_password" 
 [1]=> string(25) "$this->hashed_password" 
 [2]=> string(30) "$this->temp_hashed_password" 
 [3]=> string(15) "$this->email" 
 [4]=> string(20) "$this->first_name" 
 [5]=> string(19) "$this->last_name" 
 [6]=> string(18) "$this->position" 
 [7]=> string(18) "$this->location" 
 [8]=> string(14) "$this->city" 
 [9]=> string(17) "$this->country" 
 [10]=> string(21) "$this->institution" 
 [11]=> string(19) "$this->interests" 
 [12]=> string(25) "$this->profile_comment" }

$placeholder 是一个数组...接受类的属性($attributes)

            $place_holder = array();
            foreach ($attributes as $key => $value) {
            $place_holder[] = "&#36this->" . $key;
        }

我一直在尝试在我的用户类抽象中创建用户方法,以便我可以在我的所有类中使用它。我一直在将我的网站从 mysqli(噩梦)转换为 PDO。这里是方法....

public function  pdo_create_test() {

  $attributes = $this->attributes();
  $att = array_keys($attributes);     
   $question_marks = array();
    foreach ($attributes as $key => $value) {
            $question_marks[] = "?";
    }
   $place_holder = array();
    foreach ($attributes as $key => $value) {
           $place_holder[] = "&#36this->" . $key;
        }
  $result = join(", ", array_values($place_holder));
  $sql = "INSERT INTO ".self::$table_name." (";
  $sql .= join(", ", array_keys($attributes));
  $sql .= ") VALUES (";
  $sql .= join(", ", array_values($question_marks));
  $sql .= ")";
  $query = $handler->prepare($sql);
  $query->execute(array($this->visible_password, 
                      $this->hashed_password, 
                      $this->temp_hashed_password, 
                      $this->first_name, 
                      $this->last_name, 
                      $this->position, 
                      $this->location, 
                      $this->city, 
                      $this->email, 
                      $this->country, 
                      $this->institution, 
                      $this->interests, 
                      $this->profile_comment));

                   }

这是一个更新......(我已经改变了占位符以获得比尔所说的值) 我还呼应了 sql 和占位符的结果,以查看其内容。

public function  pdo_create_test() {
  global $handler;
  $attributes = $this->attributes();
  $att = array_keys($attributes);
  $question_marks = array();
    foreach ($attributes as $key => $value) {
    $question_marks[] = "?";
    }
  $place_holder = array();
    foreach ($attributes as $key => $value) {
    $place_holder[] = $this->$key;
        }
  $result = join(", ", array_values($place_holder));
  $sql = "INSERT INTO ".self::$table_name." (";
  $sql .= join(", ", array_keys($attributes));
  $sql .= ") VALUES (";
  $sql .= join(", ", array_values($question_marks));
  $sql .= ")";
    echo $sql;
    echo "<br/>";
    echo "<br/>";
    echo $result;
    $query = $handler->prepare($sql);
    $query->execute(array($result));

}

             $user = new User;
             $user->visible_password = "Sam";
             $user->hashed_password = "Walsh";
             $user->pdo_create_test();

输出是

插入用户(visible_password、hashed_pa​​ssword、temp_hashed_pa​​ssword、email、first_name、last_name、位置、位置、城市、国家、机构、兴趣、profile_comment)值(?、?、?、?、?、?、?、? , ?, ?, ?, ?, ?)

山姆,沃尔什,,,,,,,,,,,,,,,,

但没有进入数据库....不明白为什么...其他数据库字段设置为 NULL 所以这不是问题....

【问题讨论】:

  • $place_holder 包含什么?发布var_dump($place_holder);的输出。
  • 您的 $place_holder 值是字符串而不是变量,因此您的 join() 也返回一个字符串,而不是变量。你如何定义$place_holder

标签: php pdo


【解决方案1】:

PHP 确实有variable variables 的概念,所以你可以这样做:

$varname = 'foo';

$foo = 123;

echo $$varname;

但是这个功能是有限的。您不能将其应用于数组的所有元素,也不能将其与 $this-&gt;foo 表示法一起用于对象变量。

您可以使用变量变量语法来获取与属性对应的对象变量的

$place_holder = array();
foreach ($attributes as $key => $value) {
    $place_holder[] = $this->$key;
}

注意-&gt; 后面的$key。通常对象变量语法在那个地方没有$。通过在那里使用$,我告诉它获取名称为$key 的值的对象变量的值。

顺便说一句,这里有一种更简洁(可能更快)的方法来做同样的事情:

$place_holder = array_intersect_key($attributes, get_object_vars($this));

你的评论:

好吧,首先,你做错了:

$result = join(", ", array_values($place_holder));

这会生成一个字符串,其中的值用逗号分隔。是否将其包装在 array($result) 中并不重要,它只会创建单个字符串的数组,即使单个字符串包含逗号。

换句话说,这两个数组完全不同:

array('A,B,C') // array with one element

array('A', 'B', 'C') // array with three elements

相反,您需要传递给execute() 的是一个元素数量与? 占位符数量相同的数组。

所以只要通过这个:

$query->execute($place_holder);

其次,您需要在每个prepare()execute() 之后检查错误:

if (($query = $handler->prepare(...)) === false) {
  print_r($handler->errorInfo());
}
if ($query->execute($result) === false) {
  print_r($query->errorInfo());
}

或者,如果这看起来编码太多,您可以改为enable PDO exceptions,错误将导致您的应用因错误而终止。

$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

【讨论】:

  • Bill 尝试了这两种方法...请参阅我上面的较低编辑...输出表明正在输入正确的值,但数据库中没有发生任何事情...
  • 您好先生是个天才....虽然我确实必须使用 array_values() 将数组转换为索引数组。也感谢您提供错误提示...我将实施这些提示。
【解决方案2】:

我不确定您的 place_holder 变量包含什么,但我认为这可能是原因。 Join 只是返回字符串的 implode 函数的另一个名称。执行需要实际的物理输入项。

execute 上的 PHP 站点获取输入值数组:

包含与绑定参数一样多的元素的值数组 在正在执行的 SQL 语句中。所有值都被视为 PDO::PARAM_STR。

更新

如 cmets 中所述,这是一个使用给定数据对象执行 SQL 字符串的函数。最好将其分成几个函数(创建参数数组、绑定参数等),但为了便于阅读,我将它们全部放在一个函数中。

该函数的示例使用可能是executeQuery('SELECT * FROM users WHERE id = :id', array('id' =&gt; 1));

function executeQuery($sql, $data) {
    //Assumed that $pdo is created and is a valid PDO object
    $params = array();
    preg_match_all('/:\w+/', $sql, $matches);
    //Loop through all the matches
    //Create an array that looks like: array(
    //  :id => 1, 
    //  :name => 'Me'
    //)
    foreach($matches[0] as $param) {
        $paramName = substr($param, 1);
        //If the item is not supplied in the data object, null will be used
        $params[$param] = isset($data[$paramName]) && !empty($data[$paramName]) ? $data[$paramName] : null;
    }
    //Pepare the SQL statement
    if(($stmt = $pdo->prepare($sql)) !== false) {
        //Bind all parameters
        foreach($params as $param => $value) {
            $stmt->bindValue($param, $value);
        }
        //Execute the statement
        $stmt->execute();
    }
}

【讨论】:

  • 明白,但肯定有办法让这个动态化,不是吗?
  • 您在寻找什么样的动态功能?我将发布一些我在一些项目中使用过的东西,以使其更容易一些。
  • 我一直在尝试在我的用户类抽象中创建用户方法,以便我可以在我的所有类中使用它。我一直在将我的网站从 mysqli(噩梦)转换为 PDO。
  • @GhostRider 我已经用一个示例函数更新了我的答案,以将项目动态绑定到给定的查询。
  • 好的,我要研究这个并试一试。抱歉,如果我需要一些时间才能得出结果......
猜你喜欢
  • 2016-09-29
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
相关资源
最近更新 更多