`
wbj0110
  • 浏览: 1604533 次
  • 性别: 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锁定/解除锁定 

分享到:
评论

相关推荐

    PHP之-----------面向对象一

    【标题】:“PHP之-----------面向对象一” 在PHP编程中,面向对象(Object-Oriented Programming,OOP)是一种强大的编程范式,它允许我们通过类(Class)和对象(Object)来组织代码,实现代码的封装、继承和多态...

    PHP5面向对象开发教程第一章-PHP5面向对象基础

    在PHP的世界里,面向对象编程(Object-Oriented Programming,OOP)是一种强大的设计和实现方法,它使得代码更加结构化、可维护性更强。PHP5引入了完整的面向对象支持,显著增强了其作为Web开发语言的能力。本教程将...

    php面向对象手册

    ### PHP面向对象手册知识点解析 ...PHP5 通过提供丰富的面向对象特性,使得开发者能够在 PHP 中有效地运用这一强大的编程范式。通过理解和掌握上述概念和技术,初学者可以在 PHP 开发中迈出坚实的一步。

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

    总结,PHP5的面向对象高级类特性包括抽象类、接口、访问修饰符、魔术方法、静态成员与常量、晚期静态绑定、命名空间以及Traits等,这些特性丰富了PHP的OOP功能,使得开发者能够编写出更加健壮、可扩展的代码。...

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

    在PHP5中,面向对象编程引入了许多高级特性,使得它能更好地支持面向对象的设计原则。本章主要讨论了三个核心的面向对象特性:静态变量和方法、final关键字以及abstract(抽象)类和方法。 首先,我们来探讨静态...

    20140207PHP01_PHP面向对象程序设计.pdf

    根据提供的文档信息,本文将详细解析“20140207PHP01_PHP面向对象程序设计.pdf”中关于PHP面向对象程序设计的关键知识点。 ### 面向对象概念 面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它...

    PHP面向对象类的实例-计算器

    PHP自5.0版本开始全面支持面向对象特性,使得它在Web开发领域中的应用更加广泛。本实例将深入探讨如何使用PHP面向对象来实现一个简单的计算器。 首先,让我们了解面向对象编程的基本概念。面向对象编程的核心思想是...

    PHP5面向对象开发教程第二章-PHP5面向对象进阶

    在本教程中,我们将深入探讨PHP5的面向对象特性,这是继第一章之后的进一步学习,主要聚焦于PHP5面向对象编程的高级概念。面向对象编程(Object-Oriented Programming,OOP)是一种软件开发方法,它以对象为基本单位...

    php ob PHP面向对象教程

    总的来说,PHP的面向对象编程提供了一种更加结构化和模块化的编程方式,使得代码更易于维护和扩展。通过理解并熟练运用这些概念,开发者能够编写出高效、可维护的PHP应用。在实际开发中,结合代码示例和实践,你将更...

    php5面向对象教程【技术文档】

    PHP5面向对象的特性为开发者提供了更加灵活和强大的代码组织方式,有助于提升代码的可读性、可维护性和重用性。本教程旨在深入探讨PHP5的面向对象特性,帮助你增强在PHP中的面向对象编程能力。 首先,我们来了解...

    PHP5面向对象编程(适合初学者)

    在PHP的世界里,面向对象编程(Object-Oriented Programming,OOP)是一种强大的设计和实现程序的方法,尤其在PHP5及以后的版本中得到了极大的增强。面向对象编程的核心概念包括类(Class)、对象(Object)、封装...

    深入PHP 面向对象、模式与实践.rar

    总结来说,《深入PHP:面向对象、模式与实践》是一本全面的PHP进阶教程,它将帮助读者深入理解PHP的核心特性,掌握面向对象编程的技巧,熟悉常用的设计模式,并学会在实践中应用这些知识,从而提升编程效率和代码...

    php面向对象系列(完整)

    《PHP面向对象系列(完整)》是一...通过深入学习这些文档,开发者可以全面掌握PHP 5.0的面向对象特性,提高代码的可维护性和复用性,进一步提升开发效率。对于PHP初学者和有经验的开发者来说,都是极有价值的学习资料。

    基于PHP面向对象的自定义MVC框架高级项目开发12天视频

    ### 基于PHP面向对象的自定义MVC框架高级项目开发 #### 一、引言 在现代Web开发中,MVC(Model-View-Controller)架构模式因其清晰的结构划分与高度的可维护性而被广泛采用。本系列视频教程旨在通过12天的学习与...

    php面向对象修改版

    PHP面向对象编程是PHP5及更高版本中引入的重要特性,它使得PHP能够更好地适应大型和复杂项目的开发需求。面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它基于“对象”概念,强调数据和操作数据...

Global site tag (gtag.js) - Google Analytics