Введение в 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:pass@ftp.example.ru/file.txt");
  // Чтение удаленного файла по адресу ftp.example.ru, используя FTPS
  $ftpsfile  = file_get_contents("ftps://user:pass@ftp.example.ru/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 - это мощный и далеко не тривиальный инструмент, для овладения которым необходима определённая сноровка.
Спасибо за внимание и всего доброго!
- 
					Создано 05.09.2017 11:55:24  
- 
					 Михаил Русаков Михаил Русаков
 
			 
			 
		 
				 
			 
				 
				 
				 
				
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.