SPL, объекты как массивы

Стандартная библиотека PHP (SPL) - это набор интерфейсов и классов, предназначенных для решения стандартных задач.

Не требуется никаких внешних библиотек для сборки этого расширения, и оно доступно по умолчанию в PHP 5.0 и выше.

SPL предоставляет ряд стандартных структур данных, итераторов для оббегания объектов, интерфейсов, стандартных исключений, некоторое количество классов для работы с файлами и предоставляет ряд функций, например spl_autoload_register().

Интерфейс ArrayAccess

interface ArrayAccess
{
    function offsetSet($offset, $value);
    function offsetGet($offset);
    function offsetUnset($offset);
    function offsetExists($offset);
}

Позволяет объекту класса вести себя как псевдо массив.

Интерфейс Iterator

Позволяет проиводить простую итерацию над простым одномерным массивом.

interface Iterator
{
    function current();
    function next();
    function rewind();
    function key();
    function valid();
}

Его расширяют:

  • SeekableIterator, имеет метод seek($index) для доступа к определенному элементу из хранилища.
  • RecursiveIteratorIterator - перебор вложенных массивов.

Inner iterators служат для перебора внутренних данных, тогда как Outer Iterators служат для перебора других итераторов (например, RecursiveIteratorIterator).

Различие Iterator и IteratorAggregate

Интерфейс InteratorAggregate очень похож на Iterator, оба они наследуются от Traversable (который определяет, является ли класс обходимым через foreach). Но в отличии от Iterator интерфейс IteratorAggregate создает внешний Iterator. Но когда итератор основан на массиве, использование внешнего Iterator делает код более читабельным и простым:

class Foo implements IteratorAggregate
{
    protected $attributes;

    public function getIterator()
    {
        return new ArrayIterator($this->attributes);
    }
}

Для случаев, когда нужен польный контроль над итерацией объекта лучше использовать простой Iterator.

Интерфейс Countable

Классы, которые реализуют интерфейс Countable, могут быть использованы с функцией count().

Интерфейс Serializable

Интерфейс для индивидуальной сериализации. Классы, которые реализуют этот интерфейс не поддерживают больше __sleep() и __wakeup(). Метод serialize вызывается всякий раз, когда необходима сериализация экземпляру класса.

Класс ArrayObject

Данный класс позволяет работать с объектами как с массивами. Класс реализует интерфейсы ArrayAccess, IteratorAggregate , ArrayAccess , Serializable , Countable.

Опции ArrayObject

ArrayObject::STD_PROP_LIST

  • Свойства объекта получают стандартное поведение, при доступе к объекту как к списку (var_dump, foreach и т.д.).

ArrayObject::ARRAY_AS_PROPS

  • Записи могут быть доступны как свойства (для чтения и записи).
new ArrayObject($var); // $var может быть как array так и object (только public свойства)

$arrayobj = new ArrayObject($array,ArrayObject::STD_PROP_LIST); 
// свойства ведут себя стандартно

$arrayobj = new ArrayObject($array,ArrayObject::ARRAY_AS_PROPS); 
/*
свойства могут быть доступны двумя вариантами:
$arrayobj->prop и $arrayobj['prop'] 
*/

Функции ArrayObject

public void ArrayObject::append ( mixed $value )

  • Добавляет значение в конец массива.
  • Не возвращает значения после выполнения.
<?php
$arrayobj = new ArrayObject(array('first','second','third'));
$arrayobj->append('fourth');
$arrayobj->append(array('five', 'six'));
var_dump($arrayobj);

/*
object(ArrayObject)#1 (5) {
  [0]=>
  string(5) "first"
  [1]=>
  string(6) "second"
  [2]=>
  string(5) "third"
  [3]=>
  string(6) "fourth"
  [4]=>
  array(2) {
    [0]=>
    string(4) "five"
    [1]=>
    string(3) "six"
  }
}
*/
?>

public void ArrayObject::asort ( void )

  • Эта функция сортирует элементы массива таким образом, что сохраняются отношения между ключами и значениями. В основном, она используется при сортировке ассоциативных массивов, где важно сохранить отношение ключ => значение.
  • Не возвращает значения после выполнения.
<?php
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
$fruitArrayObject = new ArrayObject($fruits);
$fruitArrayObject->asort();

foreach ($fruitArrayObject as $key => $val) {
    echo "$key = $val\n";
}
?>
/*
c = apple
b = banana
d = lemon
a = orange
*/

public array ArrayObject::getArrayCopy ( void )

  • Возвращает копию массива. Если ArrayObject ссылается на объект, то будет возвращен массив публичных (public) свойств данного объекта.
<?php
// Массив с количеством фруктов
$fruits = array("lemons" => 1, "oranges" => 4, "bananas" => 5, "apples" => 10);

$fruitsArrayObject = new ArrayObject($fruits);
$fruitsArrayObject['pears'] = 4;

// Создать копию массива
$copy = $fruitsArrayObject->getArrayCopy();
print_r($copy);
/*
Array
(
    [lemons] => 1
    [oranges] => 4
    [bananas] => 5
    [apples] => 10
    [pears] => 4
)
*/
?>

public void ArrayObject::setFlags ( int $flags )

  • Устанавливает флаги, которые влияют на поведение ArrayObject.
  • Не возвращает значения после выполнения.
<?php
// Массив с количеством фруктов
$fruits = array("lemons" => 1, "oranges" => 4, "bananas" => 5, "apples" => 10);

