Annotation of embedaddon/php/Zend/ZEND_CHANGES, revision 1.1.1.1

1.1       misho       1: Changes in the Zend Engine 2.0
                      2: 
                      3:     * New Object Model.
                      4: 
                      5:       The Zend Engine's handling of objects has been completely
                      6:       changed in order to allow for new features, but also to increase
                      7:       its performance.
                      8: 
                      9:       Objects were handled in previous versions like primitive types
                     10:       (for instance integers and strings). The drawback of this method
                     11:       is, that semantically the whole object was copied when a
                     12:       variable was assigned or parameters were passed to a method. The
                     13:       new approach refers to objects by handle and not by value (one
                     14:       can think of a handle as an object's ID).
                     15: 
                     16:       Many PHP programmers aren't even aware of the copying quirks of
                     17:       the old object model and, therefore, there is a relatively good
                     18:       chance that the amount of PHP applications that will work out of
                     19:       the box or after a very small amount of modifications would be
                     20:       high.
                     21: 
                     22:     * $this
                     23: 
                     24:       Unlike in Zend Engine 1 the pseudo variable $this cannot be
                     25:       exchanged in Zend Engine 2. You can of course modify or work with
                     26:       an object by using $this but you cannot replace $this with another
                     27:       object to change the original object.
                     28: 
                     29:       Example:
                     30: 
                     31:         <?php
                     32:         class Foo {
                     33:             function replace($other)
                     34:             {
                     35:                 $this = $other;
                     36:             }
                     37:         }
                     38: 
                     39:         $object = new Foo;
                     40:         $object->prop = 'Hello';
                     41: 
                     42:         $other  = new Foo;
                     43:         $other->prop = 'Bye';
                     44: 
                     45:         $object->replace($other);
                     46: 
                     47:         print $object->prop; // still shows 'Hello'
                     48: 
                     49:         ?>
                     50: 
                     51:         Zend Engine 2.0 will issue a compile error, if an assignment
                     52:         to $this is found.
                     53: 
                     54:     * Private and Protected Members.
                     55: 
                     56:       The Zend Engine 2.0 introduces private and protected member
                     57:       variables. Note that for performance reasons no error message is
                     58:       emitted in case of an illegal access to a private or protectecd
                     59:       member variable.
                     60: 
                     61:       Example:
                     62: 
                     63:         <?php
                     64:         class MyClass {
                     65:             private $Hello = "Hello, World!\n";
                     66:             protected $Bar = "Hello, Foo!\n";
                     67:             protected $Foo = "Hello, Bar!\n";
                     68: 
                     69:             function printHello() {
                     70:                 print "MyClass::printHello() " . $this->Hello;
                     71:                 print "MyClass::printHello() " . $this->Bar;
                     72:                 print "MyClass::printHello() " . $this->Foo;
                     73:             }
                     74:         }
                     75: 
                     76:         class MyClass2 extends MyClass {
                     77:             protected $Foo;
                     78: 
                     79:             function printHello() {
                     80:                 MyClass::printHello();                          /* Should print */
                     81:                 print "MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */
                     82:                 print "MyClass2::printHello() " . $this->Bar;   /* Shouldn't print (not declared)*/
                     83:                 print "MyClass2::printHello() " . $this->Foo;   /* Should print */
                     84:             }
                     85:         }
                     86: 
                     87:         $obj = new MyClass();
                     88:         print $obj->Hello;  /* Shouldn't print out anything */
                     89:         print $obj->Bar;    /* Shouldn't print out anything */
                     90:         print $obj->Foo;    /* Shouldn't print out anything */
                     91:         $obj->printHello(); /* Should print */
                     92: 
                     93:         $obj = new MyClass2();
                     94:         print $obj->Hello;  /* Shouldn't print out anything */
                     95:         print $obj->Bar;    /* Shouldn't print out anything */
                     96:         print $obj->Foo;    /* Shouldn't print out anything */
                     97:         $obj->printHello();
                     98:         ?>
                     99: 
                    100:       Protected member variables can be accessed in classes extending the
                    101:       class they are declared in, whereas private member variables can
                    102:       only be accessed by the class they belong to.
                    103: 
                    104:     * Private and protected methods.
                    105: 
                    106:       The Zend Engine 2.0 introduces private and protected methods.
                    107: 
                    108:       Example:
                    109: 
                    110:         <?php
                    111:         class Foo {
                    112:           private function aPrivateMethod() {
                    113:             echo "Foo::aPrivateMethod() called.\n";
                    114:           }
                    115: 
                    116:           protected function aProtectedMethod() {
                    117:             echo "Foo::aProtectedMethod() called.\n";
                    118:             $this->aPrivateMethod();
                    119:           }
                    120:         }
                    121: 
                    122:         class Bar extends Foo {
                    123:           public function aPublicMethod() {
                    124:             echo "Bar::aPublicMethod() called.\n";
                    125:             $this->aProtectedMethod();
                    126:           }
                    127:         }
                    128: 
                    129:         $o = new Bar;
                    130:         $o->aPublicMethod();
                    131:         ?>
                    132: 
                    133:       Old code that has no user-defined classes or functions named
                    134:       'public', 'protected' or 'private' should run without modifications.
                    135: 
                    136:     * Abstract Classes and Methods.
                    137: 
                    138:       The Zend Engine 2.0 introduces abstract classes and methods. An
                    139:       abstract method only declares the method's signature and does not
                    140:       provide an implementation. A class that contains abstract methods
                    141:       needs to be declared abstract.
                    142: 
                    143:       Example:
                    144: 
                    145:         <?php
                    146:         abstract class AbstractClass {
                    147:           abstract public function test();
                    148:         }
                    149: 
                    150:         class ImplementedClass extends AbstractClass {
                    151:           public function test() {
                    152:             echo "ImplementedClass::test() called.\n";
                    153:           }
                    154:         }
                    155: 
                    156:         $o = new ImplementedClass;
                    157:         $o->test();
                    158:         ?>
                    159: 
                    160:       Classes that do not have abstract methods can be declared abstract
                    161:       to prevent them from being instantiated.
                    162: 
                    163:       Old code that has no user-defined classes or functions named
                    164:       'abstract' should run without modifications.
                    165: 
                    166:     * Interfaces.
                    167: 
                    168:       The Zend Engine 2.0 introduces interfaces. A class may implement
                    169:       an arbitrary list of interfaces.
                    170: 
                    171:       Example:
                    172: 
                    173:         <?php
                    174:         interface Printable {
                    175:           public function dump();
                    176:         }
                    177: 
                    178:         class PrintableExample implements Printable {
                    179:           public function dump() {
                    180:             // ...
                    181:           }
                    182:         }
                    183:         ?>
                    184: 
                    185:       Old code that has no user-defined classes or functions named
                    186:       'interface' or 'implements' should run without modifications.
                    187: 
                    188:       An interface may extend one or more base interfaces (but not
                    189:       implement them). Neither a class nor an interface can inherit
                    190:       methods of the same name from different root interfaces.
                    191: 
                    192:       Interfaces may contain abstract static methods.
                    193: 
                    194:       Example:
                    195: 
                    196:         <?php
                    197:         interface Printable {
                    198:           function dump();
                    199:         }
                    200: 
                    201:         interface Streamable extends Printable {
                    202:           function writeToStream();
                    203:           static function readFromStream();
                    204:         }
                    205: 
                    206:         class PrintableExample implements Streamable {
                    207:           public function dump() {
                    208:             // ...
                    209:           }
                    210:           function writeToStream() {
                    211:             // ...
                    212:           }
                    213:           static function readFromStream() {
                    214:             // ...
                    215:           }
                    216:         }
                    217:         ?>
                    218: 
                    219:       A class that does not implement all interface methods must be
                    220:       declared as an abstract class.
                    221: 
                    222:     * Class Type Hints.
                    223: 
                    224:       While remaining loosely typed the Zend Engine 2.0 introduces the
                    225:       ability to use class type hints to declare the expected class of
                    226:       objects that are passed as parameters to a method.
                    227: 
                    228:       Example:
                    229: 
                    230:         <?php
                    231:         interface Foo {
                    232:           function a(Foo $foo);
                    233:         }
                    234: 
                    235:         interface Bar {
                    236:           function b(Bar $bar);
                    237:         }
                    238: 
                    239:         class FooBar implements Foo, Bar {
                    240:           function a(Foo $foo) {
                    241:             // ...
                    242:           }
                    243: 
                    244:           function b(Bar $bar) {
                    245:             // ...
                    246:           }
                    247:         }
                    248: 
                    249:         $a = new FooBar;
                    250:         $b = new FooBar;
                    251: 
                    252:         $a->a($b);
                    253:         $a->b($b);
                    254:         ?>
                    255: 
                    256:       These class type hints are not checked upon compilation, as would
                    257:       be the case in a typed language, but during runtime.
                    258: 
                    259:       This means that
                    260: 
                    261:         function foo(ClassName $object) {
                    262:           // ...
                    263:         }
                    264: 
                    265:       is equivalent to
                    266: 
                    267:         function foo($object) {
                    268:           if (!($object instanceof ClassName)) {
                    269:             die('Argument 1 must be an instance of ClassName');
                    270:           }
                    271:         }
                    272: 
                    273:       This syntax only applies to objects/classes, not built-in types.
                    274: 
                    275:     * Final methods and classes.
                    276: 
                    277:       The Zend Engine 2.0 introduces the "final" keyword to declare
                    278:       final methods. Those cannot be overridden by sub-classes.
                    279: 
                    280:       Example:
                    281: 
                    282:         <?php
                    283:         class Foo {
                    284:           final function bar() {
                    285:             // ...
                    286:           }
                    287:         }
                    288:         ?>
                    289: 
                    290:       It is furthermore possible to make a class final. Doing this
                    291:       prevents a class from being specialized (it cannot be inherited
                    292:       by another class). There's no need to declare the methods of
                    293:       a final class themselves as final.
                    294: 
                    295:       Example:
                    296: 
                    297:         <?php
                    298:          final class Foo {
                    299:           // class definition
                    300:         }
                    301:         // the next line is impossible
                    302:         // class Bork extends Foo {}
                    303:         ?>
                    304: 
                    305:       Properties cannot be final. See per-class constants below.
                    306: 
                    307:       Old code that has no user-defined classes or functions named
                    308:       'final' should run without modifications.
                    309: 
                    310:     * Object Cloning.
                    311: 
                    312:       The Zend Engine 1.0 offered no way a user could decide what copy
                    313:       constructor to run when an object is duplicated. During
                    314:       duplication, the Zend Engine 1.0 did a bitwise copy making an
                    315:       identical replica of all the object's properties.
                    316: 
                    317:       Creating a copy of an object with fully replicated properties is
                    318:       not always the wanted behavior. A good example of the need for
                    319:       copy constructors, is if you have an object which represents a
                    320:       GTK window and the object holds the resource of this GTK window,
                    321:       when you create a duplicate you might want to create a new
                    322:       window with the same properties and have the new object hold the
                    323:       resource of the new window. Another example is if your object
                    324:       holds a reference to another object which it uses and when you
                    325:       replicate the parent object you want to create a new instance of
                    326:       this other object so that the replica has its own separate copy.
                    327: 
                    328:       An object copy is created by using the clone operator.
                    329: 
                    330:       Example:
                    331: 
                    332:         <?php
                    333:         $copy_of_object = clone $object;
                    334:         ?>
                    335: 
                    336:       When the developer asks to create a new copy of an object, the
                    337:       Zend Engine will check if a __clone() method has been defined or
                    338:       not. If not, it will call a default __clone() which will copy
                    339:       all of the object's properties. If a __clone() method is
                    340:       defined, then it will be responsible to set the necessary
                    341:       properties in the created object. For convenience, the engine
                    342:       ensures, that the clone will be initialized with all of the
                    343:       properties from the source object, so that developers can start
                    344:       with a by-value replica of the source object, and only override
                    345:       properties that need to be changed.
                    346: 
                    347:       Example:
                    348:         <?php
                    349:         class MyCloneable {
                    350:           static $id = 0;
                    351: 
                    352:           function MyCloneable() {
                    353:             $this->id = self::$id++;
                    354:           }
                    355: 
                    356:           function __clone() {
                    357:             $this->address = 'New York';
                    358:             $this->id = self::$id++;
                    359:           }
                    360:         }
                    361: 
                    362:         $obj = new MyCloneable();
                    363: 
                    364:         $obj->name = 'Hello';
                    365:         $obj->address = 'Tel-Aviv';
                    366: 
                    367:         $obj_clone = clone $obj;
                    368: 
                    369:         print $obj->id . "\n";
                    370:         print $obj->name . "\n";
                    371:         print $obj->address . "\n";
                    372: 
                    373:         print $obj_clone->id . "\n";
                    374:         print $obj_clone->name . "\n";
                    375:         print $obj_clone->address . "\n";
                    376:         ?>
                    377: 
                    378:     * Unified Constructors.
                    379: 
                    380:       The Zend Engine allows developers to declare constructor methods
                    381:       for classes. Classes which have a constructor method call this
                    382:       method on each newly-created object, so it is suitable for any
                    383:       initialization that the object may need before it can be used.
                    384: 
                    385:       With the Zend Engine 1.0, constructor methods were class methods
                    386:       that had the same name as the class itself. Since it is very
                    387:       common to call parent constructors from derived classes, the way
                    388:       the Zend Engine 1.0 worked made it a bit cumbersome to move
                    389:       classes around in a large class hierarchy. If a class is moved
                    390:       to reside under a different parent, the constructor name of that
                    391:       parent changes as well, and the code in the derived class that
                    392:       calls the parent constructor has to be modified.
                    393: 
                    394:       The Zend Engine 2.0 introduces a standard way of declaring
                    395:       constructor methods by calling them by the name __construct().
                    396: 
                    397:       Example:
                    398: 
                    399:         <?php
                    400:         class BaseClass {
                    401:             function __construct() {
                    402:                 print "In BaseClass constructor\n";
                    403:             }
                    404:         }
                    405: 
                    406:         class SubClass extends BaseClass {
                    407:             function __construct() {
                    408:                 parent::__construct();
                    409:                 print "In SubClass constructor\n";
                    410:             }
                    411:         }
                    412: 
                    413:         $obj = new BaseClass();
                    414:         $obj = new SubClass();
                    415:         ?>
                    416: 
                    417:       For backwards compatibility, if the Zend Engine 2.0 cannot find
                    418:       a __construct() function for a given class, it will search for
                    419:       the old-style constructor function, by the name of the class.
                    420:       Effectively, it means that the only case that would have
                    421:       compatibility issues is if the class had a method named
                    422:       __construct() which was used for different semantics.
                    423: 
                    424:     * Destructors.
                    425: 
                    426:       Having the ability to define destructors for objects can be very
                    427:       useful. Destructors can log messages for debugging, close
                    428:       database connections and do other clean-up work.
                    429: 
                    430:       No mechanism for object destructors existed in the Zend Engine
                    431:       1.0, although PHP had already support for registering functions
                    432:       which should be run on request shutdown.
                    433: 
                    434:       The Zend Engine 2.0 introduces a destructor concept similar to
                    435:       that of other object-oriented languages, such as Java: When the
                    436:       last reference to an object is destroyed the object's
                    437:       destructor, which is a class method name __destruct() that
                    438:       recieves no parameters, is called before the object is freed
                    439:       from memory.
                    440: 
                    441:       Example:
                    442: 
                    443:         <?php
                    444:         class MyDestructableClass {
                    445:             function __construct() {
                    446:                 print "In constructor\n";
                    447:                 $this->name = 'MyDestructableClass';
                    448:             }
                    449: 
                    450:             function __destruct() {
                    451:                 print 'Destroying ' . $this->name . "\n";
                    452:             }
                    453:         }
                    454: 
                    455:         $obj = new MyDestructableClass();
                    456:         ?>
                    457: 
                    458:       Like constructors, parent destructors will not be called
                    459:       implicitly by the engine. In order to run a parent destructor,
                    460:       one would have to explicitly call parent::__destruct() in the
                    461:       destructor body.
                    462: 
                    463:     * Constants.
                    464: 
                    465:       The Zend Engine 2.0 introduces per-class constants.
                    466: 
                    467:       Example:
                    468: 
                    469:         <?php
                    470:         class Foo {
                    471:             const constant = 'constant';
                    472:         }
                    473: 
                    474:         echo 'Foo::constant = ' . Foo::constant . "\n";
                    475:         ?>
                    476: 
                    477:       Old code that has no user-defined classes or functions
                    478:       named 'const' will run without modifications.
                    479: 
                    480:     * Exceptions.
                    481: 
                    482:       The Zend Engine 1.0 had no exception handling. The Zend Engine 2.0
                    483:       introduces a exception model similar to that of other programming
                    484:       languages. But there is no catch all and no finally clause.
                    485: 
                    486:       Old code that has no user-defined classes or functions 'catch',
                    487:       'throw' and 'try' will run without modifications.
                    488: 
                    489:       Exceptions can be rethrown in catch blocks. Also it is possible to
                    490:       have multiple catch blocks. In that case the caught exception is
                    491:       compared with the classtype of each catch block from top to bottom
                    492:       and the first block that has a 'instanceof' match gets executed.
                    493:       When the catch block finishes execution continues at the end of
                    494:       the last catch block. If no catch block has a 'instanceof' match
                    495:       then the next try/catch block is searched until no more try/catch
                    496:       blocks are available. In that case the exception is an uncaught
                    497:       exception and the program terminates with showing the exception.
                    498: 
                    499:       Example:
                    500: 
                    501:         <?php
                    502:         class MyException {
                    503:             function __construct($exception) {
                    504:                 $this->exception = $exception;
                    505:             }
                    506: 
                    507:             function Display() {
                    508:                 print "MyException: $this->exception\n";
                    509:             }
                    510:         }
                    511: 
                    512:         class MyExceptionFoo extends MyException {
                    513:             function __construct($exception) {
                    514:                 $this->exception = $exception;
                    515:             }
                    516: 
                    517:             function Display() {
                    518:                 print "MyException: $this->exception\n";
                    519:             }
                    520:         }
                    521: 
                    522:         try {
                    523:             throw new MyExceptionFoo('Hello');
                    524:         }
                    525:         catch (MyException $exception) {
                    526:             $exception->Display();
                    527:         }
                    528:         catch (Exception $exception) {
                    529:             echo $exception;
                    530:         }
                    531:         ?>
                    532: 
                    533:       Even though the above example shows that it is possible to define
                    534:       exception classes  that don't inherit from Exception it is best to
                    535:       do so. This is because the internal Exception class can gather a
                    536:       lot of information otherwise not available. The PHP code emulation
                    537:       code would look something like shown below. The comments show the
                    538:       meaning of each property. As the code shows it is possible to read
                    539:       any available information by using the getter methods. But since
                    540:       some of the methods are used internally they are marked final. All
                    541:       in all the class is very restrictive because it must be ensured
                    542:       that anything used internally always  works as expected.
                    543: 
                    544:       Emulating class Exception:
                    545: 
                    546:         <?php
                    547:         class Exception {
                    548:           function __construct(/*string*/ $message=NULL, /*int*/ $code=0) {
                    549:             if (func_num_args()) {
                    550:               $this->message = $message;
                    551:             }
                    552:             $this->code = $code;
                    553:             $this->file = __FILE__; // of throw clause
                    554:             $this->line = __LINE__; // of throw clause
                    555:             $this->trace = debug_backtrace();
                    556:             $this->string = StringFormat($this);
                    557:           }
                    558: 
                    559:           protected $message = 'Unknown exception';  // exception message
                    560:           protected $code = 0; // user defined exception code
                    561:           protected $file;     // source filename of exception
                    562:           protected $line;     // source line of exception
                    563: 
                    564:           private $trace;      // backtrace of exception
                    565:           private $string;     // internal only!!
                    566: 
                    567:           final function getMessage() {
                    568:             return $this->message;
                    569:           }
                    570:           final function getCode() {
                    571:             return $this->code;
                    572:           }
                    573:           final function getFile() {
                    574:             return $this->file;
                    575:           }
                    576:           final function getTrace() {
                    577:             return $this->trace;
                    578:           }
                    579:           final function getTraceAsString() {
                    580:             return self::TraceFormat($this);
                    581:           }
                    582:           function _toString() {
                    583:             return $this->string;
                    584:           }
                    585:           static private function StringFormat(Exception $exception) {
                    586:             // ... a function not available in PHP scripts
                    587:             // that returns all relevant information as a string
                    588:           }
                    589:           static private function TraceFormat(Exception $exception) {
                    590:             // ... a function not available in PHP scripts
                    591:             // that returns the backtrace as a string
                    592:           }
                    593:         }
                    594:         ?>
                    595: 
                    596:       If you derive your exception classes from this Exception base class
                    597:       your exceptions will be nicely shown in the builtin handler for
                    598:       uncaught exceptions.
                    599: 
                    600:       Note: The method getMessage() is a final read only access method to
                    601:       the private proeprty message that is set in the constructor. If you
                    602:       feel a need to overwrite the exception display then overload method
                    603:       __toString() in your derived class or implement your own extneral
                    604:       exception display function to accomplish your desired formatting.
                    605: 
                    606:       Example:
                    607: 
                    608:       <?php
                    609:       function display_exception(Exception $ex)
                    610:       {
                    611:           echo 'Exception: ' . $ex->getMessage() . 'with backtrace: <pre>';
                    612:           echo $ex->getTrace();
                    613:           echo '</pre>';
                    614:       }
                    615: 
                    616:       try
                    617:       {
                    618:           // your code here
                    619:       }
                    620:       catch (Exception $ex)
                    621:       {
                    622:           display_exeption($ex);
                    623:       }
                    624:       ?>
                    625: 
                    626:     * Dereferencing objects returned from functions.
                    627: 
                    628:       Example:
                    629: 
                    630:         <?php
                    631:         class Circle {
                    632:             function draw() {
                    633:                 print "Circle\n";
                    634:             }
                    635:         }
                    636: 
                    637:         class Square {
                    638:             function draw() {
                    639:                 print "Square\n";
                    640:             }
                    641:         }
                    642: 
                    643:         function ShapeFactoryMethod($shape) {
                    644:             switch ($shape) {
                    645:                 case 'Circle': return new Circle();
                    646:                 case 'Square': return new Square();
                    647:             }
                    648:         }
                    649: 
                    650:         ShapeFactoryMethod('Circle')->draw();
                    651:         ShapeFactoryMethod('Square')->draw();
                    652:         ?>
                    653: 
                    654:     * Member variables of classes can now be initialized.
                    655: 
                    656:       Example:
                    657: 
                    658:         <?php
                    659:         class foo {
                    660:             static $my_static = 5;
                    661:             public $my_prop = 'bla';
                    662:         }
                    663: 
                    664:         print foo::$my_static;
                    665: 
                    666:         $obj = foo;
                    667: 
                    668:         print $obj->my_prop;
                    669:         ?>
                    670: 
                    671:     * Static Methods.
                    672: 
                    673:       The Zend Engine 2.0 introduces the 'static' keyword to declare
                    674:       a method static, thus callable from outside the object context.
                    675: 
                    676:       Example:
                    677: 
                    678:         <?php
                    679:         class Foo {
                    680:           public static function aStaticMethod() {
                    681:             // ...
                    682:           }
                    683:         }
                    684: 
                    685:         Foo::aStaticMethod();
                    686:         ?>
                    687: 
                    688:       The pseudo variable $this is not available inside a method that
                    689:       has been declared static.
                    690: 
                    691:     * instanceof.
                    692:       New support for an instanceof operator which checks if an object
                    693:       is of a certain class or interface type.
                    694: 
                    695:       Example:
                    696: 
                    697:       <?php
                    698: 
                    699:       class Foo {
                    700:       }
                    701: 
                    702:       $obj = new Foo();
                    703:       if ($obj instanceof Foo) {
                    704:         print "Yay!\n";
                    705:       }
                    706:       ?>
                    707: 
                    708:     * Parameters that are passed by reference to a function
                    709:       may now have default values.
                    710: 
                    711:       Example:
                    712: 
                    713:         <?php
                    714:         function my_function(&$var = null) {
                    715:              if ($var === null) {
                    716:                  die('$var needs to have a value');
                    717:              }
                    718:         }
                    719:         ?>
                    720: 
                    721:     * __autoload().
                    722: 
                    723:       The __autoload() interceptor function will be automatically called
                    724:       when an undeclared class is to be instantiated. The name of that
                    725:       class will be passed to the __autoload() interceptor function as its
                    726:       only argument. __autoload() must succeed in loading the class. If it
                    727:       doesn't then an E_ERROR is emitted.
                    728: 
                    729:       Example:
                    730: 
                    731:         <?php
                    732:         function __autoload($className) {
                    733:           include_once $className . '.php';
                    734:         }
                    735: 
                    736:         $object = new ClassName;
                    737:         ?>
                    738: 
                    739:     * Method calls and property accesses can be overloaded
                    740:       by class methods  __call(), __get() and __set().
                    741: 
                    742:       __get() and __set() Example:
                    743: 
                    744:         <?php
                    745:             class Setter {
                    746:                 public $n;
                    747:                 public $x = array('a' => 1, 'b' => 2, 'c' => 3);
                    748: 
                    749:                 function __get($nm) {
                    750:                     print "Getting [$nm]\n";
                    751: 
                    752:                     if(isset($this->x[$nm])) {
                    753:                         $r = $this->x[$nm];
                    754:                         print "Returning: $r\n";
                    755:                         return $r;
                    756:                     } else {
                    757:                         print "Nothing!\n";
                    758:                     }
                    759:                 }
                    760: 
                    761:                 function __set($nm, $val) {
                    762:                     print "Setting [$nm] to $val\n";
                    763: 
                    764:                     if(isset($this->x[$nm])) {
                    765:                         $this->x[$nm] = $val;
                    766:                         print "OK!\n";
                    767:                     } else {
                    768:                         print "Not OK!\n";
                    769:                     }
                    770:                 }
                    771:             }
                    772: 
                    773:             $foo = new Setter();
                    774:             $foo->n = 1;
                    775:             $foo->a = 100;
                    776:             $foo->a++;
                    777:             $foo->z++;
                    778:             var_dump($foo);
                    779:         ?>
                    780: 
                    781:       __call() Example:
                    782: 
                    783:         <?php
                    784:             class Caller {
                    785:                 var $x = array(1, 2, 3);
                    786: 
                    787:                 function __call($m, $a) {
                    788:                      print "Method $m called:\n";
                    789:                      var_dump($a);
                    790:                      return $this->x;
                    791:                 }
                    792:             }
                    793: 
                    794:             $foo = new Caller();
                    795:             $a = $foo->test(1, '2', 3.4, true);
                    796:             var_dump($a);
                    797:         ?>
                    798: 
                    799:     * Iteration
                    800: 
                    801:       Objects may be iterated in an overloaded way when used with
                    802:       foreach. The default behavior is to iterate over all properties
                    803:       with respect to property visibility.
                    804: 
                    805:       Example:
                    806: 
                    807:         <?php
                    808:             class Foo {
                    809:                 var $x = 1;
                    810:                 var $y = 2;
                    811:             }
                    812: 
                    813:             $obj = new Foo;
                    814: 
                    815:             foreach ($obj as $prp_name => $prop_value) {
                    816:                 // using the property
                    817:             }
                    818:         ?>
                    819: 
                    820:       Each class whose instances can be iterated with foreach should
                    821:       implement the empty interface 'Traversable'. Hence any object
                    822:       that says it implements 'Traversable' can be used with foreach.
                    823: 
                    824:       The interfaces 'IteratorAggregate' and 'Iterator' allow to specify
                    825:       how class objects are iterated in PHP code. The first of them simply
                    826:       has a method 'getIterator' which must return an object that either
                    827:       implements the interface 'Iterator' or is instantiated from an
                    828:       internal class that can be iterated.
                    829: 
                    830:       Example:
                    831: 
                    832:         <?php
                    833:             class ObjectIterator implements Iterator {
                    834: 
                    835:                 private $obj;
                    836:                 private $num;
                    837: 
                    838:                 function __construct($obj) {
                    839:                     $this->obj = $obj;
                    840:                 }
                    841:                 function rewind() {
                    842:                     $this->num = 0;
                    843:                 }
                    844:                 function valid() {
                    845:                     return $this->num < $this->obj->max;
                    846:                 }
                    847:                 function key() {
                    848:                     return $this->num;
                    849:                 }
                    850:                 function current() {
                    851:                     switch($this->num) {
                    852:                         case 0: return "1st";
                    853:                         case 1: return "2nd";
                    854:                         case 2: return "3rd";
                    855:                         default: return $this->num."th";
                    856:                     }
                    857:                 }
                    858:                 function next() {
                    859:                     $this->num++;
                    860:                 }
                    861:             }
                    862: 
                    863:             class Object implements IteratorAggregate {
                    864: 
                    865:                 public $max = 3;
                    866: 
                    867:                 function getIterator() {
                    868:                     return new ObjectIterator($this);
                    869:                 }
                    870:             }
                    871: 
                    872:             $obj = new Object;
                    873: 
                    874:             // this foreach ...
                    875:             foreach($obj as $key => $val) {
                    876:                 echo "$key = $val\n";
                    877:             }
                    878: 
                    879:             // matches the following 7 lines with the for directive.
                    880:             $it = $obj->getIterator();
                    881:             for($it->rewind(); $it->valid(); $it->next()) {
                    882:                 $key = $it->key();
                    883:                 $val = $it->current();
                    884:                 echo "$key = $val\n";
                    885:             }
                    886:             unset($it);
                    887:         ?>
                    888: 
                    889:       The matching for directive is very intersting here since it shows
                    890:       the use of all abstract methods declared in the interfaces Iterator
                    891:       and IteratorAggregate respectively.
                    892: 
                    893:     * Array overloading
                    894:     
                    895:       Objects can be used with Array notation when they implement the 
                    896:       interface ArrayAccess. You cannot use such objects in standard
                    897:       array functions, however you have full control over the array
                    898:       notation. This allows lazy initialization or read only array.
                    899:       
                    900:       Note that setting [] results in a call to offsetSet() with
                    901:       index being NULL. That means that as with standard arrays you 
                    902:       cannot store NULL keys.
                    903:       
                    904:       Example:
                    905:       
                    906:         <?php
                    907:                class ArrayClass implements ArrayAccess {
                    908:                                public $a = array();
                    909:                        
                    910:                                function offsetExists($index) {
                    911:                                        return array_key_exists($index, $this->a);
                    912:                                }
                    913:                                function offsetGet($index) {
                    914:                                        return $this->a[$index];
                    915:                                }
                    916:                                function offsetSet($index, $newval) {
                    917:                                        return $this->a[$index] = $newval;
                    918:                                }
                    919:                                function offsetUnset($index) {
                    920:                                        unset($this->a[$index]);
                    921:                                }
                    922:                        }
                    923:                        
                    924:                        $obj = new ArrayClass;
                    925:                        
                    926:                        $obj[0] = 'bla';     // calls offsetSet(0,'bla')
                    927:                        $obj[] = 42;         // calls offsetSet(NULL, 42)
                    928:                        $x = $obj[0];        // calls offsetGet(0)
                    929:                        $b = isset($obj[0]); // calls offsetExists(0)
                    930:                        unset($obj[0]);      // calls offsetUnset(0)
                    931:                ?>
                    932:  
                    933: 
                    934:     * __METHOD__
                    935: 
                    936:       The pseudo constant __METHOD__ shows the current class and method
                    937:       when used inside a method and the function when used outside of a
                    938:       class.
                    939: 
                    940:       Example:
                    941: 
                    942:         <?php
                    943:             class Foo {
                    944:                 function Show() {
                    945:                     echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__;
                    946:                 }
                    947:             }
                    948:             function Test() {
                    949:                 echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__;
                    950:             }
                    951:         ?>
                    952: 
                    953:     * __toString()
                    954: 
                    955:       The magic method __toString() allows to overload the object to
                    956:       string conversion. This conversion is only done automatically for
                    957:       the printing functions (echo, print) but not for other functions
                    958:       that expect strings. Also the function __toString is not used in
                    959:       places where objects are not allowed but strings are like array
                    960:       indices. Note that specialized objects may be converted to a string
                    961:       in any place but without calling __toString().
                    962: 
                    963:       Example:
                    964: 
                    965:         <?php
                    966:             class Foo {
                    967:                 function __toString() {
                    968:                     return "What ever";
                    969:                 }
                    970:             }
                    971: 
                    972:             $obj = new Foo;
                    973:             
                    974:             $str = (string) $obj; // call __toString()
                    975:             
                    976:             echo $obj; // call __toString()
                    977:             
                    978:             $ar = array();
                    979:             $ar[(string)$obj]; // this works
                    980:             $ar[$obj];         // this is not allowed
                    981:         ?>
                    982: 
                    983:     * Reflection API
                    984: 
                    985:       PHP 5 comes with a complete Reflection API that adds the ability to
                    986:       reverse-engineer classes, interfaces, functions and methods as well
                    987:       as extensions.
                    988: 
                    989:       The Reflection API also offers ways of getting doc comments for
                    990:       functions, classes and methods.
                    991: 
                    992:       Nearly all aspects of object oriented code can be reflected by
                    993:       using the Reflection API which is documented separately:
                    994:       http://sitten-polizei.de/php/reflection_api/docs/language.reflection.html
                    995: 
                    996:       Example:
                    997: 
                    998:         <?php
                    999:             class Foo {
                   1000:                 public $prop;
                   1001:                 function Func($name) {
                   1002:                     echo "Hello $name";
                   1003:                 }
                   1004:             }
                   1005: 
                   1006:             ReflectionClass::export('Foo');
                   1007:             ReflectionObject::export(new Foo);
                   1008:             ReflectionMethod::export('Foo', 'func');
                   1009:             ReflectionProperty::export('Foo', 'prop');
                   1010:             ReflectionExtension::export('standard');
                   1011:         ?>
                   1012: 
                   1013:     * New memory manager
                   1014:       The Zend Engine has a new memory manager which allows it to run efficiently
                   1015:       in multi-threaded environments as it doesn't need to use mutexes to lock
                   1016:       and unlock during allocation/deallocation.
                   1017: 
                   1018:     * Others
                   1019:       Probably other changes which we forgot to list. This list will be kept up-to-date
                   1020:       as much as possible.
                   1021: 
                   1022: 
                   1023: Changes in the Zend Engine 1.0
                   1024: 
                   1025:   The Zend Engine was designed from the ground up for increased speed,
                   1026:   reduced memory consumption and more reliable execution. We dare say
                   1027:   it meets all of these goals and does so pretty well. Beyond that,
                   1028:   there are several improvements in the language engine features:
                   1029: 
                   1030:     * References support.
                   1031: 
                   1032:       $foo = &$a; would make $foo and $a be two names to the same
                   1033:       variable. This works with arrays as well, on either side; e.g.,
                   1034:       $foo = &$a[7]; would make $foo and $a[7] be two names to the
                   1035:       same variable. Changing one would change the other and vice
                   1036:       versa.
                   1037: 
                   1038:     * Object overloading support.
                   1039: 
                   1040:       This feature allows various OO libraries to use the OO notation
                   1041:       of PHP to access their functionality. Right now, no use is made
                   1042:       of that feature, but we'd have a COM module ready by the time
                   1043:       PHP 4.0 is released. A CORBA module would probably follow.
                   1044: 
                   1045:     * include() and eval() are now functions, and not statements.
                   1046: 
                   1047:       That means they return a value. The default return value from
                   1048:       include() and eval() is 1, so that you can do if (include())
                   1049:       without further coding. The return value may be changed by
                   1050:       returning a value from the global scope of the included file or
                   1051:       the evaluated string. For example, if 'return 7;' is executed in
                   1052:       the global scope of foo.inc, include('foo.inc') would evaluate
                   1053:       to 7.
                   1054: 
                   1055:     * Automatic resource deallocation.
                   1056: 
                   1057:       Several people have been bitten by the fact that PHP 3.0 had no
                   1058:       concept of reference counting. The Zend Engine adds full
                   1059:       reference counting for every value in the system, including
                   1060:       resources. As soon as a resource is no longer referenced from
                   1061:       any variable, it is automatically destroyed to save memory and
                   1062:       resources. The most obvious example for the advantage in this is
                   1063:       a loop that has an SQL query inside it, something like '$result
                   1064:       = sql_query(...);'. In PHP 3.0, every iteration resulted in
                   1065:       another SQL result-set allocated in the memory, and all of the
                   1066:       result sets weren't destroyed until the end of the script's
                   1067:       execution. With the Zend Engine, as soon as we overwrite an old
                   1068:       result set with a new one, the old result set which is no longer
                   1069:       referenced, is destroyed.
                   1070: 
                   1071:     * Full support for nesting arrays and objects within each other,
                   1072:       in as many levels as you want.
                   1073: 
                   1074:     * true and false are now constants of type boolean.
                   1075: 
                   1076:       Comparing any other value to them would convert that value to a
                   1077:       boolean first, and conduct the comparison later. That means, for
                   1078:       example, that 5==true would evaluate to true (in PHP 3.0, true
                   1079:       was nothing but a constant for the integer value of 1, so
                   1080:       5==true was identical to 5==1, which was false).
                   1081: 
                   1082:     * Runtime binding of function names.
                   1083: 
                   1084:       This complex name has a simple explanation - you can now call
                   1085:       functions before they're declared!
                   1086: 
                   1087:     * Added here-docs support.
                   1088: 
                   1089:     * Added foreach.
                   1090: 
                   1091:       Two syntaxes supported:
                   1092: 
                   1093:         foreach(array_expr as $val) statement
                   1094:         foreach(array_expr as $key => $val) statement
                   1095: 
                   1096:     * A true unset() implementation.
                   1097: 
                   1098:       A variable or element that is unset(), is now sent to oblivion
                   1099:       in its entirely, no trace remains from it.
                   1100: 
                   1101:     * Output buffering support.
                   1102: 
                   1103:       Use ob_start() to begin output buffering, ob_end_flush() to end
                   1104:       buffering and send out the buffered contents, ob_end_clean() to
                   1105:       end buffering without sending the buffered contents, and
                   1106:       ob_get_contents() to retreive the current contents of the output
                   1107:       buffer. Header information (header(), content type, cookies) are
                   1108:       not buffered. By turning on output buffering, you can
                   1109:       effectively send header information all throughout your file,
                   1110:       regardless of whether you've emitted body output or not.
                   1111: 
                   1112:     * Full variable reference within quoted strings:
                   1113: 
                   1114:         ${expr}    - full indirect reference support for scalar
                   1115:                      variables
                   1116:         {variable} - full variable support
                   1117: 
                   1118:         For example:
                   1119: 
                   1120:           $foo[5]['bar'] = 'foobar';
                   1121:           print "{$foo[5]["bar"]}";  // would print "foobar"
                   1122: 
                   1123:     * Ability to call member functions of other classes from within
                   1124:       member functions or from the global scope.
                   1125: 
                   1126:       You can now, for example, override a parent function with a
                   1127:       child function, and call the parent function from it.
                   1128: 
                   1129:     * Runtime information for classes (class name, parent, available
                   1130:       functions, etc.).
                   1131: 
                   1132:     * Much more efficient syntax highlighter - runs much quicker,
                   1133:       performs more reliably, and generates much tighter HTML.
                   1134: 
                   1135:     * A full-featured debugger has been integrated with the language
                   1136:       (supports breakpoints, expression evaluation, step-in/over,
                   1137:       function call backtrace, and more).
                   1138: 
                   1139:   The Zend Engine claims 100% compatability with the engine of PHP
                   1140:   3.0, and is shamelessly lying about it. Here's why:
                   1141: 
                   1142:     * Static variable initializers only accept scalar values
                   1143:       (in PHP 3.0 they accepted any valid expression). The impact
                   1144:       should be somewhere in between void and non existent, since
                   1145:       initializing a static variable with anything but a simple
                   1146:       static value makes no sense at all.
                   1147: 
                   1148:     * The scope of break and continue is local to that of an
                   1149:       include()'d file or an eval()'d string. The impact should
                   1150:       be somewhat smaller of the one above.
                   1151: 
                   1152:     * The return statement no longer works from a require()'d file. It
                   1153:       hardly worked in PHP 3.0, so the impact should be fairly small. If
                   1154:       you want this functionality - use include() instead.
                   1155: 
                   1156:     * unset() is no longer a function, but a statement.
                   1157: 
                   1158:     * The following letter combination is not supported within
                   1159:       encapsulated strings:  "{$".  If you have a string that includes
                   1160:       this letter combination, for example, print "{$somevar"; (which
                   1161:       printed the letter { and the contents of the variable $somevar in
                   1162:       PHP 3.0), it will result in a parse error with the Zend Engine.
                   1163:       In this case, you would have to change the code to print
                   1164:       "\{$somevar"; This incompatability is due to the full variable
                   1165:       reference within quoted strings feature added in the Zend
                   1166:       Engine.

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>