`
wbj0110
  • 浏览: 1558392 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

PHP5新特性--更加面向对象化的PHP

阅读更多

PHP处理对象部分的内核完全重新开发过,提供更多功能的同时也提高了性能。在以前版本的php中,处理对象和处理基本类型(数字,字符串)的方式是一样的。这种方式的缺陷是:当将对象赋值给一个变量时,或者通过参数传递对象时,对象将被完全拷贝一份。在新的版本里,上述操作将传递引用(可以把引用理解成对象的标识符),而非值。 

很多PHP程序员可能甚至没有察觉到老的对象处理方式。事实上,大多数的php应用都可以很好地运行。或者仅仅需要很少的改动。 

私有和受保护成员 
PHP5引入了私有和受保护成员变量的概念。我们可以用它来定义类成员的可见性。 

例子 
受保护成员可以被子类访问, 而私有成员只能被类本身访问。 

<?php 
class MyClass { 
   private $Hello = "Hello, World!\n"; 
   protected $Bar = "Hello, Foo!\n"; 
   protected $Foo = "Hello, Bar!\n"; 

   function printHello() { 
       print "MyClass::printHello() " . $this->Hello; 
       print "MyClass::printHello() " . $this->Bar; 
       print "MyClass::printHello() " . $this->Foo; 
   } 


class MyClass2 extends MyClass { 
   protected $Foo; 

   function printHello() { 
       MyClass::printHello();                          /* Should print */ 
       print "MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */ 
       print "MyClass2::printHello() " . $this->Bar;  /* Shouldn't print (not declared)*/ 
       print "MyClass2::printHello() " . $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(); 
?>  

私有方法和受保护方法 
PHP5也引入了私有方法和受保护方法的概念。 

例子: 
<?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(); 
?>  

以前的不使用类的老代码,没有访问修饰符(public, protected, private)的代码可以不经改动运行。 

抽象类和抽象方法 
Php5也引入了抽象类和抽象方法的概念。抽象方法只是声明了方法的签名并不提供它的实现。包含抽象方法的类必须被声明成抽象类。 

例子: 
<?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(); 
?>  

抽象类不能被实例化。以前的不使用抽象类的老代码可以不经改动运行。 

接口 
Php5引入了接口。一个类可以实现多个接口。 

例子: 
<?php 
interface Throwable { 
   public function getMessage(); 


class MyException implements Throwable { 
   public function getMessage() { 
       // ... 
   } 

?>  

以前的不使用接口的老代码可以不经改动运行 

  

类的型别提示 

PHP5依然是弱类型的,不过在定义函数参数时,可以使用类的型别提示来声明期望传入的对象类型 

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); 
?>  

和其他强类型语言一样,php5类的型别提示在运行期间检查而非编译期间检查。即: 

<?php 
function foo(ClassName $object) { 
   // ... 

?>  

和下面的代码是一样的: 

<?php 
function foo($object) { 
   if (!($object instanceof ClassName)) { 
       die("Argument 1 must be an instance of ClassName"); 
   } 

?>  

这个语法只适用于类,不适用于内建类型。  

Final 

PHP 5 引入了final关键字来声明final成员和final方法。final成员和final方法不能被子类覆盖。 

Example 
<?php 
class Foo { 
   final function bar() { 
       // ... 
   } 

?>  

更进一步,可以把类声明成final。将类声明成final可以阻止这个类被继承。final类里面的方法缺省地都是final的,无需再声明一次。 

Example 
<?php 
final class Foo { 
   // class definition 


// the next line is impossible 
// class Bork extends Foo {} 
?>  

属性不能定义成为final. 

以前的不使用final的老代码可以不经改动运行. 

对象克隆 
Php4没有提供一种机制来让用户自己定义复制构造子(copy constructor)控制对象的复制过程。Php4做二进制的拷贝,因而很精确地复制了对象的所有属性。 

精确地复制对象的所有属性可能并不是我们一直想要的。有个例子可以很好地说明我们确实需要复制构造子:比如一个GTK Window的对象 a。 a持有它所需要的全部资源。当复制的这个GTK Window到对象b时候,我们更希望b持有新的资源对象。再举个例子:对象a包含了一个对象c, 当你把对象a 复制到对象c的时候。我们可能更希望对象b包含一个新的对象c的copy, 而不是一个对象c的引用。(译者注:这里所说的就是浅克隆和深克隆。) 

对象的复制是通过clone这个关键字达到的(Clone调用被克隆对象的__clone()方法)。对象的__clone方法不能够直接被调用。 

<?php 
$copy_of_object = clone $object; 
?>  

当developer创建对象的一份拷贝的时候,php5将会检查 __clone()方法是否存在。如果不存在,那么它就会呼叫缺省的__clone()方法,复制对象的所有属性。如果__clone()方法已经定义过,那么_clone()方法就会负责设置新对象的属性。为了方便起见,Engine会缺省地复制所有的属性。所以在__clone()方法中,只需要覆盖那些需要更改的属性就可以了。如下: 
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"; 
?>  

统一构造函数 
Php5允许开发者声明一个类的构造方法。拥有构造方法的类在每次创建新的对象的时候都会呼叫这个方法,因此构造方法适合对象在被使用之前的初始化工作 

Php4中,构造方法的名称和类的名称一样。考虑到从子类构造方法呼叫父类构造方法的情况是非常普遍的,而将类从一个继承体系中搬迁引起的父类变更就常常导致需要更改类的构造方法,php4的做法显然是不太合理的。 

Php5引入了一个声明构建函数的标准方法: __construct().如下: 

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(); 
?>  

为保持向后的兼容性,如果php5不能够找到 __construct(),它会寻找老式的构造方法,即与类同名的方法。简单的说,只有当老代码里包含了一个__construct()方法的时候,才存在一个兼容性的问题。 

析构方法 
对于面向对象的编程来说,可以定义析构方法是非常有用的一个功能。析构方法可以用来记录调试信息,关闭数据库连接等等一些清除收尾的工作。Php4中没有析构方法,尽管php4已经支持可以注册一个函数以便请求结束的时候被调用。 

Php5引进的析构方法的概念和其他面向对象的语言(比如java)是一致的。当指向这个对象的最后一个引用被销毁的时候,析构方法被调用,调用完成后释放内存。注意:析构方法不接受任何参数。 

Example 
<?php 
class MyDestructableClass { 
   function __construct() { 
       print "In constructor\n"; 
       $this->name = "MyDestructableClass"; 
   } 

   function __destruct() { 
       print "Destroying " . $this->name . "\n"; 
   } 


$obj = new MyDestructableClass(); 
?>  

和构建方法一样,父类的析构方法也不会被隐含调用。子类可以在自己的析构方法通过调用parent::__destruct()来显式地调用它。 

Constants 
Php5引入了class级别的常量。  

<?php 
class Foo { 
   const constant = "constant"; 


echo "Foo::constant = " . Foo::constant . "\n"; 
?>  

老的没有使用const的代码仍然正常运行。 

Exceptions 
Php4没有异常控制。Php5引入了和其它语言(java)相似的异常控制模式。应该注意的是php5里面支持捕捉全部异常,但是不支持finally子句。 

在catch语句块里面,可以重新抛出异常。也可以有多个catch语句,在这种情况下,被捕捉到的异常从上往下依次比较和catch语句比较异常,第一个类型匹配的catch语句将会被执行。如果一直搜索到底还没有发现匹配的catch子句,则寻找下一个try/catch语句。最后不能捕捉的异常将被显示出来。如果异常被捕捉,那么程序会接着catch语句块的下面开始执行。 

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; 

?>  

上面的例子表明可以定义一个并不继承自 Exception的异常类,但是,最好还是从Exception继承并定义自己的异常。这是因为系统内建的Exception类能够收集到很多有用的信息, 而不继承它的异常类是得不到这些信息的。下面的php代码模仿了系统内建Exception类。每个属性后面都加了注释。每个属性都有一个getter,由于这些getter方法经常被系统内部处理调用,所以这些方法被标明了final。 

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 
   } 

?>  

如果我们定义的一异常类都是继承自Exception基类 

无兼容性问题。老的代码不会受到这一特性的影响。 

Dereferencing objects returned from functions 
Php4中不能再次引用函数返回的对象以进一步呼叫返回对象的方法,而php5是可以的。 

<?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 new Square(); 
   } 


ShapeFactoryMethod("Circle")->draw(); 
ShapeFactoryMethod("Square")->draw(); 
?>  

静态成员变量能够被初始化。 
Example 
<?php 
class foo { 
   static $my_static = 5; 
   public $my_prop = 'bla'; 


print foo::$my_static; 
$obj = new foo; 
print $obj->my_prop; 
?>  

静态方法 
PHP 5 引入了静态方法,可以在不实例化类的情况下呼叫静态方法。 

Example 
<?php 
class Foo { 
   public static function aStaticMethod() { 
       // ... 
   } 


Foo::aStaticMethod(); 
?>  

伪变量$this不能够在静态方法方法中使用。 

instanceof 
Php5引入了instanceof关键字,允许用它来测试一个对象是一个类的实例,或者是一个派生类的实例,或者实现了某个接口 

Example 
<?php 
class baseClass { } 

$a = new baseClass; 

if ($a instanceof baseClass) { 
   echo "Hello World"; 

?>  

Static function variables 
现在,静态变量在编译阶段处理。因此程序员可以通过引用为静态变量赋值。这可以改善性能,不过,不能够使用对静态变量的间接引用了。 

按引用传递的函数参数现在也可以设置缺省值了。 

Example 
<?php 
function my_function(&$var = null) { 
   if ($var === null) { 
       die("$var needs to have a value"); 
   } 

?>  

__autoload() 
__autoload() 拦截函数在一个未声明的类被初始化的时候自动调用。该类的名字会被自动传递给__autoload()函数。而__autoload()也只有这么唯一的一个参数。 

Example 
<?php 
function __autoload($className) { 
   include_once $className . ".php"; 


$object = new ClassName; 
?>  

可重载的方法呼叫和属性访问 
方法呼叫和属性访问都能够通过__call, __get() and __set()方法重载。 

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); 
?>  

迭代 
当和foreach一起使用对象的时候,迭代的方式被重载过了。缺省的行为是迭代类的所有属性。 

Example 
<?php 
class Foo { 
   public $x = 1; 
   public $y = 2; 


$obj = new Foo; 

foreach ($obj as $prp_name => $prop_value) { 
   // using the property 

?>  

一个类的所有对象都能够被迭代浏览到, 如果这个类实现了一个空的接口:Traversable. 换句话说,实现了Traversable接口的类可以和foreach一起使用。 

接口 IteratorAggregate 和Iterator允许指定类的对象在代码中如何迭代。IteratorAggregate接口有一个方法:getIterator() 必须返回一个数组 

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); 
?>  

新的__toString方法 
可以通过覆盖__toString方法来控制对象到字符串的转换。 

Example 
<?php 
class Foo { 
   function __toString() { 
       return "What ever"; 
   } 


$obj = new Foo; 

echo $obj; // call __toString() 
?>  

Reflection API 
Php5引入了全套的反射API,以支持对类,接口,函数,方法的反向工程。 

它也提供了API以从程序中提取注释文档。反射API的详细资料参考此处: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'); 
?>  

新内存管理机制 
Php5有一个全新的内存管理机制,使得它在多线程的环境下可以更有效地运行。在分配和释放内存时,不再使用mutex锁定/解除锁定 

分享到:
评论

相关推荐

    PHP5面向对象(第三章_类特性)

    PHP5面向对象(第三章_类特性)http://www.imotaku.net/

    php5面向对象教程[实例详解]

    文件清单: php5 面向对象初步(第一章) ...PHP5面向对象(第三章 类特性) PHP5面向对象(第四章 接口与多态) ---- 需要code实例的,我会尽快上传 ---- 此教程适合基础不太稳的朋友,急需PHP基础的童鞋,老友可绕行!

    php面向对象详细教程(完整版)

    本教程详细阐述了PHP的面向对象特性,包括PHP5面向对象初步,PHP5面向对象进阶,PHP5面向对象高级类特性,PHP5接口与多态,PHP5面向对象异常处理等5个章节。内容丰富,实例清晰,并有相关PHP设计模式的详细实例和...

    深入PHP 面向对象 模式与实践第3版(完整版) 35M

    首先介绍了PHP的OO特性,包括类声明、对象实例化、继承、方法与属性封装以及静态方法与属性、抽象类、接口、异常处理、对象克隆等高级主题。然后介绍了设计模式,阐述了模式的概念,展示了如何在PHP中实现几个关键的...

    PHP面向对象高级编程和设计—面向对象高级编程和设计模式

    PHP 5重新设计了面向对象的模型,增加许多面向对象的特性。对于面向对象思想中的高级编程和面向对象中的设计模式,PHP 5都能够很好的实现。面向对象的程序设计不仅表现在程序的语法规则和语言特性上,更表现了设计...

    深入PHP面向对象、模式与实践 (第2版)》 part2

     第10章 让面向对象编程更加灵活的模式   第11章 执行及描述任务   第12章 企业模式   第13章 数据库模式  第四部分 实践  第14章 良好和糟糕的实践   第15章 PEAR   第16章 用 phpDocumentor...

    wms-github#PHP-NOTES#面向对象及其三大特性1

    面向对象及其三大特性目录封装继承多态什么是面向对象面向对象是把解决的问题按照一定规则划分成一个或多个对象, 然后通过调用对象的方法来解决问题面向过程是把解决的问

    PHP5面向对象开发教程第三章-PHP5面向对象高级类特性

    NULL 博文链接:https://llying.iteye.com/blog/335965

    php5面向对象

    最适合初学者` 详细的php5面向对象基础、面向对象进阶、面向对象高级类特性、php5的接口与多态。 保证下了不后悔。

    实验PHP面向对象

    1.熟练掌握PHP对象的创建 2.熟练掌握PHP构造函数 与析构造函数 3. 熟练掌握PHP中封装、继承多态特性 4. 接口的使用

    (全)传智播客PHP就业班视频完整课程

    9-7 4.static关键字(静态方法) 面向对象编程三大特性① 9-7 5.面向对象编程三大特性② 9-7 6.面向对象编程三大特性③ 9-9 1.回顾 9-9 2.面向对象编程三大特性④ 9-9 3.面向对象编程三大特性⑤ 抽象类 9-9 4.接口 9-9...

    PHP5新特性: 更加面向对象化的PHP

    在新的版本里,上述操作将传递引用(可以把引用理解成对象的标识符),而非值。 很多PHP程序员可能甚至没有察觉到老的对象处理方式。事实上,大多数的php应用都可以很好地运行。或者仅仅需要很少的改动。 私有和受...

    史上最全韩顺平传智播客PHP就业班视频,10月份全集

    9-7 4.static关键字(静态方法) 面向对象编程三大特性① 9-7 5.面向对象编程三大特性② 9-7 6.面向对象编程三大特性③ 9-9 1.回顾 9-9 2.面向对象编程三大特性④ 9-9 3.面向对象编程三大特性⑤ 抽象类 9-9 4.接口 9-9...

    史上最全韩顺平传智播客PHP就业班视频,9月份全集

    9-7 4.static关键字(静态方法) 面向对象编程三大特性① 9-7 5.面向对象编程三大特性② 9-7 6.面向对象编程三大特性③ 9-9 1.回顾 9-9 2.面向对象编程三大特性④ 9-9 3.面向对象编程三大特性⑤ 抽象类 9-9 4.接口 9-9...

    php-shellcommand, 在PHP中,一个简单的面向对象的接口来执行 shell 命令.zip

    php-shellcommand, 在PHP中,一个简单的面向对象的接口来执行 shell 命令 php ShellCommand php ShellCommand提供了一个简单的面向对象接口来执行 shell 命令。特性捕获 stdOut,stdErr 和 exitCode句柄参数转义将...

    深入PHP面向对象、模式与实践 (第2版) part1

     第10章 让面向对象编程更加灵活的模式   第11章 执行及描述任务   第12章 企业模式   第13章 数据库模式  第四部分 实践  第14章 良好和糟糕的实践   第15章 PEAR   第16章 用 phpDocumentor...

    PHP 面向对象技术(全面讲解).txt

    上面已经介绍过了,面向对象程序的单位就是对象,但对象又是通过类的实例化出来的,所以 我们首先要做的就是如何来声明类,做出来一个类很容易,只要掌握基本的程序语法定义规则就可 以做的出来,那么难点在那里呢?...

    史上最全传智播客PHP就业班视频课,8月份视频

    9-7 4.static关键字(静态方法) 面向对象编程三大特性① 9-7 5.面向对象编程三大特性② 9-7 6.面向对象编程三大特性③ 9-9 1.回顾 9-9 2.面向对象编程三大特性④ 9-9 3.面向对象编程三大特性⑤ 抽象类 9-9 4.接口 9-9...

    PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象

    PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)共5页.pdf.zip

Global site tag (gtag.js) - Google Analytics