第1次親密接觸PHP5
發表于:2007-07-14來源:作者:點擊數:
標簽:
erquan注:本人現還未來得及體驗PHP5,只是翻譯一篇老外的文章。 以下均由erquan翻譯,第1次作這些的事情希望沒有誤導大家。有些不準的地方請諒解。 大家看這樣的行不行,如果行的話,偶就翻譯完,不行就翻譯了,免得誤導了大家,也累哦。。。。:) 轉貼時請
erquan注:本人現還未來得及體驗PHP5,只是翻譯一篇老外的文章。
以下均由erquan翻譯,第1次作這些的事情希望沒有誤導大家。有些不準的地方請諒解。
大家看這樣的行不行,如果行的話,偶就翻譯完,不行就翻譯了,免得誤導了大家,也累哦。。。。:)
轉貼時請注明文章來源,謝謝:)
PHP5的正式版還沒發布,但我們可以學習、體驗下開發版給我們帶來的PHP新特性。
本文將集中介紹以下3大PHP5新功能:
* 新對象模式
* 結構化異常處理
* 名稱空間
在正式開始之前,請注意:
*文章中的部分例子用PHP4的方法實現,只是為了增強文章的可讀性
*本文所描述的新特性可能會與正式版特性有出入,請以正式版本為準。
* 新對象模式
PHP5新的對象模式在PHP4的基礎上做了很大的"升級",你看起來會很像JAVA:(。
下面的一些文字將對它做一些簡單介紹,并且附有小例子讓您開始體驗PHP5的新特性
come on~~:)
* 構造函數 和 析構函數* 對象的引用* 克隆對象* 對象的3種模式:私有、公共和受保護* 接口* 虛擬類* __call()* __set()和__get()* 靜態成員構造函數 和 析構函數
在PHP4中,和類名一樣的函數被默認為該類的構造器,并且在PHP4沒有析構函數的概念。(二泉 注:這點和JAVA一樣)
但從PHP5開始,構造函數被統一命名為 __construct,而且有了析構函數:__destruct(二泉 注:這點卻和Delphi一樣,可見PHP5吸收了眾多的成熟的OO思想,可C可賀~~):
例1:構造函數和析構函數
<?php
class foo {
var $x;
function __construct($x) {
$this->x = $x;
}
function display() {
print($this->x);
}
function __destruct() {
print("bye bye");
}
}
$o1 = new foo(4);
$o1->display();
?>運行完你將看到輸出了"bye bye",這是因為類在終止的時候調用了__destruct()析構函數~~
對象的引用
正如你所知道的一樣,在PHP4中,對一個函數或方法傳遞一個變量時,實際上是傳遞了一個copy,除非你用了傳址符&來聲明
你在做一個變量的引用。在PHP5中,對象總是以引用的方式被指定:
例2:對象的引用
<?php
class foo {
var $x;
function setX($x) {
$this->x = $x;
}
function getX() {
return $this->x;
}
}
$o1 = new foo;
$o1->setX(4);
$o2 = $o1;
$o1->setX(5);
if($o1->getX() == $o2->getX()) print("Oh my god!");
?>
(二泉 注:你將看到"Oh my god!"的輸出)
克隆對象
如上,如果有時不想得到對象的引用而想用copy時,怎么辦?在PHP5提供的 __clone 方法中實現:
例3:克隆對象
<?php
class foo {
var $x;
function setX($x) {
$this->x = $x;
}
function getX() {
return $this->x;
}
}
$o1 = new foo;
$o1->setX(4);
$o2 = $o1->__clone();
$o1->setX(5);
if($o1->getX() != $o2->getX()) print("Copies are independant");
?>
克隆對象的方法在已被應用到很多語言中,所以你不必擔心它的
性能:)。
Private, Public 和 Protected
在PHP4中,你可以在對象的外面操作它任意的方法和變量--因為方法和變量是公用的。在PHP5引用了3種模式來控制
對變量、方法的控制權限:Public(公用的)、Protected(受保護)和Private(私有)
Public:方法和變量可以在任意的時候被訪問到
Private:只能在類的內部被訪問,子類也不能訪問
Protected:只能在類的內部、子類中被訪問
例子4:Public, protected and private
<?php
class foo {
private $x;
public function public_foo() {
print("I'm public");
}
protected function protected_foo() {
$this->private_foo(); //Ok because we are in the same class we can call private methods
print("I'm protected");
}
private function private_foo() {
$this->x = 3;
print("I'm private");
}
}
class foo2 extends foo {
public function display() {
$this->protected_foo();
$this->public_foo();
// $this->private_foo(); // Invalid! the function is private in the base class
}
}
$x = new foo();
$x->public_foo();
//$x->protected_foo(); //Invalid cannot call protected methods outside the class and derived classes
//$x->private_foo(); //Invalid private methods can only be used inside the class
$x2 = new foo2();
$x2->display();
?>
提示:變量總是私有形式,直接訪問一個私有變量并不是一個好的OOP思想,應該用其他的方法來實現 set/get 的功能
接口
正如你知道的一樣,在 PHP4 中實現繼承的語法是"class foo extends parent"。無論在PHP4 還是在 PHP5 中,都不支持多重繼承即只能從一個類往下繼承。 PHP5中的"接口"是這樣的一種特殊的類:它并不具體實現某個方法,只是用來定義方法的名稱和擁有的元素,然后通過關鍵字將它們一起引用并實現具體的動作。
Example 5: 接口
<?php
interface displayable {
function display();
}
interface printable {
function doprint();
}
class foo implements displayable,printable {
function display() {
// code
}
function doprint() {
// code
}
}
?>
這對代碼的閱讀性和理解性是非常有幫助的:讀到該類時,你就知道foo包含了接口displayable和printable,而且一定有print()(二泉 注:應該是doprint())方法和display()方法。不必知道它們內部是如何實現就可輕松操作它們只要你看到foo的聲明。
虛擬類
虛擬類是一種不能被實例化的類,它可以像超類一樣,可以定義方法和變量。
在虛擬類中還可以定義虛擬的方法,而且在該方法也不能在該類是被實現,但必須在其子類中被實現
Example 6: 虛擬類
<?php
abstract class foo {
protected $x;
abstract function display();
function setX($x) {
$this->x = $x;
}
}
class foo2 extends foo {
function display() {
// Code
}
}
?>
__call()方法
在PHP5時,如果你定義了 __call()方法,當你試圖訪問類中一個不存在的變量或方法時,__call()就會被自動調用:
Example 7: __call
<?php
class foo {
function __call($name,$arguments) {
print("Did you call me? I'm $name!");
}
}
$x = new foo();
$x->doStuff();
$x->fancy_stuff();
?>
這個特殊的方法被習慣用來實現"方法重載",因為你依靠一個私有參數來實現并檢查這個參數:
Exampe 8: __call 實現方法重載
<?php
class Magic {
function __call($name,$arguments) {
if($name=='foo') {
if(is_int($arguments[0])) $this->foo_for_int($arguments[0]);
if(is_string($arguments[0])) $this->foo_for_string($arguments[0]);
}
}
private function foo_for_int($x) {
print("oh an int!");
}
private function foo_for_string($x) {
print("oh a string!");
}
}
$x = new Magic();
$x->foo(3);
$x->foo("3");
?> __set()方法 和 __get()方法
當訪問或設置一個未定義的變量時,這兩個方法將被調用:
Example 9: __set and __get
<?php
class foo {
function __set($name,$val) {
print("Hello, you tried to put $val in $name");
}
function __get($name) {
print("Hey you asked for $name");
}
}
$x = new foo();
$x->bar = 3;
print($x->winky_winky);
?>
類型指示
在PHP5,你可以在一個類的方法中指明其參數必須為一個類的實例:
Example 10: 類型實例
<?php
class foo {
// code ...
}
class bar {
public function process_a_foo(foo $foo) {
// Some code
}
}
$b = new bar();
$f = new foo();
$b->process_a_foo($f);
?>
可以看到,在變量前指定一個類名,讓PHP5知道這個變量將是一個類的實例
靜態成員
靜態成員和靜態方法在OOP中一般稱為"類變量"和"類方法"。
一個"類方法"可以在對象沒有被實例化的時候調用
一個"類變量"可以在對象沒有被實例化的時候訪問(也不需要對象的方法來調用)
Example 11: 類變量和類方法
<?php
class calculator {
static public $pi = 3.14151692;
static public function add($x,$y) {
return $x + $y;
}
}
$s = calculator::$pi;
$result = calculator::add(3,7);
print("$result");
?>
* 異常處理
異常處理是開發語言中公認的處理異常錯誤的方法,如在JAVA和C++中。
PHP5用"try"和"catch"關鍵字來捕獲異常。
Example 12: 異常處理
<?php
class foo {
function divide($x,$y) {
if($y==0) throw new Exception("cannot divide by zero");
return $x/$y;
}
}
$x = new foo();
try {
$x->divide(3,0);
} catch (Exception $e) {
echo $e->getMessage();
echo "\n<br />\n";
// Some catastrophic measure here
}
?>
可以看出,"try"表示的是執行代碼的地方,當有錯誤的時候執行"catch"區域的代碼。
在"catch"區域你應當指明執行異常的對象,這樣可以使我們的結構更清晰
自定義異常處理
你可以在程序中定義自己習慣的捕獲異常錯誤的代碼。
非常簡單,你僅僅需要繼承一個異常類,在這個類中需要一個構造器和一個叫getMessage的方法而已:
Example 13: 自定義異常類
<?php
class WeirdProblem extends Exception {
private $data;
function WeirdProblem($data) {
parent::exception();
$this->data = $data;
}
function getMessage() {
return $this->data . " caused a weird exception!";
}
}
?>
現在就可以用"throw new WeirdProblem($foo) "來拋出異常。如果在try{}這樣的區域中出現異常,PHP5就會跳入
catch區域來拋出異常。
名稱空間
"名稱空間"可以讓你方便地調用一組類或方法:
Example 14: 名稱空間
<?php
namespace Math {
class Complex {
//...code...
function __construct() {
print("hey");
}
}
}
$m = new Math::Complex();
?>
注:在實際應用中,你可以在不同的名稱空間里定義同名的類來完成不同的任務(但接口要相同)
<翻譯完畢>
終天蹩手蹩腳地翻譯完了,有些翻譯不正確的地方,如術語、對原文的理解,敬請一一指出,共同完善,共同開始PHP5的學習、探討。。。
二泉
2003/7/2于鄭州
原文轉自:http://www.anti-gravitydesign.com