@Korneliy

Как сделать, чтобы неподходящие под условие не забивали лимит?

Есть такой код:
$database->setQuery("
    SELECT блаблабла
    LEFT блаблабла
    WHERE блаблабла
    ORDER блаблабла
limit 0,2");

блаблабла

while($row = mysql_fetch_assoc($request)) {	
	if (file_exists('/www/ПУТЬ/'.$row['id'].'_100.jpg')) echo 'BODY';
}


То есть, при наличии картинки '.$row['id'].'_100.jpg должны быть две итерации (limit 0,2) с BODY.

Так оно и происходит, если картинки есть у первых двух итераций.

Но проблема в том, что если первая итерация не находит соответствующей картинки, а, например, вторая находит, то показывается только одно BODY. Если наоборот - то же самое. А если у первых двух итераций нет вообще картинок - то вообще ничего не показывается.

Как сделать так, чтобы итерации, в которых нет картинок, просто пропускались? И всегда вывод был с двумя BODY (у которых есть картинки).

Заранее благодарен ответам профи!
  • Вопрос задан
  • 110 просмотров
Пригласить эксперта
Ответы на вопрос 2
@alexalexes
Вариант А.
Вы не можете гарантировать, что любой файл изображений, сведения о которых храните в базе, будет доступен физически в любой момент.
Придется неопределенное число раз постучаться в базу и протестировать каждую запись о файле, существует ли он физически. При тесте формируем список мертвых и живых файлов. После того, как протестировали нужное кол-во живых файлов, можно делать итоговый запрос с оглядкой на список мертвых файлов.
$need_count = 10;  // сколько требуется файлов для выборки
$alive_count  = 0;  // сколько живых файлов
$is_need_repeat = true; // требуется повторить попытку получить живые файлы
$death_list = []; // сюда накапливаем список id мертвых файлов
$alive_list = []; // сюда накапливаем список id живых файлов
while($is_need_repeat) // Если можно делать итерационную попытку и пока не набрали нужное количество живых файлов
{
// Этот запрос, чтобы прощупать целостность файлов, достаточно получить только те атрибуты, которые позволяют проверить его путь и запомнить id.
$database->setQuery("
    SELECT id
    from блаблабла
    WHERE блаблабла 
               ".(count($depth_list) > 0 ? : ' and id not in ('.join(',',$death_list).') ' : '')." -- отсеиваем мертвые файлы из запроса, они нам не нужны
               ".(count($alive_list) > 0 ? : ' and id not in ('.join(',',$alive_list).') ' : '')." -- отсеиваем живые файлы из запроса, мы их уже проверяли
    ORDER блаблабла
limit 0,".($need_count - $alive_count)); // делаем лимит по оптимистичному сценарию, как будто можем получить список файлов, и все они будут живые, но только то кол-во, которое недостает
while($row = mysql_fetch_assoc($request))
{
  if(file_exists('/www/ПУТЬ/'.$row['id'].'_100.jpg'))
  {
    $alive_list[] = $row['id']; // файл живой, заносим его id в список
  }
  else
  {
    $death_list[] = $row['id']; // файл мертвый, заносим его id в список
  }
  $curr_alive_count = count($alive_list);
  $is_need_repeat = $curr_alive_count > 0 && $curr_alive_count > $alive_count && $curr_alive_count < $need_count; // необходимо продолжить попытки, если на текущей итерации получили хоть один живой файл, живых файлов на этой итерации оказалось больше, чем на предыдущей, и их кол-во не достаточно до необходимого
  $alive_count = $curr_alive_count; // вписываем кол-во живых файлов на текущей итерации для проверки в будущем цикле (чтобы сравнить результаты двух циклов)
}
}
// теперь можно сделать нормальный запрос, исключив мертвые файлы:
$database->setQuery("
    SELECT *
    from блаблабла
    WHERE блаблабла 
               ".(count($depth_list) > 0 ? : ' and id not in ('.join(',',$death_list).') ' : '')." -- отсеиваем мертвые файлы из запроса
    ORDER блаблабла
limit 0,".$need_count);

Вариант Б.
Вы можете гарантировать, что контролируете целостность файлов.
Тогда в таблице изображений делаете колонку is_del. Когда удаляете файл, вы должны пометить запись о файле в базе как удаленную по этому атрибуту.
Если вы все таки частично контролируете целостность, то в определенный период времени (например, запускать скрипт по cron раз в час, сутки) вам нужно пройтись по всему списку файлов в базе и проверить целостность каждого файла, и внести актуальную метку is_del.
Тогда получать живые файлы будет чуть-чуть проще:
$database->setQuery("
    SELECT *
    from блаблабла
    WHERE блаблабла 
           and is_del is null -- или нулю, в зависимости, что будет по умолчанию
    ORDER блаблабла
limit 0,".$need_count);
Ответ написан
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
$string = '';
while($row = mysql_fetch_assoc($request)) {
  if (file_exists('/www/ПУТЬ/'.$row['id'].'_100.jpg')) 
  {
     $string .= 'BODY';
  }
  else 
  {
     $string = '';
     break;
  }
}
echo $string;


А вообще если у вас не контролируется наличие изображений, значит где-то что-то пошло не так...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы