Upgrade to Pro — share decks privately, control downloads, hide ads and more …

IPC 2013: Decoupling Objects With Standard Interfaces

IPC 2013: Decoupling Objects With Standard Interfaces

Thomas Weinert

October 30, 2013
Tweet

More Decks by Thomas Weinert

Other Decks in Programming

Transcript

  1. About Me About Me • Thomas Weinert • @ThomasWeinert •

    dimensional GmbH • papaya CMS • PHP, Javascript, XSLT • XML Fanatic (JSON is BAD)
  2. Object Initialization Object Initialization • Magic Methods • __construct() •

    __destruct() • __clone() • __sleep()/__wakeup() → Serializeable • __set_state()
  3. __toString __toString /** * Casting the object to string will

    * return the last value * @return string */ public function __toString() { return (string)end($this->_values); }
  4. Dynamic Properties Dynamic Properties $object->value = 123 $value = $object->value;

    $object->setValue(123); $value = $object->getValue();
  5. __isset() __isset() /** * @param string $name * @return boolean

    */ public function __isset($name) { switch ($name) { case name : case value : case values : return TRUE; } return FALSE; }
  6. __get() __get() /** * @param string $name * @throws InvalidArgumentException

    * @return mixed */ public function __get($name) { switch ($name) { case name : return $this->_name; case value : return end($this->_values); case values : return $this->_values; } throw new LogicException( sprintf( 'Can not read non existing property: %s::$%s', __CLASS__, $name ) ); }
  7. __set() __set() /** * @param string $name * @param string|array|Traversable

    $value * @throws LogicException */ public function __set($name, $value) { switch ($name) { case name : $this->setName($value); return; case value : $this->setData((string)$value); return; case values : $this->setData($value); return; } throw new LogicException( sprintf( 'Can not write non existing property: %s::$%s', __CLASS__, $name ...
  8. Generic Callbacks Generic Callbacks class MyEvents extends Events { public

    function __construct() { parent::__construct(['example' => 21]); } } $my = new MyEvents(); echo $my->onExample(), "n"; //21 $my->onExample = function () { return 42; }; echo $my->onExample(), "n"; //42 $my->onExample = 23; echo $my->onExample(), "n"; //23
  9. PHP Documentor PHP Documentor /** * … * @property Callable

    $onExample * @method mixed onExample() */ class MyEvents extends Events { public function __construct() { parent::__construct(['example' => 21]); } }
  10. Callback Lists Callback Lists $queries = Io\Deferred::When( $mysqlOne("SELECT Query 1,

    SLEEP(5)")->done( function($result) use ($time) { var_dump(iterator_to_array($result)); var_dump(microtime(TRUE) - $time); } ), $mysqlTwo("SELECT Query 2, SLEEP(1)")->done( function($result) use ($time) { var_dump(iterator_to_array($result)); var_dump(microtime(TRUE) - $time); } ) );
  11. Functor Example Functor Example class DatabaseResultDebugger { private $_startTime =

    0; public function __construct($startTime) { $this->_startTime = $startTime; } public function __invoke($result) { var_dump(iterator_to_array($result)); var_dump( microtime(TRUE) - $this->_startTime ); } }
  12. Callback Handlers Callback Handlers $queries = Io\Deferred::When( $mysqlOne("SELECT Query 1,

    SLEEP(5)")->done( new DatabaseResultDebugger($time) ), $mysqlTwo("SELECT Query 2, SLEEP(1)")->done( new DatabaseResultDebugger($time) ) );
  13. More Callback Handlers More Callback Handlers $queries = Io\Deferred::When( $mysqlOne("SELECT

    Query 1, SLEEP(5)") ->done( new ConcreteDatabaseResultHandler() ) ->done( new DatabaseResultDebugger($time) ), $mysqlTwo("SELECT Query 2, SLEEP(1)") ->done( new DatabaseResultDebugger($time) ) );
  14. Predeclared Interfaces Predeclared Interfaces • Serializeable • Usage • serialize($object)

    • unserialize($string); • Methods • $object->serialize() • $object->unserialize($string);
  15. OffsetExists() OffsetExists() /** * @param integer $offset * @return boolean

    */ public function offsetExists($offset) { return array_key_exists( $offset, $this->_values ); }
  16. OffsetGet() OffsetGet() /** * @param integer $offset */ public function

    offsetGet($offset) { return $this->_values[$offset]; }
  17. OffsetSet() OffsetSet() /** * @param integer $offset * @param string

    $value */ public function offsetSet($offset, $value) { if (NULL === $offset) { $this->_values[] = $value; } else { $this->_values[$offset] = $value; } }
  18. OffsetUnset() OffsetUnset() /** * @param integer $offset */ public function

    offsetUnset($offset) { unset($this->_values[$offset]); }
  19. Countable Example Countable Example class DatabaseResult implements Countable { ...

    public function count() { return $this->_count; } ... }
  20. Iterator functions - Usage Iterator functions - Usage • foreach()

    • iterator_to_array() • iterator_count() • iterator_apply()
  21. IteratorAggregate IteratorAggregate • getIterator() class MyDatabaseResult implements IteratorAggregate { private

    $_items = array(); public function getIterator() { return new ArrayIterator( $this->_items ); } }
  22. RecursiveIterator RecursiveIterator • List with Children $items = [ 1

    => '1', 2 => '1.1', 3 => '2' ]; $structure = [ 0 => [1, 3], 1 => [2] ];
  23. Inherit from IteratorIterator Inherit from IteratorIterator class Bar extends IteratorIterator

    implements RecursiveIterator { private $_items = []; private $_structure = []; public function __construct( $items, $structure, $parent = 0 ) { → next slide } …
  24. Inherit from IteratorIterator Inherit from IteratorIterator … $siblings = [];

    if (!empty($structure[$parent])) { foreach ($structure[$parent] as $id) { if (isset($items[$id])) { $siblings[$id] = $items[$id]; } } } parent::__construct( new ArrayIterator($siblings) ); $this->_items = $items; $this->_structure = $structure; …
  25. getChildren() getChildren() public function getChildren() { if ($this->hasChildren()) { return

    new $this( $this->_items, $this->_structure, $this->key() ); } else { return new $this([], []); } }
  26. RecursiveIteratorIterator RecursiveIteratorIterator • Iterator for RecursiveIterator $iterator = new RecursiveIteratorIterator(

    new Bar($items, $structure), RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $element) { echo str_repeat(*, $iterator->getDepth() + 1); echo $element; echo "n"; }
  27. Result Result * 1 ** 1.1 * 2 • No

    recursive function call • Works with Traversable/ArrayAccess • Allows for Lazy Initalization