SPL Iterators

Базовые понятия
Итераторы (Iterators) — это классы которые реализуют интерфейс Iterator. Реализация данного интерфейса необходима при организации доступа к циклическим структурам (массивы, списки и т.д.).

В SPL (Standard PHP Library) существует большое количество готовых классов, реализующих интерфейс Iterator.

Далее перечислены классы, которые непосредственно реализуют интерфейс Iterator: Traversable, IteratorAgregate, OuterIterator, RecursiveIterator. Остальные классы-итераторы SPL наследуют свои интерфейсы уже от них.

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

Так как интерфейс Iterator входит в библиотеку стандартных классов PHP (Standard PHP Library), то его реализация выполнена в исходниках самого интерпретатора (имеются в виду коды программы на языке «С»). Если выразить этот интерфейс на языке PHP, то он будет выглядеть так:

interface Iterator{
  public function current(); // возвращает значение текущего элемента
  public function key(); // возвращает значения текущего ключа элемента (индекс массива например)
  public function next(); // смещает указатель на следующий элемент
  public function rewind(); // смещает указатель на первый элемент
  public function valid(); // определяет наличие элемента (выполняется после next или rewind)
}


Итераторы могут быть использованы во многих областях программирования. Например, при обработке набора значений полученных из Базы данных или обработке значений массива, или обработке набора файлов и т.д.

Вспомогательные функции при работе с итераторами.

iterator_to_array(Iterator $iteratorObject) — возвращает содержимое объекта-итератора в виде массива.

iterator_count(Iterator $iteratorObject)) — возвращает количество элементов в объекте-итераторе.

Пример использования:


$a = Array('a', 'b', 'c');
$iterator = new ArrayIterator($a);
echo iterator_count($iterator); // Результат - 3


