ПХП: красавица и чудовище
Одна из превосходнейших вещей в ПХП — обработчики протоколов. Они позволяют работать с разнообразными источниками данных как с файлами. Встроенные протоколы умеют понимать ftp, http, data URL, ssh2, rar, zlib и ещё несколько менее известных штук. Т. е. традиционный путь до файла в ПХП на самом деле является УРЛом, по виду которого интерпретатор решает какой обработчик за него ответственен. Если протокол (в терминах УРЛ) не указан, считается, что идёт обращение к локальному файлу. Язык так же позволяет создавать свои обработчики.
ПХП единственный из известных мне языков, где я могу с лёгкостью сделать такие вещи:
copy('ftp://user:pass@example.org/pub/somefile.txt', '/tmp/somefile.txt');
$var = file_get_contents('https://example.org/index.html');
# и при этом
copy('/tmp/somefile', '/tmp/anotherfile.txt');
$var = file_get_contents('/etc/passwd');Немного более сложный синтаксис позволяет сделать и более сложные вещи:
$post = http_build_query([
'login' => $login,
'pass' => $password,
]);
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded\r\n'.
'Content-length: ' . strlen($post),
'content' => $post,
'proxy'=>"tcp://192.168.1.1:3128"
]
];
$result = file_get_contents('http://example.org/action.php', false, stream_context_create($options));От полного изящества далеко,
Что сделано из рук вон плохо — это получение заголовков ответа для протоколов HTTP и HTTPS: ответ просто помещается в локальную переменную http_response_header, это печальное и достойное сожаления решение.
Более неявное поведение трудно и выдумать. Оно настолько неявное, что многие о нём даже не подозревают. Ещё отвратительно, что эта переменная содержит заголовки не в виде ключ/значение, а просто набор строк:
file_get_contents('//bolknote.ru');
var_dump($http_response_header);вернёт:
array(14) {
[0]=>
string(15) "HTTP/1.1 200 OK"
[1]=>
string(13) "Server: nginx"
[2]=>
string(35) "Date: Wed, 11 Jul 2012 19:50:10 GMT"
… и так далееКак такой непродуманный функционал может являться продолжением такой прекрасной штуки мне непонятно.
Комментарии 25
А с методами POST, PUT и другими как?
Мда уж, великий и могучий похапе )
На руби:
Андрей, тогда на php еще красивее:
А как в ruby data: или ssh: обработать?
Конечно язык вроде бы и не виноват, но то, что открытие файла неявно (хотя и не настолько, насколько http_response_header) является и скачиванием файла по сети, может увеличить (и увеличивает) диаметр дыры с именем файла из параметра.
Комментарий для Евгения Степанищева:
Хм, а я через curl это делал потому что традиционно и работает везде примерно одинаково.
Не ерунда, а просто дыра; из сети — действительно дырища: при возможности локального чтение (в данном случае — include) чтобы выполнить свой код, его
А php тут ровно при том, что в нём (насколько я помню) открыть файл откуда угодно гораздо проще, чем открыть именно локальный файл; причём про то, что file_get_contents умеет ходить по сети, из его имени не следует. Программист, не знакомый с такой особенностью, может и не заподозрить что такая есть. То есть url_get_content было бы лучше.
rar_get_contents
ftp_get_contents
gzip_get_contents
https_get_contents
не, http:// rar:// ftp:// gzip:// https:// — входят в url как протокол
bolk, я считаю, что наличие такой «красоты» в стдлибе — это маловолнующая штука. Ну т.е. я могу порадоваться ее наличию раз в пять лет при написании
Что касается «лучше сделано». Ну в
Комментарий для masterspammer.livejournal.com:
Это в документации к этой функции сказано. Если он ни разу не читал документации к этой функции, то пусть идёт мусор развозить.
Тоже мне задача. Если сайт позволяет хотьчто-то закачивать, то можно закачать файл разрешённого типа, с ПХП-кодом внутри. Если нет — можно попытаться подключить что-то локальное с дырой, если этого нельзя сделать, можно попробовать положить что-то в сессию (на некоторых сайтах есть визарды, которые хранят промежуточные данные в сессии) и цепануть сессию из /tmp. Короче, не учите хакера сайты ломать.
Комментарий для Андрей:
Я же не поддержку кучи протоколов, а про простоту работы с ними. И я не понимаю почему это только для одноразовых скриптов. Неужели вы так редко пишите код, который в сеть лезет?
Сказано, но можно и забыть, если не доводилось использовать. И про уровень программистов на PHP —
Ага, я тоже знаю, как
Комментарий для masterspammer.livejournal.com:
Язык знать надо, на мой взгляд.
Можно подумать, что это только в ПХП так. Что из «файлов» в каталоге /dev/ на самом деле файлы? Линукс считает, что «всё — файлы».
И такое поведение файловых функций можно отключить, есть опция. Но такая универсальность мне всё равно симпатична.
Евгений, у вас опечатка: «…функционал может являЕться…».
Заодно, зная ваше щепетильное отношение к русскому языку, хочу спросить: чем обосновано использование жаргонизма «функционал»?
Извините за офтоп. Ежели допустим язык с нуля изучить
Если у вас простенький
Опа. Спасиб, но вы меня озадачили. Язык первый, да, если Фортран немного не считать. Еще однажды изучил одну книжку про С++ и было интересно. Но не хочу чтоб программирование было моей профессией (да и поздно уже :) Однако фиг же его знает, что там ждет впереди. Вдруг стартапы не пойдут, неохота подрабатывать чернорабочим :) ОК, в таком случае какой посоветуете язык на случай более серьезного погружения в программирование, но таки оставаясь в рамках цели сделать сайт? Сайт не суперсложный, но и не совсем простой. Вордпрессы изучать неохота. Мне кажется это
Если хотите учить хороший язык, но с целью сделать сайт, изучите Пайтон ( http://ru.wikipedia.org/wiki/Python )
Благодарю! Наверно так и сделаю. Несмотря что он в последнем рейтинге языков