iT邦幫忙

1

PHP 自學筆記 (4)

這邊來分享關於載入文檔的一些方法及clone方法。

1.手動加載

利用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

2.自動加載

當我們需要使用某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一樣。

1.自定義加載函數

<?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

2.class自動加載


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

物件理論上應由實體化產生,但有時候我們可以在已存在的物件,在產生一個新的物件,這時候就可以透過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) }


尚未有邦友留言

立即登入留言