Google Site Map 產生器
適用任何網站
使用範例如下:
PHP5中對類的屬性或方法的訪問控制,是通過在前面添加關鍵字 public、protected 或 private 來實現的。由 public 所定義的類成員可以在任何地方被訪問;由 protected 所定義的類成員則可以被其所在類的子類和父類訪問(當然,該成員所在的類也可以訪問);而由 private 定義的類成員則隻能被其所在類訪問。
對類成員的訪問控制
類成員都必須使用關鍵字public、protected 或 private 進行定義
聲明類成員
<?php
/** Define MyClass */
class MyClass
{ public $public = ’Public’;
protected $protected = ’Protected’;
private $private = ’Private’;
function printHello()
{ echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello();// Shows Public, Protected and Priv
class MyClass2 extends MyClass //Define MyClass2
{// We can redeclare the public and protected method, but not private
protected $protected = ’Protected2’;
function printHello()
{ echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj->public; // Works
echo $obj2->private; // Undefined
echo $obj2->protected; // Fatal Error
$obj2->printHello();// Shows Public, Protected2, not Private
?>
注意:
在 PHP 4 中使用 var 關鍵字對變量進行定義的方法在 PHP 5 的面向對象語法中不再使用。為了顧及兼容性,在類中定義一個變量的話,該變量會被自動設為 public,並且產生一個 E_STRICT 警告。
對方法的訪問控制
類中的方法都必須使用關鍵字public、protected 或 private 進行定義。如果沒有設置這些關鍵字,則該方法會被設置成默認的 public。
例 10.10. 聲明類中的方法
<?php
class MyClass //Define MyClass
{ public function __construct() { }
public function MyPublic() { }
protected function MyProtected() { }
private function MyPrivate() { }
function Foo()
{ $this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass = new MyClass;
$myclass->MyPublic(); //
$myclass->MyProtected(); //
$myclass->MyPrivate(); //
$myclass->Foo();
class MyClass2 extends MyClass //Define MyClass2
{ // This is public
function Foo2()
{ $this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic();
$myclass2->Foo2();
?>
範圍解析操作符(::)–Scope Resolution Operator (::)
範圍解析操作符(也可稱作 Paamayim Nekudotayim)或者更簡單地說是一對冒號,可以用於訪問靜態成員、方法和常量,還可以用於覆蓋類中的成員和方法。當在類的外部訪問這些靜態成 員、方法和常量時,必須使用類的名字。把 Paamayim Nekudotayim 選作該操作符的名字似乎有些奇怪。然而,這是Zend開發小組在寫Zend Engine 0.5(被用於 PHP 3 中)時所作出的決定。事實上這個詞在希伯萊文就是雙冒號的意思。
例 10.11. 在類的外部使用 :: 操作符
<?php
class MyClass
{ const CONST_VALUE = ’A constant value’;
}
echo MyClass::CONST_VALUE;
?>
self和parent這兩個特殊的關鍵字是用於在類的內部對成員或方法進行訪問的。
例 10.12. :: from inside the class definition
<?php
class OtherClass extends MyClass
{ public static $my_static = ’static var’;
public static function doubleColon()
{ echo parent::CONST_VALUE . "\n";
echo self::$my_static . "\n";
}
}
OtherClass::doubleColon();
?>
當一個子類覆蓋其父類中的方法時,PHP不會再執行父類中已被覆蓋的方法,直到子類中調用這些方法為止。這種機制也作用於構造函數和析構函數、重載及魔術函數。
例 10.13. 調用父類的方法
<?php
class MyClass
{ protected function myFunc() { echo"MyClass::myFunc()\n"; }
}
class OtherClass extends MyClass
{ // Override parent’s definition
public function myFunc()
{ // But still call the parent function
parent::myFunc();
echo "OtherClass::myFunc()\n";
}
}
$class = new OtherClass();
$class->myFunc();
?>
靜態關鍵字(Static Keyword)
聲明靜態的類的成員和方法,使它不需要一個類的實例.一個static成員的聲明不能通過一個類對象的實例來訪問(儘管一個靜態方法可以)。
靜態聲明必須在可見性聲明之後。為了兼容PHP 4,如果沒有可見性被聲明,那麼成員和方法將被當作是已經聲明為public。
由於靜態方法可以調用非對象實例,偽變量$this不可以在聲明為靜態的方法中使用。
事實上static方法調用形式在編譯時被確定。當使用必須要聲明的類名時,方法是完全標識和無繼承規則的應用。當使用必須要聲明的類名時,這種方法就被完全確認,而且沒有使用繼承的規則。
如果self已經被聲明,那麼self就被當前所屬的類所解釋。也不適用與繼承規則。靜態屬性不能通過箭頭操作符->.訪問非靜態方法,這將產生一個E_STRICT 級的警告。
例子 19-13. 靜態成員的例子
<?php
class Foo
{ public static $my_static=’foo’;
public function staticValue(){ return self::$my_static; }
}
class Bar extends Foo
{ public function fooStatic(){ return parent::$my_static; }
}
print Foo::$my_static."\n";
$foo = new Foo();
print $foo->staticValue()."\n";
print $foo->my_static."\n";// Undefined ";Property" my_static
// $foo::my_static is not possible
print Bar::$my_static."\n";
$bar = new Bar();
print $bar->fooStatic()."\n";
?>
靜態方法實例(Static method example)
<?php
class Foo
{ public static function aStaticMethod() { }
}
Foo::aStaticMethod();
?>
類常量(Class Constants)
可以在每個基類中定義常量使它保持不變。在你不使用$符號去聲明或使用它時,常量不同於普通變量。就象靜態成員,常量值不能通過對象的實例來訪問(而應使 用$object::constant). 常量值必須是一個常量表達式,而不是一個變量,一個類的成員,一個數學表達式或函數調用的結果。
定義並使用一個常量
<?php
class MyClass
{ const constant = ’constant value’;
function showConstant() { echo self::constant."\n"; }
}
echo MyClass::constant."\n";
$class = new MyClass();
$class->showConstant();// echo $class::constant; is not allowed
?>
抽象類(Class Abstraction)
PHP 5中引入了抽象類和抽象方法。不允許創建一個已經定義為abstract的類的一個實例。任何至少包含一個抽象方法的類也必須是抽象的。被定義為抽象的方法僅僅是聲明方法的一個信號,並不能定義它們的實現。
當從一個抽象類繼承時,在父類中所有抽象方法的標記的聲明必須通過子類定義;另外,這些方法必須用定義相同的訪問屬性。例如,如果方法被定義為protected類型,執行函數必須定義為protected或public.
例子 抽象類例子
<?php
abstract class AbstractClass
{ // Force Extending class to define this method
abstract protected function getValue();
abstract protected function prefixValue($prefix);
public function printOut() // Common method
{
print $this->getValue()."\n";
}
}
class ConcreteClass1 extends AbstractClass
{ protected function getValue()
{
return "ConcreteClass1";
}
public function prefixValue($prefix)
{
return "{$prefix}ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{ public function getValue()
{
return "ConcreteClass2";
}
public function prefixValue($prefix)
{
return"{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();//ConcreteClass1
echo $class1->prefixValue(’FOO_’) ."\n";//FOO_ConcreteClass1
$class2 = new ConcreteClass2;
$class2->printOut();//ConcreteClass2
echo $class2->prefixValue(’FOO_’) ."\n";//FOO_ConcreteClass2
?>
資料來源:http://www.lpi-tw.org:88/u8/lpi-china.org/bbs/viewthread.php?tid=3865
用戶定義的類,也是學好 PHP 所必備的條件之一。而 PHP 的類,和其它的面向對像語言比較起來,還算蠻單純的。PHP 只有類別 (class)、方法 (method)、屬性、以及單一繼承 (extensions) 等。對不習慣使用 C++、Java、Delphi 等面向對像語言來開發程序的用戶,不妨先閱讀一下有關面向對像概念的書,相信可以帶來許多的收穫。
下面的範例是手推車類。可以看到,使用 class 表示它是一個類類別。在類別中的 function,例如 add_item 則表示該類的一個方法。方法可以封裝類的實際處理情形,讓該類自己能依封裝好的方法來執行一些步驟。
程序中的 $this 類變量也和 $GLOBALS 及 $php_errormsg 兩個變量一樣,在 PHP 中屬於特殊的變量。$this 變量只用在類類別中,表示類的本身。
<?php
// 程序名: cart.inc
class Cart {
var $items; // 手推車類
// 本方法加入 $num 件物品到手推車中 (加到 $artnr 變量)
function add_item ($artnr, $num) {
$this->items[$artnr] += $num;
}
// 本方法從手推車減少 $num 件物品 (從 $artnr 變量減掉)
function remove_item ($artnr, $num) {
if ($this->items[$artnr] > $num) {
$this->items[$artnr] -= $num;
return true;
} else {
return false;
}
}
}
?>
要 使用手推車可以用類似下例的方式。可以先將每個類存成 Include 文件,再將它 require 或 include 進來。在定義變量 $cart 時,要使用 new 的保留字,表示 $cart 使用 Cart 類。使用 -> 符號,表示執行類的方法。
<?php
require("cart.inc");
$cart = new Cart;
$cart->add_item("10", 1);
?>
之後再設計有記名的手推車。記名手推車從手推車遺傳下來,因此手推車擁有的方法及屬性,記名手推車也有,而記名手推車比手推車增加了名字的方法 (或許該稱屬性較恰當)。
從下例中可以看到,子類 Named_Cart 使用 extends 來繼承其父類 Cart。雖然 Named_Cart 類中沒有增加物品及減少物品的方法,不過由於遺傳的特性,父類有的東西它都有。
<?php
// 程序名: named_cart.inc
require("cart.inc");
class Named_Cart extends Cart {
var $owner;
function set_owner ($name) {
$this->owner = $name;
}
}
?>
要使用記名手推車類,請看下面的範例。當然這不算太好的設計,每個子類都一直 require 它的父類,會造成服務器在 I/O 上面的負擔。在實作時,可以將整個系列的類在同一個程序文件中,從最早的袓先類到最後的子孫類,也方便日後修正。
<?php
require("named_cart.inc");
$ncart = new Named_Cart; // 建立類變量
$ncart->set_owner ("CyberRidder"); // 配置類的記名屬性
echo $ncart->owner; // 顯示類的記名屬性
$ncart->add_item ("10", 1); // 從父類遺傳的方法也可使用
?>
因此,在 PHP 中使用了 extends 保留字,加上良好的系統分析與完整的 CRC 卡片 (詳見面向對像相關書籍) 設計之後,PHP 可變成擁有強大類能力的 CGI 語言。
PHP 由於是腳本語言 (Script),因此程序源代碼可見,在軟件工程中的元件黑箱並不會在目前的 PHP 版本中出現,也就是說,全部的類其實沒有隱藏起它的內容。對於軟件業者而言,沒有辦法保護所謂的軟件 IC,站在開放團體而言,反而有源代碼是件好事,至於孰是孰非,就很難判定了,不過目前 PHP 還是 Open Source 團體的一份子,或許日後 Zend 引擎可以做到類封裝的功能也不一定。
除了上面的流程控制指令之外,尚有 break 及 continue 兩個流程控制指令。
break 用來跳出目前執行的迴圈,如下例
<?php
$i = 0;
while ($i < 10) {
if ($arr[$i] == "stop") {
break;
}
$i++;
}
?>
continue 立即停止目前執行迴圈,並回到迴圈的條件判斷處,見下例
<?php
while (list($key,$value) = each($arr)) {
if ($key % 2) { // 略過偶數
continue;
}
do_something_odd ($value);
}
?>
而 BASIC 常用的 goto 在 C 及 Borland Pascal 中或許可以使用。但在 PHP 中,由於它的 Web Server Script 特性以及結構化的組成,並不能在 PHP 中使用 goto 迴圈指令?
switch 迴圈,通常處理複合式的條件判斷,每個子條件,都是 case 指令部分。在實作上若使用許多類似的 if 指令,可以將它綜合成 switch 迴圈。
語法如下
switch (expr) {
case expr1: statement1;
break;
case expr2: statement2; break;
:
:
default: statementN; break;
}
其中的 expr 條件,通常為變量名稱。而 case 後的 exprN,通常表示變量值。冒號後則為符合該條件要執行的部分。注意要用 break 跳離迴圈。
<?php
switch (date("D")) {
case "Mon":
echo "今天星期一";
break;
case "Tue":
echo "今天星期二";
break;
case "Wed":
echo "今天星期三";
break;
case "Thu":
echo "今天星期四";
break;
case "Fri":
echo "今天星期五";
break;
default:
echo "今天放假";
break;
}
?>
很明顯的,上述的例子用 if 迴圈就很麻煩了。當然在設計時,要將出現機率最大的條件放在最前面,最少出現的條件放在最後面,可以增加程序的執行效率。上例由於每天出現的機率相同,所以不用注意條件的順序。
for 迴圈就單純只有一種,沒有變化,它的語法如下
for (expr1; expr2; expr3) { statement }
其中的 expr1 為條件的初始值。expr2 為判斷的條件,通常都是用邏輯運算符號 (logical operators) 當判斷的條件。expr3 為執行 statement 後要執行的部份,用來改變條件,供下次的迴圈判斷,如加一..等等。而 statement 為符合條件的執行部分程序,若程序只有一行,可以省略大括號 {}。
下例是用 for 迴圈寫的 "以後不敢了" 的例子,可以拿來和用 while 迴圈的比較。
<?php
for ($i=1; $i<=10; $i++) {
echo "$i. 以後不敢了<br>\n";
}
?>
從上例中,可以很明顯的看到,用 for 和用 while 的不同。實際應用上,若迴圈有初始值,且都要累加(或累減),則使用 for 迴圈比用 while 迴圈好。例如將資料從數據庫取出,可能用 for 迴圈會比用 while 迴圈適合?
由於 PHP 的大部份語法都是繼承了 C 語言的語法,因此,在流程控制方面,也是有著和 C 語言極類似的循環。PHP 的循環不像 ASP 般可以使用 goto 的 BASIC 語法,PHP 是結構化的程序語言,流程的設計上有一定的規定,而不能用 BASIC 的概念來亂跳到別的部分中。 PHP 的語法沒有像 C 語言的 main(){} 部分,其實整個 PHP 主頁面 (就是瀏覽器輸入的 URL) 就是 main(){} 部分,這點和其它的解析程序,如 Prel、Python、Shell Script 倒是很像。
在流程的部分分隔符號上,都是使用 { 當作部分的開頭,用 } 當作結尾,和 C 語言相同。不過 C 可以定義 begin 當開頭、end 當結尾 (像 Pascal),而 PHP 中不能做這種特殊的定義。
而 PHP 語法中在每條指令結束時都要加上分號 ;,但是在部分結尾符號 } 後面不用加上分號結束。
作者:DDVIP 更新人:Ideal 來源:不詳 更新時間:2004-07-01
if..else 迴圈有三種結構
第一種是只有用到 if 條件,當作單純的判斷。解釋成 "若發生了某事則怎樣處理"。語法如下:
if (expr) { statement }
其中的 expr 為判斷的條件,通常都是用邏輯運算符號 (logical operators) 當判斷的條件。而 statement 為符合條件的執行部分程序,若程序只有一行,可以省略大括號 {}。
範例:本例省略大括號。
<?php
if (date("D") == "Sat") echo "週末了,狂歡去";
?>
範例:本例的執行部分有三行,不可省略大括號。
<?php
if (file_exists("/usr/local/lib/php3.ini")) {
echo "以下是 PHP3 的配置文件<p><pre>\n";
readfile("/usr/local/lib/php3.ini");
echo "</pre>\n";
}
?>
第兩種是除了 if 之外,加上了 else 的條件,可解釋成 "若發生了某事則怎樣處理,否則該如何解決"。語法如下
if (expr) { statement1 } else { statement2 }
範例:上面的例子來修改成更完整的處理。其中的 else 由於只有一行執行的指令,因此不用加上大括號。
<?php
$f="/usr/local/lib/php3.ini";
if (file_exists($f)) {
echo "以下是 PHP3 的配置文件<p><pre>\n";
readfile($f);
echo "</pre>\n";
} else echo "很抱歉,找不到 $f";
?>
第三種就是遞歸的 if..else 迴圈,通常用在多種決策判斷時。它將數個 if..else 拿來合併運用處理。
直接看下面的例子
<?php
if ($a > $b) {
echo "a 比 b 大";
} elseif ($a == $b) {
echo "a 等於 b";
} else {
echo "a 比 b 小";
}
?>
上例只用二層的 if..else 迴圈,用來比較 a 和 b 兩個變量。實際要使用這種遞歸 if..else 迴圈時,請小心使用,因為太多層的循環容易使設計的邏輯出問題,或者少打了大括號等,都會造成程序出現莫名其妙的問題。
作者:DDVIP 更新人:Ideal 來源:不詳 更新時間:2004-07-01
do..while 是重複敘述的迴圈,可以分成兩種模式。
最單純的就是只有 while 的迴圈。用來在指定的條件內,不斷地重覆指定的步驟。語法如下
while (expr) { statement }
其中的 expr 為判斷的條件,通常都是用邏輯運算符號 (logical operators) 當判斷的條件。而 statement 為符合條件的執行部分程序,若程序只有一行,可以省略大括號 {}。
下例很有趣,要電腦的瀏覽器出現十次 "以後不敢了" 的字符串,前面並加上數字,表示說了第幾次不敢了。(感覺好像是 Web Server 做錯事被處罰)
<?php
$i = 1;
while ($i <= 10) {
print $i++;
echo ". 以後不敢了<br>\n";
}
?>
while 可以不用大括號來包住執行部分,而使用冒號加上 endwhile。見下例
<?php
$i = 1;
while ($i <= 10):
print $i++;
echo ". 以後不敢了<br>\n";
endwhile;
?>
另外一種 do..while 迴圈則先執行,再判斷是否要繼續執行,也就是說迴圈至少執行一次,有點像是先斬後奏的方法。這種的迴圈,和單用 while 是不同的 (單用 while 是先判斷再處理)。若讀者熟 Pascal 語言的話,會發現 do..while 迴圈像是 Pascal 的 repeat..until 迴圈。
作者:DDVIP 更新人:Ideal 來源:不詳 更新時間:2004-07-01