這邊來分享關於載入文檔的一些方法及clone方法。
利用include引入即可,但include有缺點,他會重複引入,所以我們可以透過include_once來避免這個問題,如果在相同的檔案中遇到另一個include或include_once語句時,PHP會檢查它是否已經被匯入過,如果是,就忽略它。
除了include之外我們還可以使用require,require_once
,而require與include最大差別在於前者遇到錯誤會立即停止
,而後者會繼續執行,至於用哪個就看自己的需求。
<?php
// 當想獲取其他文件下的class,直接獲取會報錯
// $a = new Jojo(); // Uncaught Error: Class 'Jojo' not found
// 首先我們判斷class Jojo是否存在,如果不存在就加載,如果沒有就不加載。
if (!class_exists('Jojo')) {
echo "加載class";
// include './Jojo.php';
// 利用include_once取代include可避免重複多次載入檔案
include_once './Jojo.php';
}
$a = new Jojo(); // Jojo
當我們需要使用某class,而在當前文檔,又找不到時,系統就會自動呼叫__autoload這個函數來加載class
。
<?php
function __autoload($className)
{
echo $className;
// 定義統一的一個命名規範(.php)
include_once $className . '.php';
// 寫上exit,確保加載完後不會繼續執行,也可直接用require_once代替。
exit;
}
當class在其他資料夾下,我們就可透過file_exists,來判定此路徑的資料是否存在。
function __autoload($className)
{
// 尋找c資料夾
$c_file = 'c/' . $className . '.php';
echo $c_file, '<br/>';
if (file_exists($c_file)) {
include_once $c_file;
exit;
} else {
// 尋找m資料夾
$m_file = 'm/' . $className . '.php';
echo $m_file, '<br/>';
if (file_exists($m_file)) {
include_once $m_file;
exit;
}
}
}
$a = new Eva();
但__autoload是在php7以前,而系統則推薦我們使用spl_autoload_register(定義好的函數),其本質與__autoload一樣。
<?php
function my__autoload($className)
{
// 尋找c資料夾
$c_file = 'c/' . $className . '.php';
$m_file = 'm/' . $className . '.php';
if (file_exists($c_file)) {
include_once $c_file;
} else {
if (file_exists($m_file)) {
include_once $m_file;
}
}
}
// 此時,上述函數並不會自動執行,而是要利用spl....呼叫他。
spl_autoload_register('my__autoload');
$a = new Eva(); // Eva
class Autoload
{
// 不同資料夾的自動加載
public static function loadC($className)
{
$c_file = 'c/' . $className . '.php';
// 如果該資料夾下檔案存在Eva就載入
if (file_exists($c_file)) {
require_once $c_file;
}
}
public static function loadM($className)
{
$m_file = 'm/' . $className . '.php';
// 如果該資料夾下檔案存在Eva就載入
if (file_exists($m_file)) {
require_once $m_file;
}
}
}
// 自動加載
// 我們傳入一個陣列作為參數,如果我們傳入的是class名,就表示為一個靜態的獲取
// 第一個參數為class名,第二個為方法名
spl_autoload_register(array('Autoload', 'loadC'));
spl_autoload_register(array('Autoload', 'loadM'));
$a = new Eva(); // Eva
物件理論上應由實體化產生,但有時候我們可以在已存在的物件,在產生一個新的物件
,這時候就可以透過clone來達到。
class Bobo
{
public $name;
private $money = 0;
// clone方法(clone出的物件會自動呼叫)
// public function __clone()
// {
// echo __METHOD__, '<br/>'; // Bobo::__clone
// $this->money = 87;
// var_dump($this);
// // object(Bobo)#2 (2) { ["name"]=> NULL ["money":"Bobo":private]=> int(0) }
// }
// 如果不想要物件被外部clone,就可以將其設為private
private function __clone()
{
echo __METHOD__, '<br/>'; // Bobo::__clone
}
}
// 實體化
$a1 = new Bobo();
// clone物件
$a2 = clone $a1;
// 可發現兩者已為不同物件,代表兩者在不同的記憶體空間
// var_dump($a1, $a2);
// object(Bobo)#1 (2) { ["name"]=> NULL ["money":"Bobo":private]=> int(0) }
// object(Bobo)#2 (2) { ["name"]=> NULL ["money":"Bobo":private]=> int(87) }