Scriptorama.nl

Header image showing a keyboard, mouse, laptop and books on design patterns

Operator overloading voor PHP 5.1

Via PHPDeveloper kwam ik er achter dat er een nieuwe PHP extensie is die operator overloading mogelijk maakt. Niet veel mensen houden van operator overloading doordat het onduidelijkheid kan creëeren. Desondanks is het best wel leuk om eens naar zo'n extensie te kijken, en dat is precies wat ik ga doen.

Operator overloading?

Operator overloading is een techniek waar je standaard operators, zoals +, -, /, % en andere (combinaties) voor een bepaalde klasse zelf implementeert, zodat ze in feite een andere betekenis krijgen. Dit is meteen de reden waarom de meeste mensen eigenlijk tegen operator overloading zijn. Ze geven standaard elementen in de taal een nieuwe betekenis zonder dat je dat direct ziet. Dit kan dus tot enorm gepuzzel leiden.

Het is een controversiele techniek en iets dat waarschijnlijk nooit in PHP zelf geimplementeerd zal worden. Maar met PHP 5 hebben extensie ontwikkelaars meer controle gekregen over het verwerken van instructies binnen PHP waardoor dit soort extensies mogelijk worden.

Installeren

Je kunt de operator overloading module installeren via PECL of je kunt de tarball hier downloaden Met PECL kun je met het volgende commando de extensie ophalen en compileren:

CODE:
  1. $ pecl install operator-beta

Vervolgens zul je de extensie even in php.ini moeten configureren:

CODE:
  1. extension = "operator.so"

Vervolgens zou de extensie beschikbaar moeten zijn:

CODE:
  1. $ php -m | grep operator
  2. operator

Nu kun je vrij simpel je eigen gedrag voor verschillende operators definieëren. De PHP manier om speciaal gedrag uit te voeren in klassen is het gebruik van "magic methods". Dit zijn methodes waarvan de naam altijd begint met twee underscores. PHP 5.1 heeft er zonder deze extensie al een paar: __clone(), __sleep() __wakeup(). Met deze operator komt er per mogelijke operator definitie dan een bij:

  • __add(): optellen ( + )
  • __sub(): aftrekken ( - )
  • __mul(): vermenigvuldigen ( * )
  • __div(): delen ( / )
  • __mod(): modulo ( % )
  • __assign_add: optellen en toewijzen ( += )
  • __assign_sub: aftrekken en toewijzen ( -= )
  • __assign_mul: vermenigvuldigen en toewijzen ( *= )
  • __assign_div: delen en toewijzgen ( /= )

Er is geen documentatie beschikbaar, maar een compleet overzicht vind je in de sourcecode.

Een voorbeeldje

Door deze methodes te implementeren in een van je klassen kun je dus extra gedrag geven aan een operator, zoals het volgende voorbeeldje demonstreert:

PHP:
  1. class OrderLine
  2. {
  3.   private $_price, $_number;
  4.  
  5.   function __construct($price, $number)
  6.   {
  7.     $this->_price   = $price;
  8.     $this->_number  = $number;
  9.   }
  10.  
  11.   function price()
  12.   {
  13.     return $this->_price * $this->_number;
  14.   }
  15. }
  16.  
  17. class ShoppingCart
  18. {
  19.   private $_lines, $_total;
  20.  
  21.   /* Definieer extra functionaliteit voor de += operator */
  22.   public function __assign_add(OrderLine $line)
  23.   {
  24.     $this->_lines[] = clone $line;
  25.     $this->_recalculate();
  26.   }
  27.  
  28.   private function _recalculate()
  29.   {
  30.     $this->_total = 0.00;
  31.  
  32.     foreach ($this->_lines as $line)
  33.     {
  34.       $this->_total += $line->price();
  35.     }
  36.   }
  37.  
  38.   function printTotal()
  39.   {
  40.     echo "Total: ", number_format($this->_total, 2), "\n";
  41.   }
  42. }
  43.  
  44. $cart = new ShoppingCart();
  45.  
  46. /* De += operator hebben we extra gedrag
  47.    gegeven in de Shoppingcart Klasse */
  48. $cart += new OrderLine(1.20, 5);
  49. $cart->printTotal();

geeft:

CODE:
  1. $ php test.php
  2. Total: 6.00

Conclusie

PHP 5.1 biedt extensie ontwikkelaars de mogelijkheid om extra gedrag aan bepaalde bytecodes/instructies te hangen. Deze extensie is daar een voorbeeld van. Operator Overloading biedt in sommige gevallen syntactic sugar voor bepaalde operaties. Daarin tegen kan het ook de nodige mensen er toe leiden dit soort guides te schrijven.

Reageer ook!

Leave a comment
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>