Введение в PHP Потоки. Метаданные и фильтры потока
В предыдущей статье мы узнали, что такое потоки ввода/вывода и контексты потоков в PHP, рассмотрели примеры их использования. А в этой статье мы рассмотрим, какие дополнительные данные мы сможем получить при выполнении запроса с помощью потоковых функций, также какие фильтры потоков мы можем использовать и рассмотрим примеры обработчиков потоков.
Если Вы тестировали работоспособность последнего примера, то он должен был бы распечатать содержимое главной страницы сайта example.ru, не выводя при этом http-заголовки. А заголовки ответа сервера зачастую имеют важное значение, и поэтому они считаются частью метаданных.
Пример с использованием метода GET:
<?php
$opts = [
'http' => [
'method' => "GET",
'header' => "Accept-language: en \r\n".
"Cookie: foo = bar \r\n"
]
];
$context = stream_context_create($opts);
$fp = fopen("http://example.ru/", "rb", false, $context);
echo stream_get_contents($fp);
// получаем метаданные и выводим
print_r(stream_get_meta_data($fp));
?>
Пример с POST:
<?php
// данные POST запроса
$postdata = [
'price' => 50,
'brand' => 'NNN'
];
$opts = [ 'http' => [
// метод запроса
'method' => 'POST',
// тип содержимого
'header' => 'Content-type: application/x-www-form-urlencoded',
// само содержимое
'content' => http_build_query($postdata, '', '&'),
// время ожидания скриптом отклика
'timeout' => 5,
]
];
// создаем контекст из настроек
$context = stream_context_create($opts);
// открываем соединение
$fp = fopen ("http://example.ru/", "rb", false, $ context);
// получаем содержимое страницы
echo stream_get_contents($fp);
// получаем метаданные, заголовки ответа сервера
print_r(stream_get_meta_data($fp));
?>
Здесь мы используем функцию stream_get_contents() для того, чтобы вывести содержимое ресурса $fp. Затем, чтобы получить метаданные этого запроса, мы используем stream_get_meta_data(), передав ему в аргументе указатель на ресурс $fp.
Результат выполнения скрипта будет примерно следующий:
<?php
// это данные из массива $_POST
Array
(
[price] => 50
[brand] => NNN
)
// это заголовки ответа сервера - метаданные потока (stream metadata)
Array
(
[timed_out] =>
[blocked] => 1
[eof] => 1
[wrapper_data] => Array
(
[0] => HTTP/1.0 200 OK
[1] => Host: example.ru
[2] => Connection: close
[3] => X-Powered-By: PHP/5.5.9
[5] => Content-type: text/plain;charset=UTF-8
)
[wrapper_type] => http
[stream_type] => tcp_socket/ssl
[mode] => rb
[unread_bytes] => 0
[seekable] =>
[uri] => http://example.ru/
)
?>
Фильтры потока
У потоков (php stream) в PHP есть дополнительный набор функций - фильтры потоков. С их помощью можно менять данные "налету", во время чтения и записи данных. Функции stream_filter_append() и stream_filter_prepend() присоединяют фильтр к потоку либо перед операцией, либо после. Для примера рассмотрим использование функции шифрования str_rot13() в качестве функции фильтра.
<?php
$opts = [ 'http' => [
'method' => "GET",
'header' => "Accept-language: en\r\n".
"Cookie: foo=bar\r\n"
]
];
$context = stream_context_create($opts);
// открываем соединение
$fp = fopen ("http://example.ru/", "rb", false, $context);
// применяем фильтр
stream_filter_append($fp, "string.rot13", STREAM_FILTER_READ);
// выводим результат
echo stream_get_contents($fp);
?>
Результат будет примерно следующий:
<!QBPGLCR ugzy>... // и так далее
В PHP существуют встроенные фильтры как для простых преобразований так и для кодирования и декодирования, сжатия и даже шифрования, как в примере выше. Список доступных фильтров приведен в официальном руководстве по следующему адресу PHP Streams.
Примеры использования обработчиков:
<?php
// Чтение локального файла
$localfile = file_get_contents("C:/Files/story.txt");
// С явным заданием схемы FILE
$localfile = file_get_contents("file://C:/Files/story.txt");
// Чтение удаленного файла по адресу example.ru, используя HTTP
$httpfile = file_get_contents("http://example.ru");
// Чтение удаленного файла по адресу example.ru, используя HTTPS
$httpsfile = file_get_contents("https://example.ru/file.txt");
// Чтение удаленного файла по адресу ftp.example.ru, используя FTP
$ftpfile = file_get_contents("ftp://user:[email protected]/file.txt");
// Чтение удаленного файла по адресу ftp.example.ru, используя FTPS
$ftpsfile = file_get_contents("ftps://user:[email protected]/file.txt");
?>
Запись данных в сжатый файл:
<?php
/* Создаем сжатый файл с различными данными
* Файл можно прочитать с помощью потока compress.zlib либо
* просто разархивировать
*/
$fd = fopen("compress.zlib://secret.gz", "wb");
if (!$fd) exit("Файл не может быть создан.");
fwrite($fd, "MyruSakov.Ru\n");
fclose($fd);
?>
Строго говоря, существующих обработчиков потоков данных вполне достаточно для выполнения 99% повседневных задач, да к тому же существует масса готовых решений, которые могут избавить Вас от необходимости реализации собственных обработчиков потоков ввода/вывода в PHP. Поэтому потоки (stream) в PHP - это мощный и далеко не тривиальный инструмент, для овладения которым необходима определённая сноровка.
Спасибо за внимание и всего доброго!
-
- Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.