iterator_apply(Iterator iteratorObject, function callback, [user_data) — данная функция позволяет с помощью callback-а обработать каждый элемент содержащийся в объекте-итераторе.

Пример использования:

function print_entry($iteratorObject) {
   var_dump($iterator->current());
   return true;
}

$a = Array('a', 'b', 'c');
$iterator = new ArrayIterator($a);
iterator_apply($iterator, 'print_entry', array($iterator));


Если функция callback возвращает значение отличное от true перебор элементов объекта-итератора прекращается.

Что такое PHP SPL

SPL — это набор стандартных библиотек PHP (Standard PHP Library) появившихся начиная с 5-ой версии PHP.
Если рассматривать SPL с позиции разработчика, то легко выделить шесть основных классов и интерфейсов, функционал которых расширяется в большом множестве классов-потомков.

Класс ArrayAccess
ArrayAccess — это интерфейс который позволяет создать классы которые будут вести себя как массивы. В других языках эта возможность наиболее часто предоставляется с помощью интерфейсов-счетчиков (indexer).

Класс Exception;
Exception — это родительский класс SPL для большого количества классов-потомков (LogicExeption, DomainEception, RangeException и т.д.), которые «выбрасываются» при наступлении той или иной исключительной ситуации.

Класс Iterator
Iterator — это интерфейс SPL который предназначен для реализации объектов с циклической структурой. Реализация данного интерфейса в разрабатываемых классах позволяет стандартным функциям PHP (например foreach) работать с пользовательскими объектами.

Класс IteratorAgregate
IteratorAgregate — это интерфейс SPL который содержит только один метод — «getIterator». Этот интерфейс позволяет не реализовывать в классе интерфейс «Itertator», а использовать вместо этого внешний итератор.

Класс Serializable
Serializable — это интерфейс который позволяет сериализовать любой объект с помощью функций Serialize и Unserrialize

Класс Traversable
Traversable — это служебный класс SPL который используется в интерфейсах Iterator и IteratorAgregate. Реализовать данный интерфейс в PHP-программе нельзя т.к. он реализован на урове C-кода интерпретатора PHP.

Кроме этого есть несколько других возможностей таких как шаблон проектирования «observer», вспомогательные функции для идентификации объекта и для работы с итераторами. Так же есть функционал позволяющий автоматизировать процесс загрузки классов и интерфейсов.

The requested operation has failed

Ошибка «The requested operation has failed» — это не совсем ошибка PHP, но очень часто появляется именно при попытке настроить Apache 2.2.x для работы с PHP, подключаемого в качестве модуля. В таком случае причин появления ошибки может быть несколько.

Во-первых, ошибка может проявляться в случае если используемый модуль PHP не совместим с версией Apache. Чтобы исключить данный вариант, рекомендую попытаться поискать в интернете и скачать модуль PHP более новой версии.

Во-вторых, очень часть Apache отказывается работать если на компьютере установлен Skype, тогда в последнем необходимо найти и отключить опцию «использовать порты 80 и 443 в качестве входящих альтернативных»;

В-третьих, причиной ошибки может быть неверный синтаксис конфигурационного файла httpd.conf. В таком случае найти и устранить ошибку без соответствующей подготовки очень трудно. Поэтому начинающим рекомендую скачать и установить пакет «Денвер.

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

Call to undefined function curl init

Если Вы попали на эту страницу, значит у Вас есть проблема и имя этой проблемы: «Call to undefined function curl init». Так как ошибка среди Веб-программистов очень распространенная, то смею предположить следующее:

1.Вы начинающий веб-программист и с ошибкой «Call to undefined function curl init» сталкиваетесь впервые;
2.Как начинающий программист, Вы работаете в популярном пакете «Денвер»;
3.Опыта работы с CURL у Вас нет.

Если все сказанное — это про Вас, то вполне вероятно я смогу помочь Вашему горю.

Шаг первый. Проверяем установлен ли у нас CURL

В подавляющем большинстве случаев ошибка «Call to undefined function curl init» появляется по причине того, что у Вас просто напросто не установлен CURL. Что бы проверить так ли это, пишем небольшой скрипт:


<?php
phpinfo();
?>


Сохраняем его под именем «info.php» в корне вашего сайта и открываем в браузере страницу с адресом «имя_вашего_сайта/info.php». Далее открываем окошко поиска по странице и вбиваем слово «curl». Если в результате поиска Вы ничего не нашли, то поздравляю — CURL у Вас не установлен.

Шаг второй. Устанавливаем CURL

Итак, самый простой способ установить библиотеку CURL под Денвер — это скачать файл «php_curl.dll» и разместить его в Денвере по следующему пути «usr/local/php5/ext/php_curl.dll».

После чего зайти в файл php.ini, найти и раскоментировать строку «extension=php_curl.dll» и перезапустить «Денвер».

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

Шаг третий. Что делать если все сказанное выше не помогло

Бывает и такое, что после всех усилий проблема «Call to undefined function curl ini» не решается. В таком случае рекомендую сделать следующее:

Во-первых, проверить, что параметр «extension_dir» в php.ini указывает на директорию «usr/local/php5/ext/».
Во-вторых, попробовать скачать другой файл «php_curl.dll».

Если указанные действия не помогли, то пишите в комментарии о Вашей проблеме, и мы обязательно поможем вашему горю!

Как сделать ZIP архив средствами PHP

Многие думают, что создать ZIP архив средствами PHP сложно. На самом деле это не так. Все, что нужно — это несколько строк кода и готовая библиотека PclZip.lib.

Алгоритм работы с библиотекой следующий:

1. Подключаем к проекту модуль pclzip.lib.php;
2. Создаем экземпляр класса PclZip;
3. Выполняем необходимые действия по внесению или извлечению данных из архива;
4. Обрабатываем возможные ошибки.

Для примера, рассмотрим скрипт, который извлекает файлы из заранее подготовленного архива:


require_once('pclzip.lib.php'); //подключаем pclzip.lib
// определяем директорию куда загружен файл z.zip
// по-умолчанию считаем что это та директория в которой лежит распаковочный скрипт
$upload_dir = dirname( __FILE__ ); 
$filename = 'z.zip'; 

// распаковываем в ту же директорию куда загружен файл z.zip
$zip_dir = ''; 

// распаковка делается посредством инстанса специального класса PclZip
$archive = new PclZip($filename); 

if ($archive->extract(PCLZIP_OPT_PATH, $upload_dir.'/'.$zip_dir) == 0)
// в "реальном" скрипте было бы неплохо выдавать сообщение об ошибке которая возникла в процессе распаковки
	die("Error\n"); 
echo "Ok\n";