2009-11-27 4 views
0

Nous avons une application de gestion de documents. J'ai 5000 fichiers image chargés dans MySQL DB. Besoin de les supprimer lorsque le dossier est supprimé sur le client.Erreur fatale: Appel à une fonction membre prepare() sur un non-objet

En utilisant le code suivant,

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; 
} 

La fonction ci-dessus est appelée dans une boucle de cette manière,

// 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); 
} 

Cela fonctionne parfaitement lorsque l'on supprime, si le nombre d'images dans le DB est inférieur à 500. Si plus, je suis en cours d'exécution dans la redoutée,

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

Répondre

2

Produire une instruction préparée pour chaque appel à function delete est non seulement inefficace, c'est probablement la cause de votre erreur. Vous n'avez besoin de préparer une requête qu'une seule fois, ce qui est l'une des deux principales raisons pour lesquelles elles existent. Vous pouvez utiliser une variable statique:

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

Ou, puisque vous utilisez des objets de toute façon, utiliser une variable de classe:

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

Comme alternative à outis' solution, si vous, comme moi, Pour éviter les fonctions statiques et les variables, vous pouvez redessiner la classe pour ne préparer l'instruction qu'une seule fois et vous permettre d'utiliser une instance sur plusieurs fichiers.

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; 
    } 
} 

que vous pourriez utiliser comme ceci:

$file = new FileManager($dbh); 
foreach($files as $file_id) 
{ 
    $file->setFileID($file_id); 
    $file->delete(); 
} 
$file = null; 
Questions connexes