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

0

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

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

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() для не-объекта".

Теги:
file
loops
file-io

2 ответа

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;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню