如何在img / p /

时间:2016-02-21 13:27:28

标签: php image optimization prestashop

在Prestashop,当我删除一些产品时,图像保留在他们的目录/ img / p / so,此时我的图像目录接近2GB。 找到这个脚本来删除Prestashop上无用的和BBDD未链接的图像,但我不知道为什么它只检测孤立图像但不删除它们。也许在php配置上禁用unlink功能?可能吗?或者代码错了?还有另一种方法可以进行这种清理吗?

    <?php
// root path of the shop
$shop_root='/home/myweb/public_html/';
// limit number of image files to check, set to 10 for testing
$limit=1000000000;


include $shop_root . '/config/settings.inc.php';
$pdo = new PDO( 'mysql:host='._DB_SERVER_.';dbname='._DB_NAME_, _DB_USER_, _DB_PASSWD_ );
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$r=$pdo->query('select count(1) cnt from ps_image')->fetch();
echo 'count images database: '.$r['cnt'] . "<Br />";

// reset some counters
$cnt_files=0;
$cnt_checked=0;
$cnt_not_found=0;
$cnt_found=0;

for($ii=1; ($ii<=9) && ($cnt_files != $limit); $ii++)
{
        $path=$shop_root.'img/p/'.$ii;
        delImage($path);
        for($jj=0; ($jj<=9) && ($cnt_files != $limit); $jj++)
        {       
                $path=$shop_root.'img/p/'.$ii.'/'.$jj;
                delImage($path);
                for($kk=0; ($kk<=9) && ($cnt_files != $limit); $kk++)
                {
                        $path=$shop_root.'img/p/'.$ii.'/'.$jj.'/'.$kk;
                        delImage($path);
                        for($ll=0; ($ll<=9) && ($cnt_files != $limit); $ll++)
                        {
                                $path=$shop_root.'img/p/'.$ii.'/'.$jj.'/'.$kk.'/'.$ll;
                                delImage($path);
                        }       
                }
        }

}
echo 'files: '.$cnt_files.' checked: '.$cnt_checked.' not_found: '.$cnt_not_found.' found: '.$cnt_found;

function delImage($imageDir)
{
        global $limit, $pdo, $cnt_files, $cnt_checked, $cnt_not_found, $cnt_found;
        if ($handle = @opendir($imageDir)) {                    //@ is wriiten to avoid warning message and is handled in else condition
                echo $imageDir."<BR />";
                while ($cnt_files != $limit && false !== ($entry = readdir($handle))) {
                        if ($entry != "." && $entry != "..") {
                                $cnt_files++;
                                $pi = explode('-',$entry);
                                if($pi[0]>0 && !empty($pi[1])) {
                                        $cnt_checked++;
                                        if(!checkExistsDb($pdo,$pi[0])) {
                                                $cnt_not_found++;
                                                echo 'rm '.$imageDir.'/'.$entry."<BR />";
                                                unlink($imageDir.'/'.$entry);
                                        } else {
                                                $cnt_found++;
                                        }
                                }
                        }
                }
                        closedir($handle);
  }
        else
        {
                echo $imageDir." doesn't exist".'<BR />';
        }

}

function checkExistsDb($pdo, $id_image) {
        $r=$pdo->query($q='select \'ok\' ok, (select id_image from ps_image where id_image = '.(int)$id_image.') id_image');
        $row=$r->fetch();
        if($row['ok']!='ok') die( 'Problem with query, please correct');
        return $row['id_image']?true:false;
}
?>

这是一个输出部分:

/home/myweb/public_html/img/p/9/9/7
/home/myweb/public_html/img/p/9/9/7/0 doesn't exist
/home/myweb/public_html/img/p/9/9/7/1 doesn't exist
/home/myweb/public_html/img/p/9/9/7/2 doesn't exist
/home/myweb/public_html/img/p/9/9/7/3 doesn't exist
/home/myweb/public_html/img/p/9/9/7/4 doesn't exist
/home/myweb/public_html/img/p/9/9/7/5 doesn't exist
/home/myweb/public_html/img/p/9/9/7/6 doesn't exist
/home/myweb/public_html/img/p/9/9/7/7 doesn't exist
/home/myweb/public_html/img/p/9/9/7/8 doesn't exist
/home/myweb/public_html/img/p/9/9/7/9 doesn't exist
/home/myweb/public_html/img/p/9/9/8
/home/myweb/public_html/img/p/9/9/8/0 doesn't exist
/home/myweb/public_html/img/p/9/9/8/1 doesn't exist
/home/myweb/public_html/img/p/9/9/8/2 doesn't exist
/home/myweb/public_html/img/p/9/9/8/3 doesn't exist
/home/myweb/public_html/img/p/9/9/8/4 doesn't exist
/home/myweb/public_html/img/p/9/9/8/5 doesn't exist
/home/myweb/public_html/img/p/9/9/8/6 doesn't exist
/home/myweb/public_html/img/p/9/9/8/7 doesn't exist
/home/myweb/public_html/img/p/9/9/8/8 doesn't exist
/home/myweb/public_html/img/p/9/9/8/9 doesn't exist
/home/myweb/public_html/img/p/9/9/9
/home/myweb/public_html/img/p/9/9/9/0 doesn't exist
/home/myweb/public_html/img/p/9/9/9/1 doesn't exist
/home/myweb/public_html/img/p/9/9/9/2 doesn't exist
/home/myweb/public_html/img/p/9/9/9/3 doesn't exist
/home/myweb/public_html/img/p/9/9/9/4 doesn't exist
/home/myweb/public_html/img/p/9/9/9/5 doesn't exist
/home/myweb/public_html/img/p/9/9/9/6 doesn't exist
/home/myweb/public_html/img/p/9/9/9/7 doesn't exist
/home/myweb/public_html/img/p/9/9/9/8 doesn't exist
/home/myweb/public_html/img/p/9/9/9/9 doesn't exist
files: 29013 checked: 22290 not_found: 0 found: 22290

