На самом деле у меня есть два вопроса.
(1) Есть ли снижение мощности обработки или пропускной способности, используемой на удаленном сервере, если я получаю только заголовки, а не полный поиск страниц, используя php и curl?
(2) Поскольку я думаю, и я могу ошибаться, этот ответ на первые вопросы – ДА , я пытаюсь получить последнюю измененную дату или If-Modified-Since заголовок удаленного файла только для того, чтобы сравнить его с датой даты локально сохраненные данные, поэтому я могу, если он был изменен, сохранить его локально. Тем не менее, мой скрипт, похоже, не может получить эту часть информации, я получаю NULL
, когда я запускаю ее:
class last_change { public last_change; function set_last_change() { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, "http://url/file.xml"); curl_setopt($curl, CURLOPT_HEADER, true); curl_setopt($curl, CURLOPT_FILETIME, true); curl_setopt($curl, CURLOPT_NOBODY, true); // $header = curl_exec($curl); $this -> last_change = curl_getinfo($header); curl_close($curl); } function get_last_change() { return $this -> last_change['datetime']; // I have tested with Last-Modified & If-Modified-Since to no avail } }
В случае, если $header = curl_exec($curl)
имеет аналогов, отображаются данные заголовка, даже если я его не просил и выглядит следующим образом:
HTTP/1.1 200 OK Date: Fri, 04 Sep 2009 12:15:51 GMT Server: Apache/2.2.8 (Linux/SUSE) Last-Modified: Thu, 03 Sep 2009 12:46:54 GMT ETag: "198054-118c-472abc735ab80" Accept-Ranges: bytes Content-Length: 4492 Content-Type: text/xml
Исходя из этого, возвращается «Last-Modified».
Итак, что я делаю неправильно?
Вы передаете $ header в curl_getinfo()
. Он должен быть $curl
(ручка завитка). Вы можете получить только время filetime
, передав CURLINFO_FILETIME
в качестве второго параметра curl_getinfo()
. (Часто время filetime
недоступно, и в этом случае оно будет отображаться как -1).
Ваш класс, кажется, расточительный, хотя, отбрасывая много информации, которая может быть полезна. Вот еще один способ:
class URIInfo { public $info; public $header; private $url; public function __construct($url) { $this->url = $url; $this->setData(); } public function setData() { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $this->url); curl_setopt($curl, CURLOPT_FILETIME, true); curl_setopt($curl, CURLOPT_NOBODY, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, true); $this->header = curl_exec($curl); $this->info = curl_getinfo($curl); curl_close($curl); } public function getFiletime() { return $this->info['filetime']; } // Other functions can be added to retrieve other information. } $uri_info = new URIInfo('http://www.codinghorror.com/blog/'); $filetime = $uri_info->getFiletime(); if ($filetime != -1) { echo date('Ymd H:i:s', $filetime); } else { echo 'filetime not available'; }
Да, загрузка будет легче на сервере, поскольку она возвращает только HTTP-заголовок (в конце концов, отвечает на запрос HEAD
). Сколько легче будет сильно различаться.
Зачем использовать CURL для этого? Для этого есть PHP-функция:
$headers=get_headers("http://img.ruphp.com/header/530c9613d29bd_CountvonCount.jpg"); print_r($headers);
возвращает следующее:
Array ( [0] => HTTP/1.1 200 OK [1] => Date: Tue, 11 Mar 2014 22:44:38 GMT [2] => Server: Apache [3] => Last-Modified: Tue, 25 Feb 2014 14:08:40 GMT [4] => ETag: "54e35e8-8873-4f33ba00673f4" [5] => Accept-Ranges: bytes [6] => Content-Length: 34931 [7] => Connection: close [8] => Content-Type: image/jpeg )
После этого вам будет легко получить тип контента.
Вы также можете добавить формат = 1 в get_headers:
$headers=get_headers("http://img.ruphp.com/header/530c9613d29bd_CountvonCount.jpg",1); print_r($headers);
Это вернет следующее:
Array ( [0] => HTTP/1.1 200 OK [Date] => Tue, 11 Mar 2014 22:44:38 GMT [Server] => Apache [Last-Modified] => Tue, 25 Feb 2014 14:08:40 GMT [ETag] => "54e35e8-8873-4f33ba00673f4" [Accept-Ranges] => bytes [Content-Length] => 34931 [Connection] => close [Content-Type] => image/jpeg )
Подробнее здесь (PHP.NET)
(1) Да. Запрос HEAD (как вы выдаете в этом случае) намного легче на сервере, потому что он возвращает заголовки HTTP, в отличие от заголовков и контента, например, стандартного запроса GET.
(2) Вам необходимо установить для параметра CURLOPT_RETURNTRANSFER значение true
прежде чем вы вызове curl_exec()
чтобы вернуть содержимое, а не печатать:
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
Это также должно сделать ваш класс работать правильно.
Вы должны добавить
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
для возврата заголовка вместо его печати.
Верно ли только заголовки легче на сервере, зависит от скрипта, который работает, но обычно это будет.
Я думаю, вы также хотите «filetime» вместо «datetime».
Вы можете установить контекст потока по умолчанию:
stream_context_set_default( array( 'http' => array( 'method' => 'HEAD' ) ) );
Затем используйте:
$headers = get_headers($url,1);
get_headers кажется более эффективным, чем cURL, когда get_headers пропускают такие шаги, как триггерные процедуры проверки подлинности, такие как запросы входа в систему или файлы cookie.
Вот моя реализация с использованием CURLOPT_HEADER, а затем анализ выходной строки на карту:
function http_headers($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); $headers = curl_exec($ch); curl_close($ch); $data = []; $headers = explode(PHP_EOL, $headers); foreach ($headers as $row) { $parts = explode(':', $row); if (count($parts) === 2) { $data[trim($parts[0])] = trim($parts[1]); } } return $data; };
Использование образца:
$headers = http_headers('https://i.ytimg.com/vi_webp/g-dKXOlsf98/hqdefault.webp'); print_r($headers); Array ( ['Content-Type'] => 'image/webp' ['ETag'] => '1453807629' ['X-Content-Type-Options'] => 'nosniff' ['Server'] => 'sffe' ['Content-Length'] => 32958 ['X-XSS-Protection'] => '1; mode=block' ['Age'] => 11 ['Cache-Control'] => 'public, max-age=7200' )