2016-12-27 33 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