2009-11-27 143 views
0

我們有一個文檔管理應用程序。我在MySQL DB中加載了5000個圖像文件。在客戶端刪除文件夾時需要刪除它們。致命錯誤:調用成員函數prepare()在非對象上

使用下面的代碼,

public function delete($dbh){ 

    $sql = "DELETE FROM fileTable WHERE FID=:fid; 
      DELETE FROM file_blobTable WHERE FID=:fid"; 
    $stmt = $dbh -> prepare($sql); 
    $stmt -> bindParam(":fid", $this->fid, PDO::PARAM_INT); 
    $this -> fdid = -1; // 
    if ($stmt -> execute()) { 
     return 0; 
    } 
    return 1; 
} 

上述函數被調用以這種方式循環,

// Loop through the folder and delete all the files it contains. 

foreach ($files as $fileID) { 
    // Get DB handle 
    $dbh1 = DB::getWriteDB(); 

     $f = new File($fileID); 
     $f -> delete($dbh1); 
} 

這工作完全當我們刪除,如果在數據庫中的圖像數量小於500. 如果更多,我遇到了可怕的,

"Fatal error: Call to a member function prepare() on a non-object".

回答

2

爲每次致電function delete生成準備好的聲明不僅效率低下,而且可能是導致錯誤的原因。您只需要準備一次查詢,這是它們存在的兩個主要原因之一。你可以使用一個靜態變量:

public function delete($dbh) { 
    static $sql = "DELETE FROM fileTable WHERE FID=:fid; 
     DELETE FROM file_blobTable WHERE FID=:fid"; 
    static $stmt = $dbh -> prepare($sql); 

或者,因爲你正在使用的對象,無論如何,使用類變量:

static protected function getDeleteQuery($dbh) { 
    static $sql = "DELETE FROM fileTable WHERE FID=:fid; 
     DELETE FROM file_blobTable WHERE FID=:fid"; 
    if (is_null(self::$queries['delete'])) { 
     self::$queries['delete'] = $dbh->prepare($sql); 
    } 
    return self::$queries['delete']; 
} 
public function delete($dbh) { 
    $stmt = self::getDeleteQuery($dbh); 
    ... 
1

作爲替代outis的解決方案,如果你和我一樣,爲了避免靜態函數和變量,您可以重新設計類以僅準備一次語句,並允許您在多個文件上使用一個實例。

class FileManager 
{ 
    private $db_link; 
    private $delete_stmt; 
    private $file_id; 

    public function __construct($db_link, $file_id=null) 
    { 
     $this->db_link = $db_link; 
     $this->file_id = $file_id; 
    } 

    public function setFileID($file_id) 
    { 
     $this->file_id = $file_id; 
    } 

    public function delete() 
    { 
     if(!$this->delete_stmt) 
     { 
      $sql = "DELETE FROM fileTable WHERE FID=:fid; 
          DELETE FROM file_blobTable WHERE FID=:fid"; 
      $this->delete_stmt = $this->db_link->prepare($sql); 
     } 

     $this->delete_stmt->bindParam(":fid", $this->file_id, PDO::PARAM_INT); 
     if ($this->delete_stmt->execute()) { 
      return true; 
     } 
     return false; 
    } 
} 

,你可以使用像這樣:

$file = new FileManager($dbh); 
foreach($files as $file_id) 
{ 
    $file->setFileID($file_id); 
    $file->delete(); 
} 
$file = null; 
相關問題