4 个答案:

答案 0 :(得分:0)

检查文件权限。如果php用户没有权限删除其他用户的文件,则unlink功能将无效。

答案 1 :(得分:0)

它永远不会有效,因为您删除了路径的根目录: 你删除:/ home / myweb / public_html / img / p / 9/9/7 并且在你想要删除之后:/ home / myweb / public_html / img / p / 9/9/7/0但是/ home / myweb / public_html / img / p / 9/9/7不存在:)

要做到这一点:

for($ii=1; ($ii<=9) && ($cnt_files != $limit); $ii++)
{
    $pathRacine=$shop_root.'img/p/'.$ii;
    //delImage($path);
    for($jj=0; ($jj<=9) && ($cnt_files != $limit); $jj++)
    {
            $path1=$shop_root.'img/p/'.$ii.'/'.$jj;
            //delImage($path);
            for($kk=0; ($kk<=9) && ($cnt_files != $limit); $kk++)
            {
                    $path2=$shop_root.'img/p/'.$ii.'/'.$jj.'/'.$kk;
                    //delImage($path);
                    for($ll=0; ($ll<=9) && ($cnt_files != $limit); $ll++)
                    {
                            $path3=$shop_root.'img/p/'.$ii.'/'.$jj.'/'.$kk.'/'.$ll;

                            delImage($path3);
                    }

                    delImage($path2);
            }

            delImage($path1);
    }

    delImage($pathRacine);
}

不要在任何地方使用相同的变量名称

答案 2 :(得分:0)

有关您的信息,当您删除产品时,Prestashop会自动删除与该产品相关的所有图像。

我还检查了你的脚本,通过更改$shop_root并添加配置文件,它对我来说很好。

  

require(dirname(__FILE__).'/config/config.inc.php'); // root path of the shop $shop_root = $_SERVER['DOCUMENT_ROOT']."/";

您需要检查文件夹权限并检查其不允许取消图片链接的原因。

答案 3 :(得分:0)

尝试一下。在经历了不同解决方案的多次失败之后,我花了很多时间来开发此工具。对我来说,这是最安全的方法。

<?php
####PUT THIS FILE INTO YOUR MAIN SHOP FOLDER####

// root path of the shop, almost no one needs to change something here.
$shop_root = $_SERVER['DOCUMENT_ROOT']."/"; // need to have slash / at the end
$image_folder = 'img/p/'; // also needs slash at the ennd
$scan_dir = $shop_root.$image_folder;

include_once($shop_root.'config/config.inc.php');
include $shop_root . 'config/settings.inc.php';

#---------------------------------------------#
$last_id = (int)Db::getInstance()->getValue('
    SELECT id_image FROM '._DB_PREFIX_.'image ORDER BY id_image DESC
');

$counted_images = Db::getInstance()->executeS('
    SELECT count(*) as qnt FROM '._DB_PREFIX_.'image
');
$counted_images = (int)$counted_images[0]['qnt'];


echo 'There was '.$last_id.' images in database but only '.$counted_images.' is used right now. Lets check how many of them are eating up our storage without no reason.<br>';

//$limit = 150; // for testing
$limit = $last_id; // for production

$removed_images = 0;

for ($i=1; $i <= $limit; $i++) {
    if (!imageExistsInDB($i)){
        $imageDir = str_split($i);
        $imageDir = implode('/', $imageDir);
        $path = $scan_dir.$imageDir;
        deleteImagesFromPath($path);
    }
}

function deleteImagesFromPath($path) {
    global $removed_images;
    $images = glob($path . '/*.{jpg,png,gif,jpeg}', GLOB_BRACE);
    if ($images){
        foreach ($images as $file) {
            if (is_file($file)) {
                unlink($file);
            }
        }
        $removed_images++;
        echo 'Deleted images from folder ' . $path . '/' ."<br/>";
    }
}

function imageExistsInDB($id_image){
    return Db::getInstance()->getValue('
        SELECT id_image FROM '._DB_PREFIX_.'image WHERE id_image = '.(int)$id_image
    );
}

echo '--------------------------------------<br>';
if  ($removed_images > 0)
    echo 'Hurray! We removed '.$removed_images.' product images!';
else
    echo 'Everything is ok with Your images. I did not removed any of them or I made it before. Good Job Presta!';