ZEND_CHANGES 36 KB

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