stream_filter_register

(PHP 5)

stream_filter_registerРегистрирует потоковый фильтр, определённый пользователем

Описание

bool stream_filter_register ( string $filtername , string $classname )

stream_filter_register() позволяет вам реализовать ваш собственный фильтр на любом зарегистрированном потоке, используемом со всеми другими функциями файловой системы (такими как fopen(), fread() и т. д.).

Список параметров

filtername

Название регистрируемого фильтра.

classname

Для того, чтобы реализовать фильтр, вам нужно определить класс как расширение php_user_filter c функциями-членами как указано ниже. При выполнении операций чтения/записи на потоке, к которому прикреплён ваш фильтр, PHP будет передавать данные через ваш фильтр (и через любые другие фильтры, прикреплённые к потоку) так что данные могут быть изменены как требуется. Вы должны реализовать методы точно как описано ниже. Иная реализация приведёт к непредсказуемому поведению.

int filter ( resource $in , resource $out , int &$consumed , bool $closing )

Этот метод вызывается каждый раз, когда данные читаются или записываются в прикреплённый поток (такой, как с функциями fread() или fwrite()). Переменная in - это ресурс, указывающий на последовательный поток данных (bucket brigade), который содержит одну или больше единиц данных (bucket), содержащих данные для фильтрации. Переменная out - это ресурс, указывающий на второй последовательный поток данных (bucket brigade), в который должны быть помещены ваши модифицированные единицы данных (buckets). Переменная consumed, которая должна всегда передаваться по ссылке, должна быть увеличена на длину данных, которые ваш фильтр читает и изменяет. В большинстве случаев это означает, что вы будете увеличивать consumed на $bucket->datalen для каждого $bucket. Если поток в процессе закрытия (и таким образом это последний проход по цепочке фильтров), параметр closing будет установлен в значение TRUE. Метод filter() должен возвращать одно из трёх предопределённых значений после завершения.

Возвращаемое значение Смысл
PSFS_PASS_ON Фильтр отработал успешно, данные доступны в out bucket brigade.
PSFS_FEED_ME Фильтр отработал успешно,однако данные не доступны для возврата. Требуется больше данных из потока или предыдущего фильтра.
PSFS_ERR_FATAL (по умолчанию) Фильтр получил неисправимую ошибку и не может продолжать.

bool onCreate ( void )
Этот метод вызывается во время создания объекта класса фильтра. Если ваш фильтр выделяет или инициализирует любые другие ресурсы (такие, как буфер), то нужно делать это здесь. Ваша реализация этого метода должна возвращать FALSE в случае неудачи или TRUE в случае успеха. Когда создаётся первый экземпляр вашего фильтра и вызывается метод yourfilter->onCreate(), будет доступно несколько свойств, показанных в таблице ниже.

Свойство Содержимое
FilterClass->filtername Строка, содержащая название фильтра, экземпляр которого был создан. Фильтры могут быть зарегистрированы под разными именами или шаблонами. Используйте это свойство для того, чтобы определить какое название было использовано.
FilterClass->params Содержимое параметра params, переданного функции stream_filter_append() или stream_filter_prepend().
FilterClass->stream Ресурс фильтруемого потока. Может быть доступен только во время вызовов filter(), когда параметр closing установлен в значение FALSE.

void onClose ( void )

Этот метод вызывается во время завершения фильтра (обычно это происходит во время завершения потока), и выполняется после того, как был вызван метод flush. Если любые ресурсы были выделены или инициализированы во время вызова метода onCreate(), то здесь следует их уничтожить или избавиться от них.

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

stream_filter_register() будет возвращать FALSE если фильтр с именем filtername уже определён.

Примеры

Пример #1 Фильтр для перевода букв в верхний регистр в потоке foo-bar.txt

Пример ниже реализует фильтр с названием strtoupper на файловом потоке foo-bar.txt, который будет переводить в заглавные все буквы, которые пишутся/читаются из этого потока.

<?php

/* Определяем наш класс фильтра */
class strtoupper_filter extends php_user_filter {
  function 
filter($in$out, &$consumed$closing)
  {
    while (
$bucket stream_bucket_make_writeable($in)) {
      
$bucket->data strtoupper($bucket->data);
      
$consumed += $bucket->datalen;
      
stream_bucket_append($out$bucket);
    }
    return 
PSFS_PASS_ON;
  }
}

/* Регистрируем наш фильтр в  PHP */
stream_filter_register("strtoupper""strtoupper_filter")
    or die(
"Не удалось зарегистрировать фильтр");

$fp fopen("foo-bar.txt""w");

/* Присоединяем зарегистрированный фильтр к только что открытому потоку */
stream_filter_append($fp"strtoupper");

fwrite($fp"Line1\n");
fwrite($fp"Word - 2\n");
fwrite($fp"Easy As 123\n");

fclose($fp);

/* Читаем содержимое снова
 */
readfile("foo-bar.txt");

?>

Результат выполнения данного примера:

LINE1
WORD - 2
EASY AS 123

Пример #2 Регистрация стандартного фильтра, соответствующего множественным именам фильтров.

<?php

/* Определяем наш класс фильтра */
class string_filter extends php_user_filter {
  var 
$mode;

  function 
filter($in$out, &$consumed$closing)
  {
    while (
$bucket stream_bucket_make_writeable($in)) {
      if (
$this->mode == 1) {
        
$bucket->data strtoupper($bucket->data);
      } elseif (
$this->mode == 0) {
        
$bucket->data strtolower($bucket->data);
      }

      
$consumed += $bucket->datalen;
      
stream_bucket_append($out$bucket);
    }
    return 
PSFS_PASS_ON;
  }

  function 
onCreate()
  {
    if (
$this->filtername == 'str.toupper') {
      
$this->mode 1;
    } elseif (
$this->filtername == 'str.tolower') {
      
$this->mode 0;
    } else {
      
/* Был вызван какой-то другой фильтр str.*,
         возвращаем ошибку, чтобы  PHP мог продолжить его поиск */
      
return false;
    }

    return 
true;
  }
}

/* Регистрируем наш фильтр в  PHP */
stream_filter_register("str.*""string_filter")
    or die(
"Не удалось зарегистрировать фильтр");

$fp fopen("foo-bar.txt""w");

/* Присоединяем зарегистрированный фильтр к только что открытому потоку
   Мы могли бы использовать здесь  str.tolower */
stream_filter_append($fp"str.toupper");

fwrite($fp"Line1\n");
fwrite($fp"Word - 2\n");
fwrite($fp"Easy As 123\n");

fclose($fp);

/* Читаем содержимое снова
 */
readfile("foo-bar.txt");
?>

Результат выполнения данного примера:

LINE1
WORD - 2
EASY AS 123

Смотрите также


Участник рейтинга Тэглайн 2010