2014-05-20 70 views
0

我有一個叫Form的類。我有一個add_form()方法,我打電話將記錄保存到數據庫。 add_form()基本上將記錄添加到數據庫並返回受影響的行。當我在不使用Classes或OOP方法的情況下使用此函數時,它工作正常。但是現在我得到錯誤說exec()是一個未定義的函數。而變量計數沒有定義?我使用exec()是因爲它返回受影響的行而不是隻執行查詢的execute()。PDO MySQL上的類函數

class Forms 
{ 
    private $database; 
    private $count; 

    public function __construct(PDO $database) 
    { 
    $this->database = $database; 
    } 

    function add_form($lastname, $firstname, $island, $region, $province, $baranggay, $city, $address, $gender, $birthdate) 
    { 
    $sql = "INSERT INTO forms (lastname, firstname, island, region, province, baranggay, city, address, gender, birthdate) VALUES (:lastname, :firstname, :island, :region, :province, :baranggay, :city, :address, :gender, :birthdate)"; 
    $stmt = $this->database->prepare($sql); 
    $count->exec(array(
        ':lastname'=>$lastname, 
        ':firstname'=>$firstname, 
        ':island'=>$island, 
        ':region'=>$region, 
        ':province'=>$province, 
        ':baranggay'=>$baranggay, 
        ':city'=>$city, 
        ':address'=>$address, 
        ':gender'=>$gender, 
        ':birthdate'=>$birthdate 
       )); 
    return $count; 
    } 

} 
+1

請在將來:全部包含錯誤消息+告訴我們您試圖自己調試代碼的內容......當然:[RT(F)M] (http://www.php.net/PDO)... –

回答

2

幾件事情,第一:你需要調用方法被調用PDOStatement::execute,不execexec方法是PDOas the manual clearly shows的方法。但是,PDO::exec不是很安全,因爲它不使用預先準備好的語句,所以最好使用PDOStatement,但使用適當的方法。這是很容易從一份聲明中得到受影響的行數,太...
接下來,你指定準備語句(PDOStatement實例)到一個名爲$stmt變量,但呼籲的未定義的變量exec$count

$stmt = $this->database->prepare($sql); 
    $count->exec(array(//<--- should be $stmt->execute(array()); 
        ':lastname'=>$lastname, 
        ':firstname'=>$firstname, 
        ':island'=>$island, 
        ':region'=>$region, 
        ':province'=>$province, 
        ':baranggay'=>$baranggay, 
        ':city'=>$city, 
        ':address'=>$address, 
        ':gender'=>$gender, 
        ':birthdate'=>$birthdate 
)); 

然後,讓受影響的行數,需要調用the rowCount method

return $stmt->rowCount(); 

把這些問題放在一起,並APPLI編輯你的代碼,你需要改變你的代碼:

$stmt->execute(array()); 
$count = $stmt->rowCount(); 
//optional: 
$stmt->closeCursor(); 
return $count; 

爲了完整起見,這裏使用exec不安全的版本:

$vals = array(
    'firstname' => 'Joe', 
    'lastname' => 'Goodboy' 
); 
$count = $pdo->exec(
    'INSERT INTO hackable (firstname, lastname) 
    VALUES ("'.$vals['firstname'].'", "'.$vals['lastname'].'")' 
);//all is well 
//BUT: 
$vals = array(
    'firstname' => 'Evil", /*', 
    'lastname' => '*/ (SELECT CONCAT_WS(",", id, username, password) 
     FROM users 
     WHERE isAdmin = 1 
     LIMIT 1 
    )); --' 
$count = $pdo->exec(
    'INSERT INTO hackable (firstname, lastname) 
    VALUES ("'.$vals['firstname'].'", "'.$vals['lastname'].'")' 
);//OUCH!! 

後者輸入結果查詢:

INSERT INTO hackable (firstname, lastname) 
VALUES ("Evil", /*, "*/ 
    (SELECT CONCAT_WS(",", id, username, password) 
    FROM users 
    WHERE isAdmin = 1 
    )); -- ", "") 

這只是表明,用用戶輸入執行查詢只是一個壞主意......

作爲一個幫助,一些代碼審查
請使其成爲總是寫入訪問修飾符和subscribe to the coding standards most major players subscribe to的習慣。這意味着方法應該是camalCased:add_form應該是addForm。也請你幫個忙,並添加文檔塊:

/** 
* Inserts data provided by $bind into forms table 
* @param array $bind 
* @return int 
* @throw PDOException (if PDO::ERRMODE is set to PDO::ERRMODE_EXCEPTION) 
*/ 
public function addForm(array $bind) 
{//PUBLIC + camelCased name 
    $stmt = $this->database->prepare($queryString); 
    $stmt->execute($bind); 
    return $stmt->rowCount(); 
} 

但就整體而言,這形式有固定的佈局,和值的給定數量的預期。在大型項目中,你可能會最終確定這一數據類:

class From extends DataModel 
{//where DataModel is an abstract class 
    protected $lastname = null; 
    protected $firstname = null; 
    //all properties hiere 
    public function __construct(array $data) 
    {//use assoc array in constructor 
     foreach ($data as $key => $value) 
     { 
      $setter = 'set'.ucfirst($key); 
      if (method_exists($this, $setter))//define setters for properties! 
       $this->{$setter}($value); 
     } 
    } 
    /** 
    * method to turn instance into bind array 
    * Optionally omit null values for WHERE clauses 
    * @param bool $includeNulls = true 
    * @return array 
    */ 
    public function toBind ($includeNulls = true) 
    { 
     $bind = array(
      ':firstname' => $this->firstname, 
      ':lastname' => $this->lastname, 
      //do this for all properties 
     ); 
     if ($includeNulls === false) 
      return array_filter($bind);//unset null values 
     return $bind; 
    } 
} 

如果你想知道爲什麼我勸你使用getter和setter方法,而不是魔術__get__set電話,check out some of my answers on codereview.stackexchange。我已經詳細解釋過這一切