Неустранимая ошибка: вызов функции-члена prepare () для необъекта - PullRequest
0 голосов
/ 27 ноября 2009

У нас есть приложение для управления документами. У меня есть 5000 файлов изображений, загруженных в MySQL DB. Необходимо удалить их при удалении папки на клиенте.

Используя следующий код,

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. Если больше, я сталкиваюсь с ужасом,

«Неустранимая ошибка: вызов функции-члена prepare () для необъекта».

Ответы [ 2 ]

2 голосов
/ 27 ноября 2009

Создание подготовленного оператора для каждого вызова 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 голос
/ 28 ноября 2009

В качестве альтернативы решению 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;
...