Annotation of embedaddon/php/Zend/ZEND_CHANGES, revision 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>