$fruitsArrayObject = new ArrayObject($fruits);

// Попытка использовать ключ массива как свойство
var_dump($fruitsArrayObject->lemons);
// Установка флага, позволяющего использовать ключи массива как свойства ArrayObject
$fruitsArrayObject->setFlags(ArrayObject::ARRAY_AS_PROPS);
// Новая попытка
var_dump($fruitsArrayObject->lemons);

/*
NULL
int(1)
*/
?>

public int ArrayObject::getFlags ( void )

  • Получает флаги поведения ArrayObject.
<?php
// Массив с количеством фруктов
$fruits = array("lemons" => 1, "oranges" => 4, "bananas" => 5, "apples" => 10);

$fruitsArrayObject = new ArrayObject($fruits);

// Получение текущих флагов
$flags = $fruitsArrayObject->getFlags();
var_dump($flags);

// Установка новых флагов
$fruitsArrayObject->setFlags(ArrayObject::ARRAY_AS_PROPS);

// Получение новых флагов
$flags = $fruitsArrayObject->getFlags();
var_dump($flags);

/*
int(0)
int(2)
*/
?>

public ArrayIterator ArrayObject::getIterator ( void )

  • Создаёт новый итератор из экземпляра ArrayObject.
<?php
$array = array('1' => 'one',
               '2' => 'two',
               '3' => 'three');

$arrayobject = new ArrayObject($array);

$iterator = $arrayobject->getIterator();

while($iterator->valid()) {
    echo $iterator->key() . ' => ' . $iterator->current() . "\n";

    $iterator->next();
}

/*
1 => one
2 => two
3 => three
*/
?>

public void ArrayObject::setIteratorClass ( string $iterator_class )

  • Устанавливает имя класса итератора массива, возвращаемое ArrayObject::getIterator().
<?php
// Пользовательский ArrayIterator (включает в себя ArrayIterator)
class MyArrayIterator extends ArrayIterator {
    // пользовательская реализация
}

// Массив с количеством фруктов
$fruits = array("lemons" => 1, "oranges" => 4, "bananas" => 5, "apples" => 10);

$fruitsArrayObject = new ArrayObject($fruits);

// Устанавливает новое имя класса итератора
$fruitsArrayObject->setIteratorClass('MyArrayIterator');
print_r($fruitsArrayObject->getIterator());

/*
MyArrayIterator Object
(
    [lemons] => 1
    [oranges] => 4
    [bananas] => 5
    [apples] => 10
)
*/
?>

public string ArrayObject::getIteratorClass ( void )

  • Возвращает имя класса итератора массива, который используемый ArrayObject::getIterator().

public bool ArrayObject::offsetExists ( mixed $index )

  • Проверяет, существует ли указанный индекс.
  • Возвращает TRUE если указанный индекс существует, иначе FALSE.
<?php
$arrayobj = new ArrayObject(array('zero', 'one', 'example'=>'e.g.'));
var_dump($arrayobj->offsetExists(1));
var_dump($arrayobj->offsetExists('example'));
var_dump($arrayobj->offsetExists('notfound'));

/*
bool(true)
bool(true)
bool(false)
*/

?>

public mixed ArrayObject::offsetGet ( mixed $index )

  • Возвращает значение по указанному индексу или NULL.
<?php
$arrayobj = new ArrayObject(array('zero', 7, 'example'=>'e.g.'));
var_dump($arrayobj->offsetGet(1));
var_dump($arrayobj->offsetGet('example'));
var_dump($arrayobj->offsetExists('notfound'));

/*
int(7)
string(4) "e.g."
bool(false)
*/
?>

public void ArrayObject::offsetSet ( mixed $index , mixed $newval )

  • Устанавливает новое значение по указанному индексу.
<?php
class Example {
    public $property = 'prop:public';
}
$arrayobj = new ArrayObject(new Example());
$arrayobj->offsetSet(4, 'four');
$arrayobj->offsetSet('group', array('g1', 'g2'));
var_dump($arrayobj);

$arrayobj = new ArrayObject(array('zero','one'));
$arrayobj->offsetSet(null, 'last');
var_dump($arrayobj);
/*
object(ArrayObject)#1 (3) {
  ["property"]=>
  string(11) "prop:public"
  [4]=>
  string(4) "four"
  ["group"]=>
  array(2) {
    [0]=>
    string(2) "g1"
    [1]=>
    string(2) "g2"
  }
}
object(ArrayObject)#3 (3) {
  [0]=>
  string(4) "zero"
  [1]=>
  string(3) "one"
  [2]=>
  string(4) "last"
}
*/
?>

public void ArrayObject::offsetUnset ( mixed $index )

  • Удаляет значение по указанному индексу.
<?php
$arrayobj = new ArrayObject(array(0=>'zero',2=>'two'));
$arrayobj->offsetUnset(2);
var_dump($arrayobj);
/*
object(ArrayObject)#1 (1) {
  [0]=>
  string(4) "zero"
}
*/
?>

public string ArrayObject::serialize ( void )

  • Сериализует ArrayObject
  • Возвращает сериализованное представление ArrayObject.
<?php
$o = new ArrayObject();

$s1 = serialize($o);
$s2 = $o->serialize();

var_dump($s1);
var_dump($s2);

/*
string(45) "C:11:"ArrayObject":21:{x:i:0;a:0:{};m:a:0:{}}"
string(21) "x:i:0;a:0:{};m:a:0:{}"
*/
?>