我需要清洁经营Prestashop的商店,实际上1.7,多年来.
使用this script,我删除了DB中未连接到任何产品的所有图像。
但是有很多文件没有列在数据库中。例如,实际上我在设置中有5个图像大小,所以新产品在文件夹中显示6个文件(上面的5个和imageID.jpg文件),但一些旧产品有多达18个文件。这些旧产品中的许多已经被删除,但在文件夹中我仍然找到所有其他格式,如“2026-small-cart.jpg”。
所以我试着创建一个脚本来循环文件夹,检查其中的图像文件,并验证该id_image是否存储在DB中。如果没有,我可以删除该文件。它工作,但显然循环是巨大的,它停止工作,只要我改变开始路径文件夹。
我试过减少存储数据的DB查询(用一个DB查询删除所有具有相同id的图像),但是当我改变起始路径时,它仍然崩溃。它只适用于两个嵌套循环(真的很少...)。
这是代码。有什么更好的方法来得到结果吗?
谢谢!
$shop_root = $_SERVER['DOCUMENT_ROOT'].'/';
include('./config/config.inc.php');
include('./init.php');
$image_folder = 'img/p/';
$image_folder = 'img/p/2/0/3/2/'; // TEST, existing product
$image_folder = 'img/p/2/0/2/6/'; // TEST, product deleted from DB but files in folder
//$image_folder = 'img/p/2/0/2/'; // test, not working...
$scan_dir = $shop_root.$image_folder;
// will check only images...
global $imgExt;
$imgExt = array("jpg","png","gif","jpeg");
// to avoid multiple queries for the same image id...
global $lastID;
global $delMode;
echo "<h1>Examined folder: $image_folder</h1>\r\n";
function checkFile($scan_dir,$name) {
global $lastID;
global $delMode;
$path = $scan_dir.$name;
$ext = substr($name,strripos($name,".")+1);
// if is an image and file name starts with a number
if (in_array($ext,$imgExt) && (int)$name>0){
// avoid extra queries...
if ($lastID == (int)$name) {
$inDb = $lastID;
} else {
$inDb = (int)Db::getInstance()->getValue('SELECT id_product FROM '._DB_PREFIX_.'image WHERE id_image ='.((int) $name));
$lastID = (int)$name;
$delMode = $inDb;
}
// if haven't found an id_product in the DB for that id_image
if ($delMode<1){
echo "- $path has no related product in the DB I'll DELETE IT<br>\r\n";
//unlink($path);
}
}
}
function checkDir($scan_dir,$name2) {
echo "<h3>Elements found in the folder <i>$scan_dir$name2</i>:</h3>\r\n";
$files = array_values(array_diff(scandir($scan_dir.$name2.'/'), array('..', '.')));
foreach ($files as $key => $name) {
$path = $scan_dir.$name;
if (is_dir($path)) {
// new loop in the subfolder
checkDir($scan_dir,$name);
} else {
// is a file, I'll check if must be deleted
checkFile($scan_dir,$name);
}
}
}
checkDir($scan_dir,'');
1条答案
按热度按时间xv8emn3q1#
我将创建两个包含图像列表的文件。
第一个文件是从数据库查询数据中引用的每个图像文件的结果。
(set首先是DB和DB_PREFIX的shell变量)
第二个文件是当前目录中的所有图像文件。只包括以数字开头并具有图像扩展名的文件。
对于每个文件名,检查它是否在图像ID列表中,如果不在,则输出命令删除文件。
读取文件
files_to_delete
,直观地检查列表是否正确,然后将该文件作为shell脚本运行:注意我还没有测试这个解决方案,但是它应该给予您一些东西来进行实验。