Pull to refresh

PHP и его встроенные OOP мелочи

Reading time5 min
Views2.2K
Почитал еще в «том году» статью о PHP и OOP под названием PHP и магия ООП, тамошний Девид Блейн описал в краце что есть таки OOP в PHP… Да, автор показал как «надо» использовать правильно функции, но в наше время, когда языки стали не обьектно ориентированными а обьектными, уже не удивишь простой поддержкой OOP. Многие гнобят PHP тем что он корявый, медленный… Ну подумаешь, медленный, подумаешь параметры функций принимаются в разном порядке =) его можно ускорить акселераторами, функции можно скрыть в классах… Самая мошь OOP в PHP — встроенные интерфейсы… Вот о 2-х из них (на примере массива) я и расскажу…

Интерфейсы — вершина айсберга под названием SPL, про эту штуку я узнал здесь же, от автора загадки: сделайте чтоб код возвращал тру — if( $q[0] === 1 && $q[0] === 2 ) (точно задание не помню, я его перефразировал, так интересней)

Для начала код, разьяснения потом:
<?php

class MyArray implements ArrayAccess, Iterator
{
  private $_data;
  private $_innerCounter = -1;

  public function __construct( $data = null )
  {
    $this->_data = $data;
    $this->_innerCounter = count( $data );
  }

  public function get( $offset )
  {
    return $this[$offset];
  }
  
  // start implementing ArrayAccess interface

  public function offsetExists( $offset )
  {
    return isset( $this->_data[$offset] );
  }

  public function offsetGet( $offset )
  {
    if( is_array( $this->_data[$offset] ) )
    {
      $this->_data[$offset] = new MyArray( $this->_data[$offset] );
return $this->_data[$offset];
    }

    return $this->_data[$offset];
  }

  public function offsetSet( $offset, $value )
  {
    $this->_data[$offset] = $value;
    return $this;
  }

  public function offsetUnset( $offset )
  {
    unset( $this->_data[$offset] );
    return $this;
  }

  // end implementing ArrayAccess interface  
  
  // start implementing Iterator interface  
  
  public function current()
  {
    if( is_array( current( $this->_data ) ) )
    {
      return new MyArray( current( $this->_data ) );
    }

    //return $this->_data[$offset];
    return current( $this->_data );
  }

  public function next()
  {
    $this->_innerCounter++;
    return next( $this->_data );
  }

  public function key()
  {
    return key( $this->_data );
  }

  public function valid()
  {
    return $this->_innerCounter < count( $this->_data );
  }

  public function rewind()
  {
    $this->_innerCounter = 0;
    //return reset( $this->_data );
    return;
  }
  
  // end implementing Iterator interface 
}

$array = new MyArray( array(1, 2, 'qwe' => 'asd', 6, 'obj' => array(1,2)) );

foreach( $array as $arrayKey => $arrayValue )
{
  if( is_a( $arrayValue, 'MyArray' ) )
  {
    echo "it`s an MyArray Object with key '{$arrayKey}' -> ";
    var_dump( $arrayValue );
  }
  else
  {
    var_dump( 'key = ' . $arrayKey . ' value = ' . $arrayValue );
  }
  echo '<br>';
}

var_dump( $array['qwe'] );
echo '<br>';
var_dump( $array->get('qwe') );
echo '<br>';
var_dump( $array['obj'] );
echo '<br>';
var_dump( $array->get('obj')->get(1) );

?>

// результат:
// string(17) "key = 0 value = 1"
// string(17) "key = 1 value = 2"
// string(21) "key = qwe value = asd"
// string(17) "key = 2 value = 6"
// it`s an MyArray Object with key 'obj' -> object(MyArray)#3 (2) { ["_data:private"]=> array(2) { [0]=> int(1) [1]=> int(2) } ["_innerCounter:private"]=> int(2) }
// string(3) "asd"
// string(3) "asd"
// object(MyArray)#2 (2) { ["_data:private"]=> array(2) { [0]=> int(1) [1]=> int(2) } ["_innerCounter:private"]=> int(2) }
// int(2)

* This source code was highlighted with Source Code Highlighter.


Так вот… Есть класс MyArray которые применяет 2 интерфейса: ArrayAccess и Iterator… Что же они делают? Начнем попорядку.

ArrayAccess: интерфейс дающий возможность доступа к Вашему обьекту как к массиву (доступ через квадрытные скобочки см коментарии в коде ) пример: $array[1] или $array['qwe']
Незаменимый помощник в создании массивов!
Структура:
ArrayAccess {
/* Methods */
// проверка на существование значения по ключу ( $offset - ключ массива )
abstract public boolean ArrayAccess::offsetExists ( string $offset )
// возврат по ключу ... аля $array['offset']
abstract public mixed ArrayAccess::offsetGet ( string $offset )
// задание значения по ключу ... аля $array['offset'] = 'value'
abstract public void ArrayAccess::offsetSet ( string $offset , string $value )
// ансет ... ну тут думаю все понятно :) unset $array['offset']
abstract public void ArrayAccess::offsetUnset ( string $offset )
}


Iterator: Интерфейс дающий возможность перебора через foreach/for (возможность перебора есть у всех обьектов, а тут есть контроль ;)) членов обьекта… Естественно каких вы пожелаете (поумолчанию идут только паблик свойства)
Структура:
/* Methods */
// аналог current( array(1,2,3) )
abstract public mixed Iterator::current ( void )
// аналог key( array(1,2,3) )
abstract public scalar Iterator::key ( void )
// аналог next( array(1,2,3) )
abstract public void Iterator::next ( void )
// аналог rewind( array(1,2,3) )
abstract public void Iterator::rewind ( void )
// аналог isset( $array[1]) - вроде =)
abstract public boolean Iterator::valid ( void )


Итак, что же мы получили? Мы получили базовый обьект с одним «ручным» методом get, который возвращает элемент массива по ключу. Спрашивается зачем он нам если есть ArrayAccess? Ответ очевиден (тут я задумался и проверил возможность такого действия: $array['qwe']['asd']… Так работает =) я счастлив!): надо ведь хоть один метод реализовать, хоть для виду?!?!

В общем это уже конец, дальше любые методы реализовать не сложно, базовый функционал есть, полноценный массив есть, поддержка циклов есть, контроль над выдаваемыми данными есть… Добавляйте, изменяйте, отдаю на Ваше распоряжение…

зы: PHP — удивительный язык, со всей его немошью, на нем ножно сделать практически все, со всей его неструктурированностью, его можно полностью структурировать под себя, со всей его медлительностью, его можно разогнать до скорости компилируемых языков… я люблю этот язык какие бы у него ни были недостатки, чего и вам, PHP-щики желаю — не вешайте нос!
зыы: если ты здесь не был — ты лох! =) уж извените за выражения, но никакой мануал не восполнит этого сайта :)

UPD: по просьбам трудящихся пояснение: этот обьект не будет себя вести как полноценный массив в силу того что массивы простые типы данных, а обьекты ссылочные, и в некоторых ситуациях это свойство себя проявляет
Tags:
Hubs:
Total votes 41: ↑28 and ↓13+15
Comments23

Articles