2016-12-27 52 views
2

所以我有这个不完整的方法来保存对象在数据库:数组中的绑定值?

public function save() { 
    $variables = get_object_vars($this); 
    $attributes = []; 

    foreach ($variables as $variable => $value) { 
     $attributes[] = $value; 
    } 

    $variableString = implode(", ", $attributes); 

    foreach ($variables as $variable => $value) { 
     $attributes[] = ":" . $value; 
    } 

    $valueString = implode(", ", $attributes); 

    $sql = "INSERT INTO products (" . $variableString . ") VALUES (" . $valueString . ")"; 
    $query = $this->pdo->prepare($sql); 
    // ... 
} 

如何绑定像这样使用数组我已经创造的价值?

$query->execute(array(
    ':username' => $username, 
    ':email' => $email, 
    ':password' => $password 
)); 

回答

3

这是我会怎么做:

// This gets an associative array 
$variables = get_object_vars($this); 

// Init 
$columns = []; 
$placeholders = []; 
$bindings = []; 

// Loop through variables and build arrays 
foreach ($variables as $column => $value) 
{ 
    $columns[] = $column; 
    $placeholder = ':' . $column; 
    $placeholders[] = $placeholder; 
    $bindings[$placeholder] = $value; 
} 

// Create strings 
$columnString = implode(',', $columns); 
$placeholderString = implode(',', $placeholders); 

// Prepare query 
$sql = "INSERT INTO products (" . $columnString . ") VALUES (" . $placeholderString . ")"; 
$query = $this->pdo->prepare($sql); 

// Execute query 
$query->execute($bindings); 

你基本上准备你需要的东西,然后传递给他们。

我应该提到这可能是一个脆弱的方式,因为它假设您的类中的属性总是总是在您的数据库表中。它基本上需要一个$myModel->non_column = 123;语句在哪里通过并打破你的查询。

好像你正在尝试构建自己的Active Record实现?可能想看看一些大玩家如何做到这一点,或者只是使用他们的。

+0

我正在创建一个Product类的实例,并且想创建一个将其保存到数据库的方法。 – Rudolph

+1

有很多好的框架可以为你做所有这些工作,除非你是在做一个学习练习。我的建议是Laravel:https://laravel.com –

+1

我知道。这是给我的特定任务,以便我了解PHP OOP。感谢你的回答。 – Rudolph

3

请尝试以下方法有$占位符$ COLUMNNAMES来构建你的查询,以及在$属性本身要传递给你的$query->execute()方法

public function save() 
    { 
     $variables = get_object_vars($this); 
     $attributes = []; 

     foreach ($variables as $key => $value) { 
      $attributes[':' . $key] = $value; 
     } 

     $keys = array_keys($attributes); 

     $placeholders = implode(", ", $keys); 
     $columnNames = str_replace(':', '', $placeholders); 

     $sql = "INSERT INTO products (" . $columnNames . ") VALUES (" . $placeholders . ")"; 

     $query = $this->pdo->prepare($sql); 
     // ... 
    } 

的其他方法是构造两个数组,一个用于占位符,另一个用于值,然后使用array_combine方法来实现相同的$属性。然而,这种方法将缺少的列名,你必须确保你的对象提供的所有表列以正确的顺序,即$sql = "INSERT INTO products VALUES (" . $placeholders . ")";

+0

准备一个例子,然后将更新答案 – Ali

+0

提供的例子将做的伎俩,但我可以帮助它思考用这种方法保存您的对象在数据库中的整个想法会导致你麻烦的线,有趣的想法虽然! – Ali

+1

感谢您的回答。这不是我会进一步发展的任何事情。这是一种测试任务。 – Rudolph

1

实际上你已经完成了它。实际上,$variables数组就是您要查找的数据:只需将它发送到​​即可。

此外,上述所有解决方案都过于冗长,我的口味。要创建几个简单的字符串是不是一个大问题:

$variables = get_object_vars($this); 
$columns = array_keys($variables); 

$columnString  = '`'.implode('`,`', $columns).'`'; 
$placeholderString = ':'.implode(',:', $columns); 

$sql = "INSERT INTO products ($columnString) VALUES ($placeholderString)"; 
$this->pdo->prepare($sql)->execute($variables); 

注意,对于动态生成的查询,使用标识周围的分隔符是必须的,因为你永远无法知道哪个属性原来是一个MySQL关键词。

+0

感谢您的答案,我会测试它。 – Rudolph

+0

所以你还是不完全满意。之后怎么样了? –

+0

这似乎更短,就是这样。 – Rudolph