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

Ссылка скопирована
17 января 2026 1 ответ

Есть такой код:

$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'; }

$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 (у которых есть картинки).

Заранее благодарен ответам профи!

Дополнительно:

Ответы:

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

$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);

$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);

$database->setQuery(" SELECT * from блаблабла WHERE блаблабла and is_del is null -- или нулю, в зависимости, что будет по умолчанию ORDER блаблабла limit 0,".$need_count);

  • Благодарю за такой подробный ответ!

    Но в представленном мною коде никаких сведений о файлах изображений в базе данных не хранится. В работающем коде тоже. Проверка на существование изображения осуществляется уже в цикле с помощью file_exists. В базу данных вносить сведения о картинках не будем.

    $row['id'] - это идентификатор документа.

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

  • Если вам всегда нужно выводить два неких маркера (предположу чтобы хотя бы была выборка), то зачем зондировать файлы?
    $is_have_rows = false; while($row = mysql_fetch_assoc($request)) {	   //if (file_exists('/www/ПУТЬ/'.$row['id'].'_100.jpg')) echo 'BODY';   $is_have_rows = true; } if($is_have_rows)   echo 'BODYBODY';

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

  • alexalexes, непонятно что Вы написали. Выводить BODY надо лишь тогда, когда картинки в указанном месте присутствуют.
  • Ну, блин, ответ лежит в той же плоскости.
    $have_image = false; while($row = mysql_fetch_assoc($request)) {	   if (file_exists('/www/ПУТЬ/'.$row['id'].'_100.jpg'))     $have_image = true; } if($have_image)   echo 'BODYBODY';

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

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

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

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

  • Нет, наличие break при условии, что первая итерация без картинки, прерывает всё и вообще пусто.

    Вы меня навели на мысль сделать так:

    if (file_exists('/www/ПУТЬ/'.$row['id'].'_100.jpg') == false)      continue; else      echo 'BODY';

    if (file_exists('/www/ПУТЬ/'.$row['id'].'_100.jpg') == false) continue; else echo 'BODY';

    Но всё равно ничего получается...

  • Korneliy,

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

    Короче я понял что основная ваша проблема в неумении построить нормально задачу. По вашему условию мое решение подходит, если есть картинки(2) то выводится 2 раза боди, в противном случае просто ничего не выводится.

    наличие break при условии, что первая итерация без картинки, прерывает всё и вообще пусто.

    Так у вас описано - если картинок нет (а логично что первой уже нет, значит будет только одна, что условиям не удовлетворяет), зачем проверять вторую? Просто выходим и выводим пустую строку.

  • ThunderCat, если я применяю Ваш код, то совсем ничего не выводится, break останавливает вывод и вообще пусто. А нужно, чтобы итерации, в которых нет картинок, просто пропускались и в результате выводили всегда две итерации с картинками.
  • Korneliy, Для информации: В вашем коде выбирается 2(!) элемента всего, цикл состоит из 2 проходов. Естественно что если в этих двух элементах нет картинок ничего не выведется.
  • ThunderCat, разве php такой бедный язык, что не может пропустить элементы без картинок и вывести только те, что с картинками?
  • Korneliy,

    разве php такой бедный язык, что не может пропустить элементы без картинок и вывести только те, что с картинками?

    Бедность или богатость языка тут вообще не при чем. Ваш код ПРЕДПОЛАГАЕТ ВЫБОР ИЗ 2 ЭЛЕМЕНТОВ (limit 0,2), так что у вас в коде по сути проверяется 2 элемента ВСЕГДА. Если ничего не выводится, значит хотя бы один из них не имеет картинок.

  • ThunderCat, в моём идеальном мире программа работала бы так (для примера)

    1. Смотрит первую итерацию. Ищет, есть ли картинка с тем же ID в имени. Не находит. Ничего не выводит, идёт дальше.

    2. Смотрит вторую итерацию, сопоставляет. Находит картинку, выводит.

    3. Смотрит третью. Картинки нет, ничего не выводит.

    4. В четвертой картинка есть - выводит, говорит "Ага! Лимит вывода исчерпан!" и останавливается.

    Итак, два вывода сделано. Почему глупый PHP на такое не способен - для меня загадка. :(

    =============

    Вот думаю, в limit может больше записать (например, 10), а ограничение на вывод двух при условии, что они с картинками, сделать в цикле.

  • Korneliy,

    3. Смотрит третью. Картинки нет, ничего не выводит.

    Нету третьей, в вашей выборке 2(!!!) элемента или меньше. Всегда. И это к пхп напрямую не относится, вы сами задали такие условия выборки из бд.

    Почему глупый PHP на такое не способен - для меня загадка.

    Подозреваю что глупый здесь кто-то другой, ибо нечего на зеркало пхп пенять, если не знаете как что работает ))

  • Korneliy, Кроме того,

    2. Смотрит вторую итерацию, сопоставляет. Находит картинку, выводит.

    и если дальше ни разу картинок не будет, то у вас выведется 1 раз "боди", что вроде как не соответствует условию.

  • ThunderCat, да, до меня уже дошло, что из базы надо лимит делать больше, а вот ограничивать уже в цикле.
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Павел Админов Ответ

Для того чтобы предотвратить злоупотребление и избежать неподходящих ответов, можно использовать несколько методов. Вот несколько рекомендаций:

1. **Подробное описание задачи**: В своем вопросе необходимо дать максимально подробное описание проблемы или задачи, с которой вы столкнулись. Чем точнее и яснее будет сформулирован вопрос, тем больше вероятность получить качественный и подходящий ответ.

2. **Ограничение области применения**: Укажите в своем вопросе конкретные ограничения или условия, которые должны быть выполнены в ответе. Например, если вам нужно решение на PHP, укажите это в вопросе.

3. **Использование тегов**: При формулировке вопроса используйте соответствующие теги, чтобы указать язык программирования или технологию, с которой связан ваш вопрос. Это поможет привлечь внимание специалистов по данной теме.

4. **Активное участие**: Если у вас возникают дополнительные вопросы или требуется уточнение, активно участвуйте в обсуждении в комментариях под ответами. Это поможет уточнить детали и получить более качественный ответ.

5. **Оценка ответов**: После получения ответов, не забудьте оценить их, выбрав лучший или наиболее полезный ответ. Это поможет другим пользователям выбрать правильное решение и повысит качество ответов на сайте.

Соблюдение этих рекомендаций поможет вам получить качественные и подходящие ответы на ваш вопрос, избежать неподходящих ответов и сделать общение на сайте более продуктивным.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно