|
|
|
| Здравствуйте!
В течении времени работы сайта накопилось очень много не используемых фото в каталоге сервера.
В ручную удалять очень трудоемкий процесс, т.к. их много и не известно отображается она на сайте или нет.
В базе данных пути к фото уже нет, а сама фото еще хранится (может не удалилась или изначально не загрузилась в каталог) или бывает наоборот, фото нет в каталоге, а путь в базе есть.
В общем бардак полный.
1. Как очистить каталог на сервере от не нужных фото и "пустых" путей к фото в базе?
2. Как изначально предотвратить запись пути к фото в базе без самого фото и наоборот? | |
|
|
|
|
|
|
|
для: segazav
(27.03.2014 в 11:18)
| | Ну если у вас должно быть строгое соответствие файл-база, чистите по отсутствию связи, в чем проблема? | |
|
|
|
|
|
|
|
для: KPETuH
(27.03.2014 в 11:28)
| | Что чистить по отсутствию связи между ними это я понял, а как именно? | |
|
|
|
|
|
|
|
для: segazav
(27.03.2014 в 11:53)
| | Запрос на выдачу все путей к фоткам.
В цикле пока есть такие пути проверять, есть ли такой файл.
Если есть файл, оставить запись, нет файла - удалить запись.
Потом наоборот - пройтись по файлам в папке. Выяснить имя
файла, если это картинка, проверить, есть ли на него ссылка
в таблице. Есть - оставить, нет - удалить. Если, конечно, в
папке с картинками хранятся только фотографии и нет других
картинок, не занесенных в базу фотографий (фоны, кнопки и т.д.) | |
|
|
|
|
|
|
|
для: elenaki
(27.03.2014 в 12:35)
| | А как избежать дальнейшей записи при отсутствии связи "путь-картинка" | |
|
|
|
|
|
|
|
для: segazav
(27.03.2014 в 12:50)
| | записывать в базу только в случае наличия файла физически. | |
|
|
|
|
|
|
|
для: KPETuH
(27.03.2014 в 13:02)
| | Какие функции лучше использовать, можно пример с кодом проверки файла физически | |
|
|
|
|
 2.9 Кб |
|
|
для: segazav
(27.03.2014 в 13:05)
| | В приложении файл, который мне дали давно на этом форуме. Я им меняла размеры у
фотографий (фотошоп своей пакетной обработкой мне поменял все имена, пришлось
переделывать). Если убрать комменты, то можно вывести структуру заданного ката-
лога. А потом вместо изменения размеров подставить свои действия - запрос и т.д. | |
|
|
|
|
|
|
|
|
для: KPETuH
(27.03.2014 в 15:15)
| | кстати не самый лучший подход. в том плане, что будет результат true даже если переданный аргумент директория. так что если вдруг попадет пустое имя файла, до будет попытка удалить директорию. я бы лучше использовал is_file | |
|
|
|
|
|
|
|
для: elenaki
(27.03.2014 в 12:35)
| | Это получается цикл в цикле?rnОчень мощный запрос, файлов около 9 Гб. а записей с путями десятки тысяч.rnНе один сервер не даст выполнить такой код по времени выполнения скрипта.rnКак быть? | |
|
|
|
|
|
|
|
для: segazav
(27.03.2014 в 11:18)
| | >Как изначально предотвратить запись пути к фото в базе без самого фото и наоборот?
Это как смотреть на ситуацию - если фото, это обязательное условие, значит и записи не должно быть до тех пор, пока первое не загружено, если путь это всего лишь конфигурация и фото необязательное условие, то записывать нужно не путь, а признак есть/нет. | |
|
|
|
|
|
|
|
для: confirm
(27.03.2014 в 15:52)
| | Всем участникам - спасибо!!!
Буду пробовать проводить зачистку, чего бы нужного не удалилось))) | |
|
|
|
|
|
|
|
для: confirm
(27.03.2014 в 15:52)
| | А можно как то так реализовать на деле:
1. собрать все имена файлов из каталога в один массив
2. собрать все пути файлов из базы данных в один массив
3. сравнить эти массивы и если нет соответствующих пар, удалить файл либо путь в базе.
Без использования циклов, т.е. не по одному файлу сравнивать, а все сразу. | |
|
|
|
|
|
|
|
для: segazav
(28.03.2014 в 11:49)
| | у вас какая-то каша в голове. просто напишите скрипт, который будет обходить все директории последовательно и проверять существование изображения в базе данных. все что не найдутся в базе удаляйте. естественно, нужно обязательно вести лог-файл, чтобы видеть сколько директорий он уже прошел, чтобы не обходить их снова. не будет отрабатывать за один раз - запускайте 2 раза, 5 раз. неважно. циклы тут вообще непричем, основная нагрузка именно чтение из директории, ну и проверка в базе, если записей очень много. поэтому чтобы проверка в базе работала быстрее желательно добавить индекс для имени изображения в таблице. | |
|
|
|
|
|
|
|
для: psychomc
(28.03.2014 в 13:30)
| | При попытке очистить сервер от не нужных файлов почему то удалились даже те, пути на которые были в базе данных.
foreach (glob("foto/*.*") as $filename)
{
$filename = basename($filename);
$file = "foto/". $filename;
$result1212 = mysql_query ("SELECT id FROM doska WHERE foto_mini1='$file'
OR foto_mini2='$file'
OR foto_mini3='$file'
OR foto_mini4='$file'
OR foto_mini5='$file'
OR foto_mini6='$file'
OR foto_big1='$file'
OR foto_big2='$file'
OR foto_big3='$file'
OR foto_big4='$file'
OR foto_big5='$file'
OR foto_big6='$file'",$db);
$myrow1212 = mysql_fetch_array ($result1212);
if (!$myrow1212 = mysql_fetch_array ($result1212)) // если нет такой записи в таблице
{
if (unlink($file)) echo "$file<br>";
}
/*$i++;
if ($i==100) break; // Задаём количество выполнения циклов*/
}
|
| |
|
|
|
|
|
|
|
для: segazav
(31.03.2014 в 00:52)
| | ... вы сами написали этот скрипт? я боюсь, здесь нет смысла что-то объяснять. просто сходите в документацию почитайте как работает MYSQL COUNT, mysql_fetch_array/mysql_fetch_assoc, mysql_result, да и glob можно тоже. обязательно посмотрите на примеры использования
p.s а почему для одних и тех же фотографий разных размеров в базе данных используются разные имена файлов? | |
|
|
|
|
|
|
|
для: psychomc
(31.03.2014 в 01:03)
| | Если бы я знал что нужно исправить, я бы исправил. | |
|
|
|
|
|
|
|
для: segazav
(31.03.2014 в 11:00)
| | есть 2 пути
1) правильный: идити в документацию, внимательно читайте про то что я написал и смотрите примеры
2) не совсем правильный: выкладывайте здесь дамп таблицы "doska" и немного данных и ждите, может быть вам помогут и перепишут. у меня в данный момент нет на это времени | |
|
|
|
|
|
|
|
для: psychomc
(31.03.2014 в 11:12)
| | Нашел более оптимальное и менее мощное решение.
$result = mysql_query ("SELECT foto_mini1,foto_mini2,foto_mini3,foto_mini4,foto_mini5,foto_mini6,foto_big1,foto_big2,foto_big3,foto_ big4,foto_big5,foto_big6 FROM doska",$db);
$myrow = mysql_fetch_array ($result);
$dh = opendir('podaty_obyavlenie/foto/'); // Открыть папку
while (false !== ($filename = readdir($dh))) {
// собрать все файлы
if ( $filename != "." && $filename != ".."){
$file_dir[] = "foto/". $filename;
}
}
closedir($dh);
// Расхождение массивов
$raznica = array_diff($file_dir, $myrow); // сравниваем массивы
if (is_array($raznica)) // если файл является массивом
{
foreach ($raznica as $del_foto)
{
echo "$del_foto<br><br>"; // удаляем файлы
}
}
|
Ресурсов вроде хватает, но разные результаты массивов print_r($myrow);
Array ( [0] => [foto_mini1] => [1] => [foto_mini2] => [2] => [foto_mini3] => [3] => [foto_mini4] => [4] => [foto_mini5] => [5] => [foto_mini6] => [6] => [foto_big1] =>
[7] => [foto_big2] => [8] => [foto_big3] => [9] => [foto_big4] => [10] =>
[foto_big5] => [11] => [foto_big6] => )
А результат print_r($file_dir):
Array ( [0] => foto/0.11298200 1332744739.jpg [1] => foto/0.98137800 1373571971.jpg [2] => foto/0.22620400 1361369943.jpg [3] => foto/0.33276300 1378456558.jpg [4] => foto/0.67648100 1394874976.jpg [5] => foto/0.82936300 1322641887.jpg [6] => foto/0.98386900 1394688107.jpg [7] => foto/0.71861900 1332954448.jpg [8] =>
Как привести массивы к одинаковому виду, чтобы получить $raznica? | |
|
|
|
|
|
|
|
для: segazav
(02.04.2014 в 02:52)
| | здесь всё неправильно. вот эта конструкция
$result = mysql_query ("SELECT foto_mini1,foto_mini2,foto_mini3,foto_mini4,foto_mini5,foto_mini6,foto_big1,foto_big2,foto_big3,foto_ big4,foto_big5,foto_big6 FROM doska",$db);
$myrow = mysql_fetch_array ($result);
|
выбирает только первую по счету строку из таблицы doska а дальше вы выбираете ВСЕ картинки из директории. естественно, если и посчитается какое-то расхождение, то только с первой записью и на выходе получится абы что. так можно удалить почти все картинки из папки.
никакие расхождения тут не нужны. если так уж хочется сначала выбрать все записи из базы данных в массив и потом в цике обходить директорию, то достаточно просто проверять на каждом проходе существует ли в этом массиве такое изображение с помощью in_array. я же написал что нужно сделать. выложите здесь дамп таблицы базы данных "doska", чтобы было видно как в ней хранятся пути к изображениям и вам могли помочь. и желательно полный путь к папке с изображениями на сервере тоже. вы же упёрлись и ищете "менее мощные решения" | |
|
|
|
|
|
|
|
для: psychomc
(02.04.2014 в 11:22)
| | Дамп таблицы с фото выложить не могу, т.к. там хранятся так же и контактные данные пользователей.
Функцией in_array() пробовал, не хватает памяти для обработки массива, т.к. файлов около 500 000 шт. | |
|
|
|
|
|
|
|
для: segazav
(02.04.2014 в 11:41)
| | ну так не надо выкладывать все поля, выложите только первичный ключи поля с фото. | |
|
|
|
|
|
|
|
для: psychomc
(02.04.2014 в 11:58)
| | А как создать дамп таблицы только некоторых полей? | |
|
|
|
|
|
|
|
для: segazav
(02.04.2014 в 12:07)
| | А что если все имена файлов занести во временную таблицу и сравнить с таблицей путей к ним? | |
|
|
|
|
|
|
|
для: segazav
(02.04.2014 в 12:40)
| | извините, но вы больны, честное слово. вам в голову приходят какие-то ужасные решения, не имеющие ничего общего с реальностью и вы отвергаете всё что вам предлагают
еще раз, пошагово напишу что нужно делать, раз вам всё-таки нужен алгоритм.
1) открываем директорию с файлами изображений и обходим каждый файл по отдельности
2) при обходе для каждого файла ищем запись в базе данных, запрос будет вида:
"SELECT COUNT(*) FROM doska WHERE foto_mini1 = '" . mysql_real_escape_string($image_name_from_directory) . "' OR foto_mini2='" . mysql_real_escape_string($image_name_from_directory) . "' ......
3) если количество возвращаемых записей = 0 - удаляем изображение, если нет - ничего не делаем
ВСЁ. ЭТО ВСЁ ЧТО НУЖНО СДЕЛАТЬ!
какие сравнения, какие временные таблицы? да даже если у вас не хватит ресурсов на первый запуск - запустите еще 1 раз, запустите 2 раза. НЕУЖЕЛИ ТАК СЛОЖНО ПОНЯТЬ, ЧТО С КАЖДЫМ РАЗОМ КАРТИНОК В ДИРЕКТОРИИ БУДЕТ СТАНОВИТЬСЯ ВСЁ МЕНЬШЕ ПОТОМУ ЧТО ОНИ БУДУТ УДАЛЯТЬСЯ И ЗНАЧИТ РЕСУРСОВ С КАЖДЫМ РАЗОМ НУЖНО БУДЕТ ВСЁ МЕНЬШЕ? | |
|
|
|
|
|
|
|
для: segazav
(02.04.2014 в 12:07)
| | в phpmyadmin жмете Export и выбираете нужные поля в таблице | |
|
|
|