php中有建構函數,其語法說明是“__construct(mixed ...$values = ""): void”,具有建構函式的類別會在每次建立新物件時先呼叫此方法,所以非常適合在使用物件之前做一些初始化工作。
本文操作環境:Windows7系統、PHP7.1版、DELL G3電腦
php中有沒有建構子?
php 建構子
__construct(mixed ...$values = ""): void
PHP 允許開發者在一個類別中定義一個方法作為建構子。具有建構函式的類別會在每次建立新物件時先呼叫此方法,所以非常適合在使用物件之前做一些初始化工作。
注意: 如果子類別中定義了建構函式則不會隱式呼叫其父類別的建構子。要執行父類別的建構函數,需要在子類別的建構子中呼叫 parent::__construct()。如果子類別沒有定義建構函式則會如同一個普通的類別方法一樣從父類別繼承(假如沒有被定義為 private 的話)。
範例 #1 繼承中的建構子
<?php class BaseClass { function __construct() { print "In BaseClass constructor\n"; } } class SubClass extends BaseClass { function __construct() { parent::__construct(); print "In SubClass constructor\n"; } } class OtherSubClass extends BaseClass { // 继承 BaseClass 的构造函数 } // In BaseClass constructor $obj = new BaseClass(); // In BaseClass constructor // In SubClass constructor $obj = new SubClass(); // In BaseClass constructor $obj = new OtherSubClass(); ?>
與其它方法不同, __construct() 在繼承時不受簽章相容性規則的限制。
自 PHP 5.3.3 起,在命名空間中,與類別名稱同名的方法不再作為建構子。不使用命名空間中的類別則不受影響。建構函式是一個普通的方法,在對應物件實例化時會自動被呼叫。因此可以定義任何數量的參數,可以是必選、可以有型別、可以有預設值。構造器的參數放在類別名稱後的括號裡呼叫。
範例 #2 使用建構子參數
<?php class Point { protected int $x; protected int $y; public function __construct(int $x, int $y = 0) { $this->x = $x; $this->y = $y; } } // 两个参数都传入 $p1 = new Point(4, 5); // 仅传入必填的参数。 $y 会默认取值 0。 $p2 = new Point(4); // 使用命名参数(PHP 8.0 起): $p3 = new Point(y: 5, x: 4); ?>
如果一個類別沒有建構函數,以及建構函式的參數不是必填項時,括號就可以省略。
舊式風格的建構子
PHP 8.0.0 之前,全域命名空間內的類別如果有一個同名的方法,則會解析為舊式風格的建構器。雖然函數能被當作建構器,但該語法已被廢棄,並會導致 E_DEPRECATED 錯誤。如果 __construct() 和同名方法同時存在時, 會呼叫 __construct()。
以下兩種情況時,與類別同名的方法不再有特殊意義:命名空間中的類別、PHP 8.0.0 起的任何類別。
新程式碼中要使用 __construct()。
建構器屬性提升
PHP 8.0.0 起,建構器的參數也可以對應提升為類別的屬性。構造器的參數賦值給類別屬性的行為很普遍,否則無法操作。而構造器提升的功能則為這種場景提供了便利。因此上面的範例可以用以下方式重寫:
範例#3 使用建構子屬性提升
<?php class Point { public function __construct(protected int $x, protected int $y = 0) { } }
當建構子參數帶存取控制(visibility modifier)時,PHP 會同時把它當作物件屬性和建構器參數, 並賦值到屬性。構造器可以是空的,或包含其他語句。參數值賦值到對應屬性後執行正文中額外的程式碼語句。
並非所有參數都需要提升。可以混合提升或不提升參數作為屬性,也不需要依序。提升後的參數不影響建構器內程式碼呼叫。
注意:
物件屬性的類型不能為 callable 以避免為引擎帶來混淆。因此提升的參數也不能是 callable。其他任意 類型聲明 是允許的。
注意:
放在建構子提升參數裡的屬性會同時複製為屬性和參數。
Static 創造方法
在 PHP 中每個 class 只能有一個建構器。然而有些情況下,需要用不同的輸入實現不同的方式來建構物件。這種情況下建議使用 static 方法包裝構造。
範例 #4 使用 static 創造方法
<?php class Product { private ?int $id; private ?string $name; private function __construct(?int $id = null, ?string $name = null) { $this->id = $id; $this->name = $name; } public static function fromBasicData(int $id, string $name): static { $new = new static($id, $name); return $new; } public static function fromJson(string $json): static { $data = json_decode($json); return new static($data['id'], $data['name']); } public static function fromXml(string $xml): static { // 自定义代码逻辑。 $data = convert_xml_to_array($xml); $new = new static(); $new->id = $data['id']; $new->name = $data['name']; return $new; } } $p1 = Product::fromBasicData(5, 'Widget'); $p2 = Product::fromJson($some_json_string); $p3 = Product::fromXml($some_xml_string);
可以設定建構器為 private 或 protected,防止自行額外呼叫。這時只有 static 方法可以實例化一個類別。由於它們位於同一個定義的 class 因此可以存取私有方法,也不需要在同一個物件實例中。當然構造器不一定要設定為 private,是否合理取決於實際情況。
三個 static 方法展示了物件以不同方式的實例化方式。
fromBasicData() 將所需的全部參數傳入建構器,建立物件並傳回結果。
fromJson() 接受 JSON 字串,,預處理成建構器所需的格式,然後傳回新的物件。
fromXml() 接受 XML 字串並解析,然後建立一個單純的物件。由於參數都是可選的,使得可以忽略所有參數去呼叫建構器。然後為物件的屬性賦值後傳回結果。
在上述三個範例中,static 關鍵字會被翻譯成程式碼所在類別的類別名稱。這個例子中是 Product。
推薦學習:《PHP影片教學》
以上是php中有沒有建構函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!