Как стать автором
Обновить

Комментарии 79

А зачем тут preg_match?
можно и strpos() — суть статьи не в этом, согласитесь ;)
Просто раз уже вы сравнивали скорость, то, возможно, со strpos() обработка была бы быстрее :)
Но это так, мелочи. =)
Так уж сложилось, что я стараюсь избегать preg'ов, ereg'ов в поиске текста :)
да, соглашусь, что быстрее будет с strpos() и тогда еще немного больше выигрыш в скорости — отрудактирую соответственно статью ;)
вообще регэкспы очень быстрые. когда идет речь о том, чтобы делать http запрос — избавляться от регэкспа — оптимизация сотых долей процента.
В вашей точке зрения есть проблема — вы говорите о замене регэкспа strposом как об оптимизации. Ситуация же иная — замена strposа регэкспом тут — извращение и самого начало написать
preg_match('/const/', $a)
это не очень хорошо.

Ведь даже в документации большими буквами написано:
Do not use preg_match() if you only want to check if one string is contained in another string. Use strpos() or strstr() instead as they will be faster.
да неважно что там написано. регэкспы быстрые, и понятные.
Чем preg_match('/const/', $a) понятнее strpos($a, 'const') !== false?

(я минусами не бросаюсь ._.)
тем, что регэкспы не привязаны к пхп, понятны почти любому программисту? я вот, например, давно не писал на пхп и не помню особенностей работы strpos. мне более логичным кажется искомая подстрока первым аргументом — а с регэкспом разночтений не будет.
В последнем блоке кода ошибка.
$Headers = @get_headers($url);
if(preg_match("|200|", $AgetHeaders[0]))


У вас все время не будет существовать файла, исправте пожалуйста :)
поправил опечатку, благодарю ;)
лучше использовать реализацию через curl или fopen. Так как можно указать больше отправляемых параметров. Допустим некоторые сайты не отдают контент если не получен заголовок «User-Agent».
у вас браузер который не отсылает свой user-agent?
задача именно в том, чтоб выявить, доступно ли то, что мы вставляем в свои страницы.
Вроде бы можно использовать функция из stream_context() для установки хидеров.
*функции
две сотые секунды вам погоду сделают? учитывая еще что это больше от загруженности сети зависит…
при большом количестве запросов будет расти и совокупное время
и если преследуем одну цель, почему же не выбрать метод быстрее. ;)
Если нам надо брать файл, то fopen дает выигрыш, т.к. повторно не надо открывать(file_get_contents), если просто проверяем ТО используем getimagesize.
Тесты linux php 5.2.6
microtime file exists = true
file_exists 1.91
fopen 0.27
get_headers 0.31
getimagesize 0.22
microtime file exists = false
file_exists 2.2
fopen 0.21
get_headers 0.22
getimagesize 0.16
p.s.бралось время отдачи без парсинга
Оптимизация начинается с поиска узких мест.
А оптимизация ради оптимизации это так, рукоблудство.
спасибо. когда-нибудь пригодится.
Вы бы уже сишный модуль с ассемблерными ставками написали, глядишь так еще быстрее и надежнее будет :)
Кстати, через системные функции мне кажется быстрее, все равно пхп — обертка :)
а если удаленный сервер не доступен?
В следующий раз напишите статью на тему «Стопицот способов вывести значение переменой». А серьезно — может быть хватит уже чепуху постить? Кому это нужно?
вам не надо — не читайте. хабр сделан не только для вас
когда я тестил, у меня вышло, что curl значительно быстрее get_headers
Не хватает //} :)
к сожалению, ваш способ ужасен по самой сути.

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

кроме того, для проверки файла без его открытия есть команда stat. которая будет работать ощутимо быстрее любого из ваших способов. учите матчасть!
Мгм, а команда stat позволяет проверить наличие файла на удаленном сервере без открытия сокетов? :)
да, согласен, что ошибся. но ответить самому себе я не смог, так как хабр мне предложил подождать пять минут, прежде я смогу отправить еще один комментарий.

тем не менее, проверять файлы таким образом — все равно ужасно. потому что на каждую генерацию страницы с ссылками на внешние ресурсы будет затрачено очень большое количество синхронных соединений. и времени тоже. в качестве примера можно привести пример такого рода: проверяется наличие файла на сервере, у которого очередь на i/o очень велика. тогда пока вы не исчерпаете таймаут, ваш скрипт не отработает. а в силу того, что таймауты по умолчанию зачастую стоят одинаковые, пользователь тоже не увидит страницу
проверять файлы при каждом генерации страницы — это также глупо, как и оптимизировать сам процесс.
fopen или get_headers — для данной операции не имеет значения :)
is_file неужели медленнее?
НЛО прилетело и опубликовало эту надпись здесь
Предложите свою жесть — лучше. Без критики… :)
НЛО прилетело и опубликовало эту надпись здесь
А вы предложите не в PHP.
Какие есть возможности для проверки наличия файла на другом сервере?
можно на почту хозяину сервера написать, спросить мол, так и так, имеется ли такой файл.
Бред какой-то. Еще быстрее, кстати shutdown()'ить сокет после первой же строки ответа (с кодом) от сервера, зачем нам все заголовки?

