我们有一个文档管理应用程序。我在mysql DB中加载了5000个图像文件。在客户端删除文件夹时需要删除它们。
使用以下代码
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()”。
答案 0 :(得分: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 :(得分: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;