Как проверить есть ли файл на сервере и если нету отдать другой файл?

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

В общем такая проблема, есть новостной сайт и на нём много записей, и чтобы уменьшить весь фтп, раз в год удаляют старые папки, но в админке эти ссылки остаются.
Вопрос! Как проверить миниатюру записи и если нет файла то отдать другой?
Делал так

$thumb = get_the_post_thumbnail( $post->ID, $post_card_thumb_size, array( 'itemprop' => 'image', 'onError' => 'this.src="https://site.ru/wp-content/themes/reboot/placeholder.jpg"' ) );

$thumb = get_the_post_thumbnail( $post->ID, $post_card_thumb_size, array( 'itemprop' => 'image', 'onError' => 'this.src="https://site.ru/wp-content/themes/reboot/placeholder.jpg"' ) );

но при lazy-load она не работает.
А так же делал так

$featured_img_url = get_the_post_thumbnail_url(get_the_ID(),'full'); if (!file_exists($featured_img_url) {       $thumb = '<img src="https://site.ru/wp-content/themes/reboot/placeholder.jpg">'; }

$featured_img_url = get_the_post_thumbnail_url(get_the_ID(),'full'); if (!file_exists($featured_img_url) { $thumb = '<img src="https://site.ru/wp-content/themes/reboot/placeholder.jpg">'; }

но сайт вообще рухнул

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

Как проверить есть ли файл на сервере и если нету отдать другой файл?

// $image[0] = WPP_CORE_URL . 'components/assets/img/placeholder.jpg'; замените на свой путь

if ( ! function_exists( 'wpp_image_placeholder' ) ) :  	/** 	 * Изображение заполнитель 	 */ 	function wpp_image_placeholder( $image = null, $return = 'array', $size = 'thumbinail' ) { 		if ( ! empty( $image ) ) { 			$uploads   = wp_upload_dir(); 			$file_path = str_replace( $uploads['baseurl'], $uploads['basedir'], $image[0] ); 		} else { 			$image = []; 		}  		if ( empty( $file_path ) || ! file_exists( $file_path ) ) { 			$placeholder_image = get_option( 'wpp_placeholder_image', 0 );  			if ( empty( $placeholder_image ) ) { 				$image[0] = WPP_CORE_URL . 'components/assets/img/placeholder.jpg'; 			} else { 				$image_opt = wp_get_attachment_image_src( $placeholder_image );  				if ( ! empty( $image_opt ) ) { 					$image[0] = $image_opt[0]; 				} 			} 		}  		$img = 'array' === $return ? $image : $image[0];  		return apply_filters( 'wpp_placeholder_img', $img, $return ); 	}   endif;  add_filter( 'wp_get_attachment_image_src', 'wpp_image_placeholder', 10 );

if ( ! function_exists( 'wpp_image_placeholder' ) ) : /** * Изображение заполнитель */ function wpp_image_placeholder( $image = null, $return = 'array', $size = 'thumbinail' ) { if ( ! empty( $image ) ) { $uploads = wp_upload_dir(); $file_path = str_replace( $uploads['baseurl'], $uploads['basedir'], $image[0] ); } else { $image = []; } if ( empty( $file_path ) || ! file_exists( $file_path ) ) { $placeholder_image = get_option( 'wpp_placeholder_image', 0 ); if ( empty( $placeholder_image ) ) { $image[0] = WPP_CORE_URL . 'components/assets/img/placeholder.jpg'; } else { $image_opt = wp_get_attachment_image_src( $placeholder_image ); if ( ! empty( $image_opt ) ) { $image[0] = $image_opt[0]; } } } $img = 'array' === $return ? $image : $image[0]; return apply_filters( 'wpp_placeholder_img', $img, $return ); } endif; add_filter( 'wp_get_attachment_image_src', 'wpp_image_placeholder', 10 );

  • класс!
  • Прошу прощения, а не подскажите как добавить туда свой класс?
  • redesupar, Сюда никак это меняет только путь к изображению, если оригинальное не найдено, с html разметкой оно никак не взаимодействует.

    написано как раз под подобную задачу что бы можно было использовать стандартные функции движка для картинок и не заморачиваться с HTML

    да и не надо оно, что бы выделить такую картинку в верстке можно обратится к ней через src

    img[src="ваш_путь_к_картинке"] {}

Нужно решить такую задачу?

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

Заказать помощь
Лучший ответ
1
Web-разработка Ответ

Проверять существование миниатюры через file_exists() нужно по пути на диске, а не по URL. В Вашем примере get_the_post_thumbnail_url() возвращает адрес вида https://site.ru/..., а file_exists() ждёт путь вроде /home/user/site/wp-content/uploads/.... Поэтому код и ломается.

Рабочая схема: получить ID миниатюры, взять путь файла через get_attached_file(), проверить его, а если файла нет — отдать placeholder.

function my_safe_post_thumb($post_id, $size = 'medium') {
    $thumb_id = get_post_thumbnail_id($post_id);
    $placeholder = get_stylesheet_directory_uri() . '/assets/img/placeholder.jpg';
 
    if (!$thumb_id) {
        return '<img src="' . esc_url($placeholder) . '" alt="">';
    }
 
    $file = get_attached_file($thumb_id);
 
    if (!$file || !file_exists($file)) {
        return '<img src="' . esc_url($placeholder) . '" alt="">';
    }
 
    return get_the_post_thumbnail($post_id, $size, [
        'loading' => 'lazy',
        'decoding' => 'async',
    ]);
}

function my_safe_post_thumb($post_id, $size = 'medium') { $thumb_id = get_post_thumbnail_id($post_id); $placeholder = get_stylesheet_directory_uri() . '/assets/img/placeholder.jpg'; if (!$thumb_id) { return '<img src="' . esc_url($placeholder) . '" alt="">'; } $file = get_attached_file($thumb_id); if (!$file || !file_exists($file)) { return '<img src="' . esc_url($placeholder) . '" alt="">'; } return get_the_post_thumbnail($post_id, $size, [ 'loading' => 'lazy', 'decoding' => 'async', ]); }

Вариант с onerror тоже имеет право на жизнь, но lazy-load плагины часто подменяют src на data-src, поэтому событие может работать не так, как ожидается. Серверная проверка надёжнее, но если записей очень много, не делайте file_exists() сотни раз на каждой странице без кэша.

Лучше один раз пройтись скриптом по старым записям, найти отсутствующие файлы и заменить миниатюры на заглушку в базе. Тогда фронт будет быстрее и проще.

Ещё момент: если на сайте включён CDN или плагин оптимизации изображений, файл может физически отсутствовать локально, но картинка продолжит открываться с внешнего хранилища. В таком случае серверный file_exists() даст ложный минус. Тогда либо проверяйте именно локальные uploads, либо делайте HTTP-проверку фоном и кэшируйте результат, но не выполняйте внешние запросы на каждой загрузке страницы.

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

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

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

комментарий

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

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