@midarovrk

Как добавить проверку кода 404 при скачивании файла через php?

Как добавить к php коду для скачивания файла проверку существует файл или нет?

Например при таком ответе сервера:

HTTP/1.1 404 Not Found
Server: nginx/1.10.2
Date: Fri, 25 May 2018 16:16:21 GMT
Content-Type: text/html
Content-Length: 3652
Connection: keep-alive
ETag: "58173b0b-e44"

Файл всё равно создаётся на сервере в виде изображения с размером 3652 кб
Но это в итоге не изображение, а битый файл получается.
Как сделать проверку, и если 404 то пропускать такой файл и не сохранять на сервере?

/**
* Получить и сохранить файл
*
* @param string $url - ссылка на файл
* @param string $path - путь для сохранения файла
* @param string $fileName - не обязательный параметр, имя файла для сохранения
*
* @return bool - результат
*/
function getAndSaveFile($url, $path, $fileName = false) {
    // открываем содержимое файла
    $file = @file_get_contents($url);
    // если не удалось получить файл вернем false
    if(!$file) return false;
    // получаем имя файла, если не задано, то берем из урла
    if(!$fileName) $fileName = basename($url);
    // сохраняем файл
    $resultSave = @file_put_contents($path.$fileName, $file);
    // проверяем результат сохранения
    if ($resultSave || $resultSave > 0) return true;
    return false;
}

var_dump(getAndSaveFile("http://vk-book.ru/img/codirovka.png", './files/'));
  • Вопрос задан
  • 362 просмотра
Решения вопроса 1
sergiks
@sergiks Куратор тега PHP
♬♬
При выполнении file_get_contents() заполняется специальная переменная $http_response_header – это массив, заполненный строками заголовков ответа сервера. Самая первая – что-то типа "HTTP/1.1 200 OK" в случае найденного файла или "HTTP/1.1 404 Not Found"

Вытащить оттуда код статуса можно регулярным выражением:
if( preg_match( "#HTTP/[0-9\.]+\s+([0-9]+)#",$http_response_header[0], $matches ) )
  $reponse_code = intval($matches[1]);
else $response_code = 0; // не получилось узнать код ответа че-т


А вообще для веб-запросов удобнее пользоваться cURL
примерно так
function getAndSaveFile($url, $path, $fileName = false) {
    // открываем содержимое файла
    $file = @file_get_contents($url);
    // если не удалось получить файл вернем false
    if(!$file) return false;

    // получаем имя файла, если не задано, то берем из урла
    if(!$fileName) $fileName = basename($url);
    
    // файл для записи результата
    $fp = fopen($fileName, 'w');

    // подготавливаем cURL
    $ch = curl_init();
    curl_setopt_array($ch, array(
	    CURLOPT_URL => $url,
	    CURLOPT_FILE => $fp,
	    CURLOPT_FOLLOWLOCATION => true,
	    CURLOPT_TIMEOUT => 100,
    ));

	// выполняем запрос
	curl_exec($ch);
	
	// проверяем статус
	if (curl_errno($ch)) { // какая-то ошибка, таймаут?
		// закрываем cURL и файл
		curl_close($ch);
		fclose($fp);
		return false;
	} else {
		$status_code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
		if( $status_code !== "200") {
			// закрываем cURL и файл
			curl_close($ch);
			fclose($fp);
			unlink($fileName);
			return false;
		}
		
		return true;
	}
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Yan-s
Лучше всего использовать какую нибудь библиотеку представляющую удобную абстракцию для HTTP.

Например Guzzle:
docs.guzzlephp.org/en/stable

После запроса у вы получите объект ответа у него есть метод getStatusCode() который возвращает полученный код ответа, например 404. Всё сводится к трем строкам кода.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы