Достойные куски – это результаты, которые в значительной степени можно игнорировать. Это все еще немного читатель, но я стараюсь быть основательным в своем анализе и опросе. Если вы знакомы с stream_get_meta_data
, вам было бы stream_get_meta_data
перейти к «Вопросам» в конце .
Кроме того, что в DOC, у меня возникли проблемы с поиском stream_get_meta_data
в stream_get_meta_data
PHP. Общая функциональность не сильно отличается от функциональности PHP get_headers
, но я не могу на всю жизнь найти какие-либо сравнения между ними, или плюсы / минусы 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 текущих (т.е. живых, действительных, статусных = 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
С [строгими] выводами этих двух будет что-то вроде:
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 и чувствую, что они могут получить некоторое представление о нем, определения функций можно найти по адресу:
'get_headers' (PHP Git)
а также
'stream_get_meta_data' (PHP Git)
Почему stream_get_meta_data
настолько недопредставлена (в поисках и доступных фрагментах кода) по сравнению с get_headers
?
То, как я это сформулировал, приводит к мнению , но мои намерения более stream_get_meta_data
на следующие: «Есть ли что-то настолько известное и ужасное в stream_get_meta_data
которое препятствует людям использовать его?»
Как и в предыдущем, есть ли хорошо известные отраслевые плюсы и минусы между этими двумя? Виды вещей, на которые ссылается более полное понимание CS. Возможно, get_headers
является более безопасным / надежным и менее восприимчивым к ne'erdowells и несогласованностью с выводами сервера? Или, может быть, get_headers
как известно, работает в тех экземплярах, где stream_get_meta_data
и ошибки?
Из того, что я могу найти, у stream_get_meta_data
есть пара заметок и предупреждений (… для fopen) , но ничего ужасного, что их нельзя обойти.
До тех пор, пока это безопасно и непротиворечиво, я хотел бы включить его в свой проект, поскольку эта операция выполняется часто , и сокращение времени выполнения пополам будет иметь существенное значение.
С тех пор я нашел несколько URL-адресов, которые успешно работают с get_headers
но 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
(должны включать в себя все переадресации и final status_code = 200
для действующих сайтов).
Большое спасибо, если вы сделали это так далеко.
Кроме того, прокомментируйте, если вы проголосуете, так что я могу усовершенствовать этот вопрос, и мы все можем узнать о будущих делах.