PHP5 new features: A more object-oriented php_php technique

Source: Internet
Author: User
Tags abstract class definition getmessage gtk reflection rewind throwable
The kernel of the object part of the PHP process has been completely redesigned to provide more functionality while improving performance. In previous versions of PHP, the same method of handling objects and processing basic types (numbers, strings) was used. The flaw in this approach is that when an object is assigned to a variable, or when an object is passed through a parameter, the object is completely copied. In the new version, the above operation will pass the reference (the reference can be interpreted as an object's identifier) rather than a value.





Many PHP programmers may not even be aware of the old object-handling style. In fact, most PHP applications can run well. Or just need a little change.





Private and protected members


PHP5 introduces the concept of private and protected member variables. We can use it to define the visibility of class members.





Example


Protected members can be accessed by the quilt class, while private members can only be accessed by the class itself.





<?php


Class MyClass {


Private $Hello = "Hello, world!\n";


protected $Bar = "Hello, foo!\n";


protected $Foo = "Hello, bar!\n";





function Printhello () {


Print "MyClass::p Rinthello ()". $this->hello;


Print "MyClass::p Rinthello ()". $this->bar;


Print "MyClass::p Rinthello ()". $this->foo;


}


}





Class MyClass2 extends MyClass {


protected $Foo;





function Printhello () {


MyClass::p Rinthello (); /* Should Print * *


Print "MyClass2::p Rinthello ()". $this->hello; /* shouldn ' t print out anything * *


Print "MyClass2::p Rinthello ()".  $this->bar; /* shouldn ' t print (not declared) * *


Print "MyClass2::p Rinthello ()".  $this->foo; /* Should Print * *


}


}





$obj = new MyClass ();


Print $obj->hello; /* shouldn ' t print out anything * *


Print $obj->bar; /* shouldn ' t print out anything * *


Print $obj->foo; /* shouldn ' t print out anything * *


$obj->printhello (); /* Should Print * *





$obj = new MyClass2 ();


Print $obj->hello; /* shouldn ' t print out anything * *


Print $obj->bar; /* shouldn ' t print out anything * *


Print $obj->foo; /* shouldn ' t print out anything * *


$obj->printhello ();


?>





Private methods and protected methods


PHP5 also introduces the concept of private methods and protected methods.





Example:


<?php


Class Foo {


Private Function Aprivatemethod () {


echo "Foo::aprivatemethod () called.\n";


}





protected function Aprotectedmethod () {


echo "Foo::aprotectedmethod () called.\n";


$this->aprivatemethod ();


}


}





Class Bar extends Foo {


Public Function Apublicmethod () {


echo "Bar::apublicmethod () called.\n";


$this->aprotectedmethod ();


}


}





$o = new Bar;


$o->apublicmethod ();


?>





Old code that does not use a class, and code that has no access modifiers (public, protected, private) can run without changes.





Abstract classes and abstract methods


PHP5 also introduces the concepts of abstract classes and abstract methods. The abstract method simply declares that the signature of the method does not provide its implementation. Classes that contain abstract methods must be declared as abstract classes.





Example:


<?php


Abstract class AbstractClass {


Abstract public Function test ();


}





Class Implementedclass extends AbstractClass {


Public Function test () {


echo "Implementedclass::test () called.\n";


}


}





$o = new Implementedclass;


$o->test ();


?>





Abstract classes cannot be instantiated. Old code that does not use abstract classes before can be run without change.





Interface


PHP5 introduces the interface. A class can implement multiple interfaces.





Example:


<?php


Interface Throwable {


Public function getMessage ();


}





Class MyException implements Throwable {


Public Function GetMessage () {


// ...


}


}


?>





Old code that does not use the interface can run without changes











Type hints for classes





PHP5 is still weakly typed, but when defining function arguments, you can use the type hint of the class to declare the type of object that you expect to pass in





Example


<?php


Interface Foo {


Function A (Foo $foo);


}





Interface Bar {


Function B (Bar $bar);


}





Class FooBar implements Foo, Bar {


Function A (Foo $foo) {


// ...


}





Function B (Bar $bar) {


// ...


}


}





$a = new FooBar;


$b = new FooBar;





$a->a ($b);


$a->b ($b);


?>





Like other strongly typed languages, type hints for php5 classes are checked during run time rather than during compilation. That





<?php


function foo (ClassName $object) {


// ...


}


?>





The following code is the same:





<?php


function foo ($object) {


if (!) ( $object instanceof ClassName)) {


Die ("Argument 1 must be a instance of ClassName");


}


}


?>





This syntax applies only to classes, not to builtin types.





Final





PHP 5 introduces the final keyword to declare the final member and final method. Final members and final methods cannot be overridden by a quilt class.





Example


<?php


Class Foo {


Final function bar () {


// ...


}


}


?>





Further, the class can be declared final. Declaring a class as final can prevent this class from being inherited. The methods in the final class are, by default, final, without having to declare them again.





Example


<?php


Final class Foo {


Class definition


}





The next line is impossible


Class Bork extends Foo {}


?>





Attribute cannot be defined as final.





Previous old code that did not use final could run without change.





Object cloning


PHP4 does not provide a mechanism for the user to define the replication process of the copy constructor (copy constructor) control object. PHP4 makes a binary copy, thus replicating all the attributes of the object with precision.





Copying all the attributes of an object in an exact way may not be what we always wanted. An example would be a good illustration of the fact that we do need to replicate constructs: for example, a GTK window object A. A holds all the resources it needs. When we copy this GTK window to object B, we prefer B to hold the new resource object. Let's take another example: Object A contains an object C, when you copy object A to object C. We might prefer that object B contain a new copy of Object C instead of a reference to object C. (Translator Note: This is the shallow cloning and deep cloning.) )





Object replication is achieved through the keyword clone (clone invokes the __clone () method of the cloned object). The __clone method of an object cannot be invoked directly.





<?php


$copy _of_object = Clone $object;


?>





When developer creates a copy of the object, PHP5 checks to see if the __clone () method exists. If it does not exist, it will call the default __clone () method and copy all the properties of the object. If the __clone () method has already been defined, the _clone () method is responsible for setting the properties of the new object. For convenience, engine replicates all properties by default. So in the __clone () method, you just need to overwrite the attributes that need to be changed. As follows:


Example


<?php


Class Mycloneable {


static $id = 0;





function mycloneable () {


$this->id = self:: $id + +;


}





function __clone () {


$this->address = "New York";


$this->id = self:: $id + +;


}


}





$obj = new Mycloneable ();





$obj->name = "Hello";


$obj->address = "Tel-aviv";





Print $obj->id. "\ n";





$obj _cloned = Clone $obj;





Print $obj _cloned->id. "\ n";


Print $obj _cloned->name. "\ n";


Print $obj _cloned->address. "\ n";


?>





Unified constructors


PHP5 allows developers to declare the construction method of a class. The class that owns the constructor will call this method every time a new object is created, so the constructor works well for the initialization of the object before it is used





PHP4, the name of the constructed method is the same as the name of the class. Considering that it is very common to call a parent-class constructor from a subclass constructor, and that the parent-class change caused by moving a class from an inheritance system often leads to the need to change the constructor method of the class, PHP4 's approach is obviously unreasonable.





PHP5 introduces a standard method of declaring a constructor: __construct (). as follows:





Example


<?php


Class BaseClass {


function __construct () {


Print "in BaseClass constructor\n";


}


}





Class Subclass extends BaseClass {


function __construct () {


Parent::__construct ();


Print "in subclass constructor\n";


}


}





$obj = new BaseClass ();


$obj = new Subclass ();


?>





To maintain backward compatibility, if PHP5 cannot find __construct (), it will look for old-fashioned constructs, that is, a method with the same name as a class. Simply put, a compatibility problem exists only when the old code contains a __construct () method.





destructor method


For object-oriented programming, the ability to define a destructor is a useful feature. The destructor can be used to record debugging information, to turn off database connections, and so on, and some cleanup finishing work. There is no destructor in Php4, although PHP4 has supported the option of registering a function to be invoked at the end of the request.





The concept of PHP5 introduced is consistent with other object-oriented languages such as Java. When the last reference to this object is destroyed, the destructor is invoked and the memory is freed after the call completes. Note: The destructor does not accept any parameters.





Example


<?php


Class Mydestructableclass {


function __construct () {


Print "in constructor\n";


$this->name = "Mydestructableclass";


}





function __destruct () {


Print "destroying". $this->name. "\ n";


}


}





$obj = new Mydestructableclass ();


?>





As with the build method, the destructor of the parent class is not implicitly invoked. Subclasses can call it explicitly by calling Parent::__destruct () in its own destructor.





Constants


PHP5 introduced a class-level constant.





<?php


Class Foo {


CONST CONSTANT = "constant";


}





echo "foo::constant =". Foo::constant. "\ n";


?>





Old code that doesn't use const still works.





Exceptions


PHP4 no exception control. PHP5 introduces an exception control pattern similar to other languages (Java). It should be noted that the PHP5 support captures all exceptions, but does not support finally clauses.





Inside the catch statement block, you can throw the exception again. You can also have more than one catch statement, in which case the caught exception is compared from top to bottom and the catch statement is compared to the exception, and the first type-matching catch statement will be executed. If you have been searching for a matching catch clause, find the next Try/catch statement. The last exception that cannot be caught will be displayed. If the exception is caught, the program then starts execution below the catch statement block.





Example


<?php


Class MyException {


function __construct ($exception) {


$this->exception = $exception;


}





function Display () {


Print "MyException: $this->exception\n";


}


}





Class Myexceptionfoo extends MyException {


function __construct ($exception) {


$this->exception = $exception;


}





function Display () {


Print "MyException: $this->exception\n";


}


}





try {


throw new Myexceptionfoo (' Hello ');


}


catch (MyException $exception) {


$exception->display ();


}


catch (Exception $exception) {


Echo $exception;


}


?>





The above example shows that you can define an exception class that does not inherit from exception, but it is best to inherit from exception and define your own exception. This is because the exception class built in the system can collect a lot of useful information, but not the exception class that does not inherit it. The following PHP code mimics the system-built exception class. Each attribute is followed by a comment. Each attribute has a getter, and these methods are marked final because these getter methods are often called internally by the system.





Example


<?php


Class Exception {


function __construct (string $message =null, int code=0) {


if (Func_num_args ()) {


$this->message = $message;


}


$this->code = $code;


$this->file = __file__; of throw clause


$this->line = __line__; of throw clause


$this->trace = Debug_backtrace ();


$this->string = StringFormat ($this);


}





protected $message = ' Unknown exception '; Exception message


protected $code = 0; User defined exception code


protected $file; SOURCE filename of exception


protected $line; Source line of exception





Private $trace; BackTrace of exception


Private $string; Internal only!!





Final function getMessage () {


return $this->message;


}


Final function GetCode () {


return $this->code;


}


Final function GetFile () {


return $this->file;


}


Final function Gettrace () {


return $this->trace;


}


Final function gettraceasstring () {


Return Self::traceformat ($this);


}


function _tostring () {


return $this->string;


}


Static Private Function StringFormat (Exception $exception) {


... a function not available in PHP scripts


That returns all relevant information as a string


}


Static Private Function Traceformat (Exception $exception) {


... a function not available in PHP scripts


That returns the BackTrace as a string


}


}


?>





If we define an exception class that inherits from the exception base class





No compatibility issues. Old code is not affected by this feature.





dereferencing objects returned from functions


Php4 can not refer again to the object returned by the function to call the method of returning the object further, and PHP5 is OK.





<?php


Class Circle {


function Draw () {


print "circle\n";


}


}





Class Square {


function Draw () {


print "square\n";


}


}





function Shapefactorymethod ($shape) {


Switch ($shape) {


Case "Circle":


return new Circle ();


Case "Square":


Return to New Square ();


}


}





Shapefactorymethod ("Circle")->draw ();


Shapefactorymethod ("Square")->draw ();


?>





Static member variables can be initialized.


Example


<?php


class Foo {


static $my _static = 5;


Public $my _prop = ' bla ';


}





Print foo:: $my _static;


$obj = new Foo;


Print $obj->my_prop;


?>





static method


PHP 5 introduces a static method that can call a static method without instantiating the class.





Example


<?php


Class Foo {


public static function Astaticmethod () {


// ...


}


}





Foo::astaticmethod ();


?>





Pseudo-variable $this cannot be used in static method methods.





instanceof


PHP5 introduces the instanceof keyword, allowing it to test that an object is an instance of a class, or an instance of a derived class, or implements an interface





Example


<?php


Class BaseClass {}





$a = new BaseClass;





if ($a instanceof BaseClass) {


echo "Hello World";


}


?>





Static function variables


Static variables are now processed in the compile phase. So programmers can assign values to static variables by referencing them. This can improve performance, however, it is not possible to use indirect references to static variables.





Function arguments passed by reference can now also set the default value.





Example


<?php


Function my_function (& $var = null) {


if ($var = = null) {


Die ("$var needs to have a value");


}


}


?>





__autoload ()


The __autoload () intercept function is invoked automatically when an undeclared class is initialized. The name of the class is automatically passed to the __autoload () function. and __autoload () has only such a single parameter.





Example


<?php


function __autoload ($className) {


Include_once $className. ". PHP";


}





$object = new ClassName;


?>





Overloaded method call and property access


Both method call and property access can be overloaded through the __call, __get () and __set () methods.





Example: __get () and __set ()


<?php


Class Setter {


Public $n;


Public $x = Array ("A" => 1, "B" => 2, "C" => 3);





function __get ($nm) {


print "Getting [$nm]\n";





if (Isset ($this->x[$nm])) {


$r = $this->x[$nm];


Print "Returning: $r \ n";


return $r;


} else {


print "nothing!\n";


}


}





function __set ($nm, $val) {


Print "Setting [$nm] to $val \ n";





if (Isset ($this->x[$nm])) {


$this->x[$nm] = $val;


print "ok!\n";


} else {


Print "Not ok!\n";


}


}


}





$foo = new Setter ();


$foo->n = 1;


$foo->a = 100;


$foo->a++;


$foo->z++;


Var_dump ($foo);


?>





Example: __call ()


<?php


Class Caller {


Private $x = Array (1, 2, 3);





function __call ($m, $a) {


Print "Method $m called:\n";


Var_dump ($a);


return $this->x;


}


}





$foo = new Caller ();


$a = $foo->test (1, "2", 3.4, true);


Var_dump ($a);


?>





Iterations


When you use objects with foreach, the iterative approach is overloaded. The default behavior is all of the properties of the iteration class.





Example


<?php


Class Foo {


public $x = 1;


Public $y = 2;


}





$obj = new Foo;





foreach ($obj as $PRP _name => $prop _value) {


Using the property


}


?>





All objects of a class can be browsed by iteration, if the class implements an empty interface: traversable. In other words, a class that implements the Traversable interface can be used with foreach.





Interfaces Iteratoraggregate and iterator allow you to specify how objects of a class are iterated in code. The Iteratoraggregate interface has a method: Getiterator () must return an array





Example


<?php


Class Objectiterator implements iterator {





Private $obj;


Private $num;





function __construct ($obj) {


$this->obj = $obj;


}


Function Rewind () {


$this->num = 0;


}


function valid () {


return $this->num < $this->obj->max;


}


Function key () {


return $this->num;


}


function current () {


Switch ($this->num) {


Case 0:return "1st";


Case 1:return "2nd";


Case 2:return "3rd";


Default:return $this->num. " TH ";


}


}


function Next () {


$this->num++;


}


}





Class Object implements Iteratoraggregate {





Public $max = 3;





function Getiterator () {


return new Objectiterator ($this);


}


}





$obj = new Object;





This foreach ...


foreach ($obj as $key => $val) {


echo "$key = $val \ n";


}





Matches the following 7 lines with the for directive.


$it = $obj->getiterator ();


For ($it->rewind (); $it->hasmore (); $it->next) {


$key = $it->current ();


$val = $it->key ();


echo "$key = $val \ n";


}


Unset ($it);


?>





The new __tostring method


You can control the conversion of an object to a string by overriding the __tostring method.





Example


<?php


Class Foo {


function __tostring () {


Return "What ever";


}


}





$obj = new Foo;





Echo $obj; Call __tostring ()


?>





Reflection API


PHP5 introduces a full set of reflection APIs to support reverse engineering of classes, interfaces, functions, and methods.





It also provides an API to extract the annotation document from the program. Detailed information of the Reflection API reference here: http://sitten-polizei.de/php/reflection_api/docs/language.reflection.html





Example


<?php


Class Foo {


Public $prop;


function Func ($name) {


echo "Hello $name";


}


}





Reflection_class::export (' Foo ');


Reflection_object::export (new Foo);


Reflection_method::export (' Foo ', ' func ');


Reflection_property::export (' Foo ', ' prop ');


Reflection_extension::export (' standard ');


?>





New memory management mechanism


PHP5 has a new memory management mechanism that allows it to run more efficiently in a multi-threaded environment. No mutex locking/unlocking is used when allocating and freeing memory


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.