Достойные куски этого являются результатами, которые можно в значительной степени игнорировать. Это все еще немного читатель, но я пытаюсь быть тщательным в моем анализе и опросе. Если вы знакомы с stream_get_meta_data
, вы бы хорошо, чтобы перейти к «Вопросы» в конце.
Помимо документов, у меня возникают проблемы с поиском информации о PHP. stream_get_meta_data
. Общая функциональность не сильно отличается от PHP get_headers
, но я не могу на всю жизнь найти какие-либо сравнения между двумя, или плюсы / минусы первого.
До этого момента я всегда использовал PHP get_headers
проверить правильность URL. Недостаток с get_headers
это то, что это заведомо медленный. Понятно, что большая часть задержек напрямую связана с сервером, на котором размещен интересующий сайт, но может быть метод просто чрезмерно устойчив, или что-то еще замедляет его.
Есть много ссылок, которые рекомендуют использовать CURL
утверждая, что это быстрее, но я запустил параллельные, синхронизированные тесты и get_headers
всегда выходил на первое место, часто в 1,5 или 2 раза.
Я еще не видел каких-либо решений, использующих stream_get_meta_data
и только сегодня наткнулся на него впервые. Я исчерпал свои навыки Google, без особой удачи. Но в целях оптимизации моей схемы я провел несколько тестов.
Сравнения между get_headers
а также stream_get_meta_data
были запущены с использованием списка из 106 текущих (т. е. живых, действительных, status = 200) URL:
Code Block #1
// All URLs in format "http://www.domain.com"$urls = array('...', '...', '...'); // *106 URLs
// get_headers
$start = microtime(true);
foreach($urls as $url) {
try{
// Unfortunately, get_headers does not offer a context argument
stream_context_set_default(array('http' => array('method' => "HEAD")));
$headers[] = @get_headers($url, 1);
stream_context_set_default(array('http' => array('method' => "GET")));
}catch(Exception $e){
continue;
}
}
$end1 = microtime(true) - $start;
// stream_get_meta_data
$cont = stream_context_create(array('http' => array('method' => "HEAD")));
$start = microtime(true);
foreach($urls as $url) {
try{
$fp = fopen($url, 'rb', false, $cont);
if(!$fp) {
continue;
}
$streams[] = stream_get_meta_data($fp);
}catch(Exception $e){
continue;
}
}
$end2 = microtime(true) - $start;
И результаты, которые я получаю, stream_get_meta_data
выходит на первое место, 90% времени или больше. Иногда времена почти идентичны, но чаще всего stream_get_meta_data
имеет более короткое время выполнения
Run Times #1
"get_headers": 112.23 // seconds
"stream_get": 42.61 // seconds
С [stringified] выходами этих двух что-то вроде:
Excerpt of Comparison #1
url .. "http://www.wired.com/"
get_headers
| 0 ............................ "HTTP/1.1 200 OK"| Access-Control-Allow-Origin .. "*"| Cache-Control ................ "stale-while-revalidate=86400, stale-while-error=86400"| Content-Type ................. "text/html; charset=UTF-8"| Link ......................... "; rel=\"https://api.w.org/\""| Server ....................... "Apache"| Via
| | "1.1 varnish"| | "1.1 varnish"|
| Fastly-Debug-State ........... "HIT"| Fastly-Debug-Digest .......... "c245efbf14778c681ce317da114c1a762199e1326323d07b531d765e97fc8695"| Content-Length ............... "135495"| Accept-Ranges ................ "bytes"| Date ......................... "Tue, 23 Aug 2016 22:32:26 GMT"| Age .......................... "701"| Connection ................... "close"| X-Served-By .................. "cache-jfk8149-JFK, cache-den6024-DEN"| X-Cache ...................... "HIT, HIT"| X-Cache-Hits ................. "51, 1"| X-Timer ...................... "S1471991546.459931,VS0,VE0"| Vary ......................... "Accept-Encoding"
stream_get
| wrapper_data
| | "HTTP/1.1 200 OK"| | "Access-Control-Allow-Origin: *"| | "Cache-Control: stale-while-revalidate=86400, stale-while-error=86400"| | "Content-Type: text/html; charset=UTF-8"| | "Link: ; rel=\"https://api.w.org/\""| | "Server: Apache"| | "Via: 1.1 varnish"| | "Fastly-Debug-State: HIT"| | "Fastly-Debug-Digest: c245efbf14778c681ce317da114c1a762199e1326323d07b531d765e97fc8695"| | "Content-Length: 135495"| | "Accept-Ranges: bytes"| | "Date: Tue, 23 Aug 2016 22:32:26 GMT"| | "Via: 1.1 varnish"| | "Age: 701"| | "Connection: close"| | "X-Served-By: cache-jfk8149-JFK, cache-den6020-DEN"| | "X-Cache: HIT, HIT"| | "X-Cache-Hits: 51, 1"| | "X-Timer: S1471991546.614958,VS0,VE0"| | "Vary: Accept-Encoding"|
| wrapper_type ................. "http"| stream_type .................. "tcp_socket/ssl"| mode ......................... "rb"| unread_bytes ................. 0
| seekable ..................... false
| uri .......................... "http://www.wired.com/"| timed_out .................... false
| blocked ...................... true
| eof .......................... false
По большей части, все те же данные, за исключением того, что stream_get_meta_data
не предлагает никаких способов включить ключи для wrapper_data
, не разбирая его вручную.
Достаточно просто …
Code Block #2.1/2.2
$wd = $meta[$url]['wrapper_data'];
$wArr = wrapperToKeys($wd);
где…
function wrapperToKeys($wd) {
$wArr = array();
foreach($wd as $row) {
$pos = strpos($row, ': '); // *Assuming* that all separated by ": " (Might be colon, without the space?)
if($pos === false) {
$wArr[] = $row;
}else {
// $pos, $key and $value can probably be done with one good preg_match
$key = substr($row, 0, $pos);
$value = substr($row, ($pos + 2));
// If key doesn't exist, assign value
if(empty($wArr[$key])) {
$wArr[$key] = $value;
}
// If key already points to an array, add value to array
else if(is_array($wArr[$key])) {
$wArr[$key][] = $value;
}
// If key currently points to string, swap value into an array
else {
$wArr[$key] = array($wArr[$key], $value);
}
}
}
return $wArr;
}
И вывод идентичный в get_headers($url, 1)
:
Excerpt of Comparison #2
url .. "http://www.wired.com/"
headers
| 0 ............................ "HTTP/1.1 200 OK"| Access-Control-Allow-Origin .. "*"| Cache-Control ................ "stale-while-revalidate=86400, stale-while-error=86400"| Content-Type ................. "text/html; charset=UTF-8"| Link ......................... "; rel=\"https://api.w.org/\""| Server ....................... "Apache"| Via
| | "1.1 varnish"| | "1.1 varnish"|
| Fastly-Debug-State ........... "HIT"| Fastly-Debug-Digest .......... "c245efbf14778c681ce317da114c1a762199e1326323d07b531d765e97fc8695"| Content-Length ............... "135495"| Accept-Ranges ................ "bytes"| Date ......................... "Tue, 23 Aug 2016 22:35:29 GMT"| Age .......................... "883"| Connection ................... "close"| X-Served-By .................. "cache-jfk8149-JFK, cache-den6027-DEN"| X-Cache ...................... "HIT, HIT"| X-Cache-Hits ................. "51, 1"| X-Timer ...................... "S1471991729.021214,VS0,VE0"| Vary ......................... "Accept-Encoding"
w-arr
| 0 ............................ "HTTP/1.1 200 OK"| Access-Control-Allow-Origin .. "*"| Cache-Control ................ "stale-while-revalidate=86400, stale-while-error=86400"| Content-Type ................. "text/html; charset=UTF-8"| Link ......................... "; rel=\"https://api.w.org/\""| Server ....................... "Apache"| Via
| | "1.1 varnish"| | "1.1 varnish"|
| Fastly-Debug-State ........... "HIT"| Fastly-Debug-Digest .......... "c245efbf14778c681ce317da114c1a762199e1326323d07b531d765e97fc8695"| Content-Length ............... "135495"| Accept-Ranges ................ "bytes"| Date ......................... "Tue, 23 Aug 2016 22:35:29 GMT"| Age .......................... "884"| Connection ................... "close"| X-Served-By .................. "cache-jfk8149-JFK, cache-den6021-DEN"| X-Cache ...................... "HIT, HIT"| X-Cache-Hits ................. "51, 1"| X-Timer ...................... "S1471991729.173641,VS0,VE0"| Vary ......................... "Accept-Encoding"
Даже с разбором ключей, stream_get_meta_data
чемпион
Sample Run Times #2
"get_headers": 99.51 // seconds
"stream_get": 43.79 // seconds
Примечание. Эти тесты выполняются на дешевом общем сервере — отсюда и большие различия во времени тестирования. Тем не менее, разрыв между этими двумя методами очень согласован между тестами.
Для тех из вас, кто понимает c-код для PHP и чувствует, что может получить от него некоторое представление, определения функций можно найти по адресу:
а также
‘stream_get_meta_data’ (PHP Git)
Как так stream_get_meta_data
настолько недопредставлен (в поисках и доступных фрагментах кода) по сравнению с get_headers
?
То, как я это сформулировал, приводит к мнения, но мое намерение больше похоже на: «Есть ли что-то настолько известное и ужасное в stream_get_meta_data
что удерживает людей от его использования?
Как и в предыдущем, есть ли известные, отрасль согласована плюсы и минусы между двумя? Виды вещей, на которые намекает более полное понимание CS. возможно get_headers
является более безопасным / надежным и менее восприимчивым к ошибкам и несоответствиям с выходными данными сервера? Или, может быть get_headers
известно Работа в случаях, когда stream_get_meta_data
выдает и ошибка?
Из того, что я могу найти, stream_get_meta_data
есть пара заметки а также предупреждения (… для fopen), но ничего такого ужасного, что их нельзя обойти.
Пока это безопасно и непротиворечиво, я хотел бы включить это в свой проект, видя, как эта операция выполнена довольно часто, и сокращение времени выполнения в два раза имело бы существенное значение.
С тех пор я нашел несколько URL, которые успешно с get_headers
но бросить предупреждение для stream_get_meta_data
PHP Warning: fopen(http://www.alealimay.com/): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request
PHP Warning: fopen(http://www.thelovelist.net/): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request
PHP Warning: fopen(http://www.bleedingcool.com/): failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden
get_headers
возвращает только 403 Forbidden
статус, даже если вы можете вставить URL-адреса в браузер и увидеть, что они рабочие сайты.
Не уверены в этом: как разбивка stream_get_meta_data
и неполный заголовок из get_headers
(должен включать все перенаправления и окончательный status_code = 200
для функционирующих сайтов).
Большое спасибо, если вы сделали это так далеко.
Также, пожалуйста, прокомментируйте, если вы проголосовали против, так что я мог бы улучшить этот вопрос, и мы все можем учиться для будущих дел.
Задача ещё не решена.
Других решений пока нет …