Вообще первым абзацем стоило бы понятно написать какую задачу имеено вы хотите решить указанным кодом.

p.s. Вы что, хотите делать 2 запроса? убедиться первым, что файл существует, а вторым скачать? А смысл?

Еще. Если вы при запросе пользователя сами делаете HTTP-запрос, с ростом аудитории ваше приложение будет тормозить. я конечно не знаю, что там у вас, но научитесь хранить контент на своем сервере.
> Еще быстрее, кстати shutdown()'ить сокет после первой же строки ответа (с кодом) от сервера

бестолку. в сокетный буфер всё равно успеет налиться больше. как уже правильно сказали, в таких случаях самое правильное — использовать метод HEAD.
сразу возникают вопросы — а что с ошибками будете делать? а с таймаутами? а с перенаправлениями?

ну и, конечно, вы не предлагаете использовать этот код при обслуживании клиентских запросов. максимум — регулярный вызов по крону, я правильно понял? надеюсь, что да.
автор, откройте для себя HEAD
опередили :)
А вот интересно, при помощи этой функции, можно вытащить из удаленной мп3 информацию о битрейте, теги какие-нибудь и так далее? *ушел в гугл*
Мне кажется эта функция сильно полезней fopen и других, в тех случаях, когда сам файл большой, а не как иконка, весом в килобайт.
никак эта функция вам не поможет — автор написал бред.
битрейт содержится в первых нескольких кб файла (насколько я помню mp3) — так что вам нужно лишь скачать эту часть файла (любым из доступных способов: сокеты, курл, файловые функции, ...) и распарсить.
Да, действительно. Но эти теги содержаться либо в первых нескольких байтах (для первой версии) и в последних (для второй).
Спасибо за ответ:)
ну значит или качать первые или юзать Range ;-)
или в самом конце файла… зависит от версии тегов
уже поправили выше :-)
так или иначе — скачать начало или конец файла (если сервер поддерживает докачку) не проблема.
НЛО прилетело и опубликовало эту надпись здесь
> if(strpos('200', $Headers[0])) {

HTTP/1.1 404 I have 200 other files but not this one


упс :)

текст после кода не регламентирован стандартом и может содержать всё что угодно.
наоборот нужно

strpos($Headers[0], '200')


strpos

да и проверка на существование 0 индекса не помешала бы
Миллисекунды за счет выбора функции получил, а за счет двойного запроса к стороннему серверу ( 1. проверка наличия файла, 2. вывод его на странице ) — не меньше потерял.
HTTP/1.1 404 I have 200 other files but not this one
Ага, а еще в конце — «Ok?» :)
Тьфу, не туда написал, этот пост ответ на пост rojer.
да сколько угодно :)
даже вот такой ответ будет вполне соответствовать стандарту:

HTTP/1.1 404 HTTP/1.1 200 OK :)
Я думаю, что также работают хостинг компании, у которых можно проверить место под домен занято или нет.
Что за место под домен? ))
он думает, что так проверяется зарегистрированность домена :-)))))
да да
жжошь :-))))))))
я всегда думал, что так, а как? Мне главное на bash.org.ru не попасть )
зарегистрированность домена никак не связано с тем, будет он откликаться или нет.
я понимаю! Но можно же «проверить» занят ли он или нет?
whois запрос делайте, и смотрите что в ответе вам выдаётся
жжошь :-))))))))
Коллеги, что эта статья делает на главной?
А почему никто не написал бредовость самой идеи проверять наличие ФАЙЛА на УДАЛЕННОЙ системе через протокол, который не знает, что такое файлы в принципе?

Как раз собирался написать коммент в этом ключе, но вы меня опередили.

Такое впечатление, что автор вообще слабо себе представляет, что такое HTTP.
В HTTP вообще нет файлов, есть только ресурсы.
Любая динамическая страница, которую генерирует тот же PHP-шный скрипт — это никакой не файл, а ресурс.
Если цель была проверить наличие ресурса на удаленном сервере через HTTP, данный способ хоть и кривой и дырявый (как уже заметили выше), но более- менее рабочий.
Если же стоит цель проверить именно наличие файла на удаленном сервере, то нужно юзать совершенно другие протоколы, предназначенные для работы с файлами, например FTP.
интересно, а если при отсутствии файла сервер сообщает не 404, а делает редирект на главную страницу и ответ 200?
данный код сочтет, что файл существует
лучше сделать проверку на предмет «не 200», чтобы ловить внутренние ошибки (5xx) и пр.
к тому же, если сервер делает редирект (3xx), то это неправильный сервер (скрипт)
Такое в браузере делать надо, зачем сервер зря напрягать.
<img src="путь к картинке" onerror="alert('Тут я как бы сообщаю, что картинка по какой-либо причине не хочет грузиться, хотя можно, например, подсунуть дефолтную картинку.')">
круто, про onerror незнал
Вы в strpos перепутали needle и haystack.
Надо не strpos('200', $Headers[0]), а strpos($Headers[0], '200')
function remote_file_exists($url){
return (bool)preg_match('~HTTP/1\.\d\s+200\s+OK~', @current(get_headers($url)));
}

работает как часы
А почему нельзя было воспользоваться функцией file_exists(), она медленнее?? Судя по коментам ей больше 9 лет
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории