autoload_autoload机制 - CSDN
精华内容
参与话题
  • Autoload 自动载入

    千次阅读 2018-06-04 17:25:32
    Okay,我們可以透過 include, include_once, require 或是 require_once 來將檔案引入到我們目前正在編寫的這個檔案,我們也知道習慣上我們會將一個 Class 存放在單一的 PHP 檔案中,例如 Member.php 相對於 ...

    Okay,我們可以透過 includeinclude_oncerequire 或是 require_once 來將檔案引入到我們目前正在編寫的這個檔案,我們也知道習慣上我們會將一個 Class 存放在單一的 PHP 檔案中,例如 Member.php 相對於 Member 這個 Class,當我們的程式需要用到這個 Class 的時候就可以用上述的方法來引用這個 Class 以供後續操作。

    //index.php
    include_once "Member.php";
    
    $member = new Member();
    $member->getMemberList();
    

    完美!!! 但是如果今天我們有一卡車的 Classes 要引入呢?

    //index.php
    include_once "Member.php";
    include_once "Mailsender.php";
    include_once "Validate.php";
    inlcude_once "Other.php";
    

    What the #$%^# ... Okay! 夠了! 這看上去實在是不怎麼舒服,光這些引入就佔了一堆行數,我都還沒開始寫呢! 那有沒有辦法可以解決這個問題呢?有的 - Autoload !!!

    PHP Autoload

    PHP Autoload 機制可以讓我們能夠在需要這個物件的時候才去真正的引入這個 Class,這個動作就是常聽到的 Lazyload 延遲載入,在這裡我們不會談論實際上 PHP 怎麼去實現這個機制,只階段性的介紹 PHP 內幾種 Autoload 的做法。

    • __autoload
    • spl_autoload
    • autoload 與 namespace

    __autoload

    PHP5 提供了 __autoload() 這個魔術方法實現上述 Autoload 機制,雖然這個方法效能上及方便性並不是非常理想(後續會提到其他做法),讓我們來用這個方法實際寫點東西吧!

    為了讓例子看起來比較簡單,我們將不會把資料夾分的太細,以下為我們的根目錄資料夾。

    + classes
    +-- Member.php
    - autoload.php
    - index.php
    

    首先我們看到 classes 資料夾底下的 Member.php。

    <?php
    //classes/Member.php
    class Member
    {
        public function getMemberList()
        {
            echo "print member list...<br>";
        }
    }
    

    是的! 沒什麼特別的,我們在 classes 資料夾底下建立了一個 Member Class 包含了一個 public method getMemberList() 簡單的輸出一串字串 print member list...

    接著來到我們的重頭戲 autoload.php 這個檔案

    <?php
    //autoload.php
    function __autoload($className) {    
        $filename = __DIR__ . "/classes/" . $className . ".php";
        if (is_readable($filename)) {
            require $filename;
        }
    }
    

    在這個 function 內,我們首先取得存放 classes 路徑中的檔案名稱 $filename 接著我們用到了 is_readable() 這個 PHP 內建 function 判斷是檔案是否存在及可讀取,然後 require 引入這個檔案。聽起來棒極了,但是你沒有告訴我怎麼使用這個 __autoload() 這個 function 啊!!! 別急,究竟要怎麼讓這個東西動起來,讓我們看下去...

    <?php
    //index.php
    include_once __DIR__ . "/autoload.php";
    
    $member = new Member();
    $member->getMemberList();
    

    我們將 autoload.php 引入到我們程式的最一開始,現在當需要使用在 classes 目錄底下(不包含子目錄)的所有 class 都將會自動被載入,你不需要在手動的引入你所需要的 class。

    執行 index.php 會輸出一段文字 print member list... 在你的 browser 上,太神奇了!!!

    什麼!!! 有件事我忘了跟你說嗎? 呃... __autoload() 不能重覆的被定義,也就是說,當你嘗試引入兩支不一樣的 autoload.php (或許你有其他目錄底下的 class 也想被自動載入...) 的時候,PHP 將會報出錯誤訊息 Fatal error: Cannot redeclare __autoload()...

    這樣子很不方便耶! 別急,PHP 當然知道要幫你解決這個問題,下一章節將說明。
    (你當然可以通過 php.ini 設定 include path 來解決這樣子的問題,不過這有點不明智就是了...)

    spl_autoload 與 spl_autoload_register

    PHP 在 5.1.2 以後提供了 SPL 這個方便的大玩意,SPL 全名為 Standard PHP Library,顧名思義,提供你 許多 Interface 及 class,目的為解決常見的問題。

    • spl_autoload
      預設實作 __autoload() 魔術方法,也就是說,當 spl_autoload_register() 沒有定義或是沒有帶任何參數的時候,預設會採用 __autoload() 這個 function

    • spl_autoload_register
      spl_autoload_register() 讓你能夠註冊你自定義的 autoload function,當 spl_autoload_register() 有註冊之後,__autoload() 將會失效,你必需自己手動將 __autoload() 註冊,才能使用。

    廢話不多說,我們來寫點程式。

    首先我們新增兩個目錄 first, second 在我們剛剛建立的目錄,同時也個新增兩個 class 在 first 和 second 底下。

    + classes
    +-- Member.php
    + first
    +-- First.php
    + second
    +-- Second.php
    - autoload.php
    - index.php
    

    讓我們來看一下 First.php 和 Second.php 的內容。

    <?php
    //first/First.php
    class First
    {
        public function doSomething()
        {
            echo "I am first class...<br>";
        }
    }
    
    <?php
    //second/Second.php
    class Second
    {
        public function doSomething()
        {
            echo "I am second class...<br>";
        }
    }
    

    新增的這兩個 class 內容沒什麼特別的,各有一個 doSomething() 的 method 分別輸出 I am first class... 和 I am second class..., 接著我們來修改一下我們 index.php。

    <?php
    //index.php
    $first = new First();
    $first->doSomething();
    
    $second = new Second();
    $second->doSomething();
    

    聰明的你一定會說,你把 autoload.php 的引入拿掉,這一定出錯的啊! 沒錯,所以我們現在要來註冊我們自己定義的 autoload,我們在資料夾底下再新增兩個檔案 firstAutoload.php 和 secondAutoload.php。

    + classes
    +-- Member.php
    + first
    +-- First.php
    + second
    +-- Second.php
    - firstAutoload.php
    - secondAutoload.php
    - autoload.php
    - index.php
    

    接著我們來看看這兩個 autoload 裡寫了些什麼。

    <?php
    //firstAutoload.php
    function firstAutoload($className) {    
        $filename = __DIR__ . "/first/" . $className . ".php";
        if (is_readable($filename)) {
            require $filename;
        }
    }
    
    spl_autoload_register('firstAutoload');
    
    <?php
    //secondAutoload.php
    function secondAutoload($className) {    
        $filename = __DIR__ . "/second/" . $className . ".php";
        if (is_readable($filename)) {
            require $filename;
        }
    }
    
    spl_autoload_register('secondAutoload');
    

    我們定義了自己的 autoload function 之後就使用 spl_autoload_register() 註冊這個 function 的名稱,接著我們在 index.php 裡把這兩個自定義的 autoload 檔案引入。

    <?php
    //index.php
    include_once __DIR__ . "/firstAutoload.php";
    include_once __DIR__ . "/secondAutoload.php";
    
    $first = new First();
    $first->doSomething();
    
    $second = new Second();
    $second->doSomething();
    

    完美的輸出像這樣子的畫面...

    I am first class...
    I am second class...
    

    眼尖的你一定發現了,我們這樣子每要加入一個目錄放 class 不就要多寫一個 autoload,而且還要引入這些檔案,那不就跟原來一樣,喔不對,還比原來麻煩。
    嗯,你說的沒錯,那我們用 foreach 來處理這樣的問題呢?

    我們再新增一個檔案 allAutoload.php 在目錄底下,並看看內容寫了些什麼。

    <?php
    //allAutoload.php
    
    function allAutoload($className)
    {
        $folders = array(
            __DIR__ . "/first/",
            __DIR__ ."/second/",
        );
        
        foreach ($folders as $folder) {
            $fileName = $folder . $className . ".php";
            if (is_readable($fileName)) {
                require $fileName;
            }
        }
    }
    
    spl_autoload_register('allAutoload');
    

    Okay,我們把我們想要自動載入的目錄都設定在一個 array 裡,接著我們 foreach 這個 array,裡面做的事其實就跟先前的一樣,接著我們用 spl_autoload_register() 註冊這個 function 的名稱,我們來看一下 index.php 做了哪些改變。

    <?php
    //index.php
    include_once __DIR__ . "/allAutoload.php";
    
    $first = new First();
    $first->doSomething();
    
    $second = new Second();
    $second->doSomething();
    

    這次我們只需要引入一個 allAutoload.php 檔案了,我們又再一次完全的輸出了...

    I am first class...
    I am second class...
    

    看起來是不錯,不過聰明的你一定又發現了,這樣子我們每次要新增一個 class 目錄或是子目錄的時候,都要去更動我們的 autoload 檔案耶,這樣還是很麻煩呀!

    沒關係,是 namespace 該出場的時候了。

    autoload 與 namespace

    PHP 5.3.0 以後提供了namespace (命名空間) 的功能解決了 class 名稱重覆定義造成衝突的問題,這問題很容易發生在你的 project 內有使用到其他第三方的程式庫的時候。而 PHP FIG 也在它所制定的 PSR-0 定義了依照 namespace 使用 autoload 的方法。

    我們先來看一下 簡單的 namespace 使用方法。

    <?php 
    //MyClass.php
    
    namespace MyNamespace;
    
    class MyClass
    {
        public function doSomething()
        {
            echo "This is my class...<br>";
        }
    }
    
    <?php
    //index.php
    include_once __DIR__ . "/MyClass.php";
    
    $myClass = new \MyNamespace\MyClass();
    $myClass->doSomething();
    

    在 MyClass.php 內,我們看到 namespace MyNamespace; 定義了這個 class 的命名空間,也就是說當我們之後需要實例化這個 class 的時候,我們不能像這樣子實例化這個 class new MyClass();,我們需要在 class 名稱前面加上命名空間,命名空間以 \ 做分隔,new \MyNamespace\MyClass();,如同上面的 index.php 一樣,執行 index.php 完美的輸出...

    This is my class...
    

    讓我們來依照 PSR-0 的 autoload 範例來寫我們的 autoload 吧!
    首先我們想要將我們的 class 全部整理到根目錄下的 classes 目錄的 MyNamespace 目錄底下,我們先來看一下我們的目錄結構。

    + classes
    +-+ MyNamespace
    - autoload.php
    - index.php
    

    當然,我們還沒有建立任何的 class 我們的 MyNmaespace 目錄底下,我們先來看一下 autoload.php 寫了些什麼。

    <?php
    //autoload.php
    
    function autoload($className)
    {
        $className = ltrim($className, '\\');
        $fileName  = '';
        $namespace = '';
        if ($lastNsPos = strrpos($className, '\\')) {
            $namespace = substr($className, 0, $lastNsPos);
            $className = substr($className, $lastNsPos + 1);
            $fileName  = 'classes/' . str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
        }
        $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
        
        require $fileName;
    }
    
    spl_autoload_register('autoload');
    

    autoload.php 會依照定義的 namespace 把 \ 替換成系統的目錄分隔符號(最後一個 \ 之後的 _ 也會被替換成系統目錄分隔符號),找到相對應的 class 檔案並引入。我們只要在程式的一開始引入這支 autoload.php 檔案,就可以在不需要手動引入 class 的情況下任意的實例化 MyNamespace 目錄底下的 class 檔案並進行操作,讓我們實際在 MyNamespace 目錄底下建立一個 class 及 兩個子目錄各包含一個 class 檔案。

    + classes
    +-+ MyNamespace
    +-+-- MyClass.php
    +-+-+ Member
    +-+-+-- Member.php
    +-+-+ Email
    +-+-+-- Mailler.php
    - autoload.php
    - index.php
    
    <?php
    //classes/MyNamespace/MyClass.php
    
    namespace MyNamespace;
    
    class MyClass
    {
        public function doSomething()
        {
            echo "This is my class...<br>";
        }
    }
    
    <?php
    //classes/MyNamespace/Member/Member.php
    
    namespace MyNamespace\Member;
    
    class Member
    {
        public function getMemberList()
        {
            echo "This is member list...<br>";
        }
    }
    
    <?php
    //classes/MyNamespace/Email/Mailler.php
    
    namespace MyNamespace\Email;
    
    class Mailler
    {
        public function sendMail()
        {
            echo "send email...<br>";
        }
    }
    

    值得注意的是當我們在建立一個新的 class 的時候,千萬記得將 class 的 namespace 定義到正確的目錄結構上,這樣子我們的 autoload 才能夠正確的辨認相對應的 class,我們來看看我們的 index.php 內容與執行的結果吧!

    <?php
    //index.php
    include_once __DIR__ . "/autoload.php";
    
    $myClass = new \MyNamespace\MyClass();
    $myClass->doSomething();
    
    $member = new \MyNamespace\Member\Member();
    $member->getMemberList();
    
    $mailler = new \MyNamespace\Email\Mailler();
    $mailler->sendMail();
    

    執行結果如下。

    This is my class...
    This is member list...
    send email...
    

    我們只引入了 autoload.php,之後只要是要實例化在 MyNamespace 目錄底下的 class 就都不用再手動引入了,未來想要增加新的 class 也不需要再去定義 array 或是 設定 php include path,如果覺得 new \MyNamespace\Member\Member();這樣的宣告方式太冗長了,可以考慮使用 use 這個 keyword,在 Using namespaces: Aliasing/Importing 有詳細的用法。
    Okay,我想我們今天該告一段落了,如果覺得不想自己寫這些 autoload 的 function,有機會我會在寫一篇如何使用 composer 套件管理中的 autoload 來更方便的管理你的 autoload,我們下次見^^

    展开全文
  • php自动加载autoload方法,在我们编写mvc框架的时候可能会常常用到,虽然在性能上会有些...主要通过两种方法来使用自动加载autoload方法: 一、通过类路径和类名来调用 function __autoload($class_name) { $pat

    原文链接:关于php自动加载autoload方法的使用及弊端

    php自动加载autoload方法,在我们编写mvc框架的时候可能会常常用到,虽然在性能上会有些影响,是在可承受范围之内的,但框架在整体上的架构和开发会方便很多,易于管理框架中的类及方法,觉得它的利还是大于它的弊的。

    主要通过两种方法来使用自动加载autoload方法:

    一、通过类路径和类名来调用

    function __autoload($class_name) { 
       $path = str_replace('_', '/', $class_name); 
       require_once $path . '.php'; 
    } 
    //这里会自动加载Core/Http/File.php文件 
    $a = new Core_Http_File();

    这种方法调用比较简单也很方便,一般情况下也会采用这种方法,但是缺点是__autoload的最大缺陷是无法有多个autoload方法,不过在php5.1版本之后又添加了spl_autoload函数。

    二、spl_autoload是_autoload()的默认实现

    /*File.php*/ 
    <?php 
    class File { 
      public function callname(){ 
        echo "this is file class"; 
      } 
    } 
    /*test.php*/
    <?php  
      set_include_path("/Core/Http/"); //这里需要将路径放入include  
      spl_autoload("File"); //寻找/Core/Http/File.php  
      $f = new File();
      $f->callname();
    ?>

    使用spl_autoload函数的好处是可以注册多个自定义的autoload函数,会形成autoload调用堆栈,不会产生冲突。

    目前常用的php的mvc框架有的也使用了自动加载方法,像Zend、CodeIgniter、ThinkPHP等等都有用到,另外在性能上的影响几乎可以忽略,具体试验可以查看此文

    展开全文
  • 其中composer的autoload功能可是一大亮点,今天看到一篇文章,能帮大家深入理解composer自动加载的原理,分享给大家,原文出处:如何使用composer的autoload来自动加载自己编写的函数库与类库? composer...

    https://www.toolmao.com/composer-autoload

    composer可谓有一统PHP界的趋势,从此PHP开发成了搭积木的游戏。其中composer的autoload功能可是一大亮点,今天看到一篇文章,能帮大家深入理解composer自动加载的原理,分享给大家,原文出处:如何使用composer的autoload来自动加载自己编写的函数库与类库?

    composer的出现真是让人们眼前一亮,web开发从此变成了一件很『好玩』的事情,开发一个CMS就像在搭积木,从packagist中取出『积木』搭建在自己的代码中,一点一点搭建出一个属于自己的王国。
    从此以后我基本就抛弃了require和include函数,一个项目中,这两个函数只可能出现一次,那就是require '../vendor/autoload.php'
    那么,既然抛弃了传统的文件包含方法,我们使用所有类库都将用namespace和composer自带的autoload。可是,我们自己编写的函数库与类库,怎么用composer的方法来自动加载呢?

    这就要从composer.json说起,我们需要通过修改这个文件来达到目的。
    composer.json相当于是composer的配置文件,这个配置文件中有一个autoload段,比如我的一个项目:

    autoload

    其中又包含主要的两个选项: files 和 psr-4。
    files就是需要composer自动帮我们加载的函数库(不含类),只要在后面的数组中将函数库的文件路径写入即可。
    psr-4顾名思义,是一个基于psr-4(http://www.php-fig.org/psr/psr-4/)规则的类库自动加载对应关系,只要在其后的对象中,以 "命名空间": "路径" 的方式写入自己的类库信息即可。
    修改完成后,只要执行一下composer update,即可完成对应工作。

    之后,我们在项目中,用如下方式即可加载自定义类库:

    new \Core\View();

    composer的autoload将会自动包含”./core/view.php”,并找到其中的Core命名空间下的View类。

    我们来深挖一下,探索一下autoload的原理。
    在我们修改完composer.json并执行update后,将会修改./vender/composer/autoload_psr4.php,比如我的某个项目,其中增加了这样一个对应关系:

    autoload

    这其实就是我刚刚在.json中添加的对应关系,他等于将.josn的配置文件,换成了php的形式。
    那么我看到vendor/autoload.php:

    <?php
    
    // autoload.php @generated by Composer
    
    require_once __DIR__ . '/composer' . '/autoload_real.php';
    
    return ComposerAutoloaderInitff1d77c91141523097b07ee2acc23326::getLoader();
    

    其执行了一个自动生成的类ComposerAutoloaderInitff1d77c91141523097b07ee2acc23326中的getLoader方法。
    跟进:

        public static function getLoader()
        {
            if (null !== self::$loader) {
                return self::$loader;
            }
    
            spl_autoload_register(array('ComposerAutoloaderInitff1d77c91141523097b07ee2acc23326', 'loadClassLoader'), true, true);
            self::$loader = $loader = new \Composer\Autoload\ClassLoader();
            spl_autoload_unregister(array('ComposerAutoloaderInitff1d77c91141523097b07ee2acc23326', 'loadClassLoader'));
    
            $map = require __DIR__ . '/autoload_namespaces.php';
            foreach ($map as $namespace => $path) {
                $loader->set($namespace, $path);
            }
    
            $map = require __DIR__ . '/autoload_psr4.php';
            foreach ($map as $namespace => $path) {
                $loader->setPsr4($namespace, $path);
            }
    
            $classMap = require __DIR__ . '/autoload_classmap.php';
            if ($classMap) {
                $loader->addClassMap($classMap);
            }
    
            $loader->register(true);
    
            $includeFiles = require __DIR__ . '/autoload_files.php';
            foreach ($includeFiles as $file) {
                composerRequireff1d77c91141523097b07ee2acc23326($file);
            }
    
            return $loader;
        }

    可以明显看到,他将autoload_namespaces.php、autoload_psr4.php、autoload_classmap.php、autoload_files.php等几个配置文件包含了进来,并进行了相关处理(setPsr4),最后注册(register)。
    那么我们跟进register方法:

        public function register($prepend = false)
        {
            spl_autoload_register(array($this, 'loadClass'), true, $prepend);
        }

    这函数就一行,但简单明了,直接调用php自带的spl_autoload_register函数,注册处理__autoload的方法,也就是loadClass方法。再跟进loadClass方法:

        public function loadClass($class)
        {
            if ($file = $this->findFile($class)) {
                includeFile($file);
    
                return true;
            }
        }

    从函数名字就可以大概知道流程:如果存在$class对应的这个$file,则include进来。
    那么进findFile方法里看看吧:

        public function findFile($class)
        {
            // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
            if ('\\' == $class[0]) {
                $class = substr($class, 1);
            }
    
            // class map lookup
            if (isset($this->classMap[$class])) {
                return $this->classMap[$class];
            }
            if ($this->classMapAuthoritative) {
                return false;
            }
    
            $file = $this->findFileWithExtension($class, '.php');
    
            // Search for Hack files if we are running on HHVM
            if ($file === null && defined('HHVM_VERSION')) {
                $file = $this->findFileWithExtension($class, '.hh');
            }
    
            if ($file === null) {
                // Remember that this class does not exist.
                return $this->classMap[$class] = false;
            }
    
            return $file;
        }

    通过类名找文件,最终锁定在findFileWithExtension方法中。
    不过发现了一个小宝藏:在php5.3.0~5.3.2版本下,类名的第一个字符是\的小bug,也许以后挖漏洞会用上。
    还是跟进findFileWithExtension方法:

        private function findFileWithExtension($class, $ext)
        {
            // PSR-4 lookup
            $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
    
            $first = $class[0];
            if (isset($this->prefixLengthsPsr4[$first])) {
                foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
                    if (0 === strpos($class, $prefix)) {
                        foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
                            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
                                return $file;
                            }
                        }
                    }
                }
            }
    
            // PSR-4 fallback dirs
            foreach ($this->fallbackDirsPsr4 as $dir) {
                if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
                    return $file;
                }
            }
    
            // PSR-0 lookup
            if (false !== $pos = strrpos($class, '\\')) {
                // namespaced class name
                $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
                    . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
            } else {
                // PEAR-like class name
                $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
            }
    
            if (isset($this->prefixesPsr0[$first])) {
                foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
                    if (0 === strpos($class, $prefix)) {
                        foreach ($dirs as $dir) {
                            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                                return $file;
                            }
                        }
                    }
                }
            }
    
            // PSR-0 fallback dirs
            foreach ($this->fallbackDirsPsr0 as $dir) {
                if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                    return $file;
                }
            }
    
            // PSR-0 include paths.
            if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
                return $file;
            }
        }

    最终实现将命名空间\类这样的类名,给转换成目录名/类名.php这样的路径,并返回完整路径。
    我发现composer的autoload与php自带的spl_autoload,在包含文件时有一点小区别。那就是,spl_autoload会查找.inc类型的文件名,但composer不会。
    另外也可以发现,虽然配置文件的名字是autoload_psr4.php,但实际上psr0格式的自动加载也是支持的。二者最大的不同就是psr0中用”_”来代替目录间的”\”。

    展开全文
  • __autoload()

    2019-12-01 20:29:18
    __autoload()方法并不是一个魔术方法,但是这个方法非常有用,当实例化或继承一个不存在的类,会自动调用__autodoad(),同时将该类的类名作为参数。 在实际的开发当中,一个类会放到一个专门的php文件中,而且这个...

    1、概念

    __autoload()方法并不是一个魔术方法,但是这个方法非常有用,当实例化或继承一个不存在的类,会自动调用__autodoad(),同时将该类的类名作为参数。

    在实际的开发当中,一个类会放到一个专门的php文件中,而且这个文件的名称一般会加class后缀

    2、例题

    2.1Women.class.php

    class Women{
     	publiC function work(){
     		echo '女性在工作';
     	}
     	public function doWork($obj){
     		$obj->work();
     	}
    }
    

    2.2Nurse.class.php

    <?php
    class Nurse extends Women
    {
        public function work()
        {
            echo '护士在为病人扎针';
        }
    }
    

    2.3Teacher.class.php

    <?php
    class Teacher extends Women
    {
        public function work()
        {
            echo '老师在喋喋不休的上课';
        }
    }
    

    2.4autoload.php

    <?php
    include 'Women.class.php';
    include 'Nurse.class.php';
    include 'Teacher.class.php';
    $w=new Women();
    $n=new Nurse();
    $t=new Teacher();
    
    $w->doWork($n);
    $w->doWork($t);
    

    自动加载
    帮着我们自动的将类所在的php文件引入,修改上面代码如下:

    <?php
    $w=new Women();
    $n=new Nurse();
    $t=new Teacher();
    
    $w->doWork($n);
    $w->doWork($t);
    
    function __autoload($class){
      // echo 'autoload';
      include $class.'.class.php';
    }
    
    

    说明:如果使用__autoload方法,必须去掉手动的include 代码,否则方法不会执行。

    展开全文
  • __autoload废弃不用

    2018-12-16 18:57:21
    类自动加载 - __autoload:一个项目依赖多个框架,会报重复定义致命错误。 - spl_autoload_register:php5.3之后针对__autoload的缺陷出来的函数。
  • 当程序执行到实例化某个类的时候,如果在实例化前没有引入这个类文件,那么就自动执行__autoload()函数。 这个函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后 ...
  • __autoload 首先,这个方法与__call,__set等不一致,他不属于类,但是跟类有关。因为他会在类调用不到时自动调用。 首先,前面我们知道,调用另一个类要么与调用处在一个文件内部,要么就要使用require,include等...
  • Deprecated: __autoload() is deprecated, use spl_autoload_register() 解决:可能原因PHP版本过高,亲测discuz3.4版本使用php7.2.10会出现此bug,更换到php7.1以下就可以
  • 织梦提示 __autoload() is deprecated, use spl_autoload_register() instead in 原因是php版本问题,改成php5即可
  • 详解spl_autoload_register()函数

    万次阅读 多人点赞 2014-04-08 16:35:51
    在了解这个函数之前先来看另一个函数:__autoload。  一、__autoload  这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数。看下面例子:  printit.class.php...
  • PHP自动加载函数

    千次阅读 2012-06-28 16:07:31
    __autoload() :PHP原生的函数 spl_autoload():PHP的C扩展函数 两者的速度,区别很明显了。 自动加载俗称:Lazy Loading /** * 实现自动加载类 * FAQ:需要引入一个类文件,如show.php,类名为Show,然后...
  • 错误信息:`Warning: require(/http/www.mywakavLee.cn/bootstrap/../vendor/autoload.php): failed to open stream: No such file or directory in /...
  • 在看框架源码时,发现了__autoload和apl_autoload_register这两个函数,于是对其进行了一番学习。php的__autoload函数是一个魔术函数,在这个函数出现之前,如果一个php文件里引用了100个对象,那么这个文件就需要...
  • 1、PHP-FIG官网 2、composer 新文件夹中执行命令 composer init composer install //执行后显示 Generating autoload files(自动添加 autoload.php)
  • spl_autoload_register与autoload区别

    千次阅读 2012-07-24 19:06:35
    spl_autoload_register(PHP 5 >= 5.1.2)spl_autoload_register — 注册__autoload()函数说明bool spl_autoload_register ([ callback $autoload_function ] )将函数注册到SPL __autoload函数栈中。如果该栈中的函数...
  • PHP的类自动加载机制

    万次阅读 2012-07-27 19:15:20
    PHP的类自动加载机制 ... ...这个在小规模开发的时候,没什么大问题。但在大型的开发项目中,这么做会产生大量的require或者include方法调用,这样不因降低效率,而且使得代码难以维护,况且require_once的代价很大。 ...
  • 玩坏了的spl_autoload_register

    千次阅读 2018-09-02 23:13:39
    为什么要用spl_autoload_register其实我觉得这一段话基本可以解决所有的问题 尽管 __autoload() 函数也能自动加载类和接口,但更建议使用 spl_autoload_register() 函数。spl_autoload_register() 提供了一种...
  • PHP中spl_autoload_register函数的用法

    千次阅读 2013-11-26 08:43:57
    spl_autoload_register (PHP 5 >= 5.1.2) spl_autoload_register — 注册__autoload()函数 说明 bool spl_autoload_register ([ callback $autoload_function ] ) 将函数注册到SPL __autoload函数栈中。如果该栈中...
  • composer dump-autoload

    千次阅读 2020-03-28 23:31:39
    除了psr-4的自动加载规格,其他的需要执行这个命令,composer才能自动加载到 可以看到 psr-4 或者 psr-0 的自动加载都是一件很累人的事儿。基本是个O(n2)的复杂度。另外有一大堆is_file之类的 IO 操作所以性能堪忧 ...
  • php类文件的自动加载机制

    千次阅读 2014-09-28 11:15:11
    通常情况,在使用php面向对象开发的过程中,一个类的定义都是一个文件,这样子下来,当类与类之间需要...在php5之后已经有了类的自动加载机制,可以定义__autoload函数,在使用到某个未定义的类,执行php会出错,但是
1 2 3 4 5 ... 20
收藏数 30,764
精华内容 12,305
关键字:

autoload