<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] * * * * * ## 1 文件加載的意義 大型項目工程中,通常將項目的功能組織**以文件進行組織**,并使用目錄進行劃分。 為了**使用不同文件中定義的函數,類等**,需要加載目標文件。 因此文件加載是**項目工程分文件組織**后,**加載功能目標文件**的方法。 ## 2 文件的手動加載 >[info] 1 四個手動加載語言結構 * * * * * **inculde**與**require**是php用來手動加載文件的函數, **include_once**與**require_once**是限定同一個文件只被加載一次 1 首先按照參數給出的路徑查找 2 沒有給出目錄,從include_path指定目錄查找 3 include_path指定目錄查找失敗,在調用腳本文件所在目錄和當前工作目錄下查找 4 最后加載失敗時,include發出一條警告,而require會發出致命錯誤 這四個是**語言構造器或者說是語言結構**,通常后面**接一個字符串**。 與普通函數不同,普通函數后面接帶參數的大括號。 >[info] 2 示例 * * * * * exampe1:基本的include例子。 ~~~ vars.php <?php $color = 'green' ; $fruit = 'apple' ; ?> test.php <?php echo "A $color $fruit " ; // A include 'vars.php' ; echo "A $color $fruit " ; // A green apple ?> ~~~ >[danger] include等加載調用出現在一個函數里,則加載文件包含的代碼中的普通變量的作用域范圍就是該函數,其中的魔術變量是全局范圍。 example2:函數中include文件 ~~~ <?php function foo () { global $color ; include 'vars.php' ; echo "A $color $fruit " ; } /*vars.php中的$furit的作用域在foo()函數中,因此 因此foo()函數正常輸出$fruit echo語句中的$fruit為空 $color 聲明為全局變量 ,因此$color的作用域在全局。 foo() echo都輸出$color。 */ foo (); // A green apple echo "A $color $fruit " ; // A green ?> ~~~ >[info] 3 加載文件模式切換 加載文件時,php語法解析器會**從php模式切換到html模式**,**加載完文件后恢復到php模式**。因此也可以用來加載html文件,**其中的php代碼必須包含在php的起始與結束標記中** >[info] 4 url加載遠程文件 php.ini的配置中URL fopen_wrappers激活時,可以使用url加載網絡服務器文件進行解釋。**與加載本地文件不同的是模板文件如果作為php代碼解釋,已經在服務器運行了,本地腳本只是包含其輸出結果**。通常使用其他的文件打開函數如readfile()等更好 example #3 通過 HTTP 進行的 include ~~~ <?php include 'http://www.example.com/file.txt?foo=1&bar=2' ; //txt文件不會被運行 include 'file.php?foo=1&bar=2' ; //查找本地file.php?foo=1&bar=2文件,而不是運行file.php include 'http://www.example.com/file.php?foo=1&bar=2' ; // 查找遠程服務器的file.php,并以foo=1&bar=2參數運行。 $foo = 1 ; $bar = 2 ; include 'file.txt' ; //加載本地file.txt文件 include 'file.php' ; //加載本地file.php文件 ?> ~~~ >[info] 5 加載返回值檢測 include等加載失敗時返回false,并發出警告,成功則返回1,除非包含文件使用return等給出了返回值。 需要注意的是include 不是函數,其參數不需要括號 example #4 比較 include 的返回值 ~~~ <?php //錯誤的檢查返回值格式, if (include( 'vars.php' ) == 'OK' ) { echo 'OK' ; } //正確的檢查其返回值格式 if ((include 'vars.php' ) == 'OK' ) { echo 'OK' ; } ?> ~~~ 可以在目標文件中**使用return語句可以終止文件的加載,并返回調用的腳本**。thinkphp的默認**數組配置就是使用這個功能返回一個數組**。 example #5 include 和 return 語句 ~~~ return.php <?php $var = 'PHP' ; return $var ; ?> noreturn.php <?php $var = 'PHP' ; ?> testreturns.php <?php $foo = include 'return.php' ; echo $foo ; // prints 'PHP' $bar = include 'noreturn.php' ; echo $bar ; // prints 1 ?> ~~~ >[info] 6 加載包含函數的文件 包含文件中定義了函數,不管是return之前還是之后定義的,都可以獨立在主文件中使用。 **php5會對重復加載文件時出現的函數重復定義發出致命錯誤報告**。php4不會對return之后定義的函數報錯。**推薦使用include_once加載此類文件** >[info] 7 tp5.0中手動加載的使用 ~~~ index.php: require __DIR__ . '/../thinkphp/start.php'; ~~~ ~~~ start.php: require __DIR__ . '/base.php'; require CORE_PATH . 'Loader.php'; ~~~ ~~~ App.php public static function run(){ ... if (!empty($config['extra_file_list'])) { foreach ($config['extra_file_list'] as $file) { $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT; if (is_file($file)) { include_once $file; } } } ... } private static function initModule($module, $config){ $module = (COMMON_MODULE == $module || !APP_MULTI_MODULE) ? '' : $module . DS; if (is_file(APP_PATH . $module . 'init' . EXT)) { include APP_PATH . $module . 'init' . EXT; } else { $path = APP_PATH . $module; $config = Config::load(APP_PATH . $module . 'config' . EXT); if ($config['app_status']) { $config = Config::load(APP_PATH . $module . $config['app_status'] . EXT); } if ($config['extra_config_list']) { foreach ($config['extra_config_list'] as $name => $file) { $file = strpos($file, '.') ? $file : $path . $file . EXT; Config::load($file, is_string($name) ? $name : pathinfo($file, PATHINFO_FILENAME)); } } if (is_file($path . 'alias' . EXT)) { Loader::addMap(include $path . 'alias' . EXT); } if (APP_HOOK && is_file($path . 'tags' . EXT)) { Hook::import(include $path . 'tags' . EXT); } if (is_file($path . 'common' . EXT)) { include $path . 'common' . EXT; } if ($config['lang_switch_on'] && $module) { Lang::load($path . 'lang' . DS . LANG_SET . EXT); } } } ~~~ ## 3 文件的自動加載 在php引入面向對象編程思想后, 開發者習慣將每個類的定義建立一個php文件。 使用這些類需要使用require加載需要的類文件。 為了簡化類的加載,php中引入了類的自動加載 >[info] 1 __autoload 在php5中可以通過定義一個__auload()函數, 使用未被定義的類時自動調用。 通過調用此函數,腳本引擎可以加載目標類文件 ~~~ <?php function __autoload ( $class_name ) { require_once $class_name . '.php' ; } $obj = new MyClass1 (); $obj2 = new MyClass2 (); //在上面創建對象時,會調用__autoload,使用require加載對應的Myclass1.php類文件和MyClass2.php類文件。 ?> ~~~ 加載的異常處理 ~~~ <?php function __autoload ( $name ) { echo "Want to load $name .\n" ; throw new Exception ( "Unable to load $name ." ); } try { $obj = new NonLoadableClass (); } catch ( Exception $e ) { echo $e -> getMessage (), "\n" ; } ?> ~~~ 輸出: Want to load NonLoadableClass. Unable to load NonLoadableClass. 提示類加載失敗 5.3+版本后,__autoload 函數拋出的異常,可以被 catch 語句塊捕獲。 拋出的是一個自定義異常,那么必須存在相應的自定義異常類 __autoload 函數可以遞歸的自動加載自定義異常類。 ~~~ <?php function __autoload ( $name ) { echo "Want to load $name .\n" ; throw new MissingException ( "Unable to load $name ." ); } try { $obj = new NonLoadableClass (); } catch ( Exception $e ) { echo $e -> getMessage (), "\n" ; } ?> ~~~ 輸出: Want to load NonLoadableClass. Want to load MissingException.Fatal error: Class 'MissingException' not found in testMissingException.php on line 4 異常類查找失敗 >[info] 2 spl_autoload SPL提供了一個__autoload()函數默認實現。 如果不使用任何參數調用 autoload_register() 函數,則以后在進行 __autoload() 調用時會自動使用此函數 `void spl_autoload ( string $class_name [, string $file_extensions ] )` > $class_name 加載的類名 > $file_extensions 文件后綴,默認為.inc或.php * * * * * >[info] 3 spl_autoload_register 注冊給定的函數作為 __autoload 的實現,并將函數注冊到SPL __autoload函數隊列中 該函數會將__autoload()函數取代為lspl_autoload()或者spl_autoload_call() 因此程序中實現的__autoload()函數,需要使用該函數注冊到SPL __autoload隊列中 需要多條autoload函數,使用該函數。 實際上創建了autoload函數隊列,按照定義逐個執行 而__autoload()只可定義一個 `bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] )` > $autoload_function 自動加載函數,省略則為spl_autoload > $throw 注冊失敗時,是否拋出異常 > $prepend 添加到加載函數隊列隊首,還是加載函數隊尾 spl_autoload_register()示例 ~~~ <?php // function __autoload($class) { // include 'classes/' . $class . '.class.php'; // } function my_autoloader ( $class ) { include 'classes/' . $class . '.class.php' ; } spl_autoload_register ( 'my_autoloader' ); // 自 PHP 5.3.0 起可以使用一個匿名函數 spl_autoload_register (function ( $class ) { include 'classes/' . $class . '.class.php' ; }); ?> ~~~ spl_autoload_register()加載失敗示例 ~~~ <?php namespace Foobar ; class Foo { static public function test ( $name ) { print '[[' . $name . ']]' ; } } spl_autoload_register ( __NAMESPACE__ . '\Foo::test' ); new InexistentClass ; ?> ~~~ 輸出: [[Foobar\InexistentClass]] Fatal error: Class 'Foobar\InexistentClass' not found in ... >[info] 4 其他相關函數 spl_autoload_unregister() 注銷已注冊的__autoload()函數 spl_autoload_extensions() 修改spl_autoload()函數默認文件擴展名 spl_autoload_functions() 返回注冊的__autoload()函數 spl_autoload_call() 手動調用已注冊的__autoload()函數 * * * * * **在php的面向對象編程中,通常使用spl_autoload_register()來進行類的自動加載** * * * * * ## 4 composer的自動加載實現 使用composer安裝tp5后 thinkphp\vendor\composer\目錄中包含了composer的自動加載實現, 其目錄結構如下: ![](https://box.kancloud.cn/2016-03-11_56e272c8d3d04.jpg) autoload_classmap.php ;類名映射文件 autoload_files.php ;文件名映射文件 autoload_namespace.php ;命名空間映射文件 autoload_psr4.php ;psr4規范修正文件 autoload_real.php ;composer加載器入口 ClassLoader.php ;composer加載器核心 >[info] 1 autoload_real.php ~~~ class ComposerAutoloaderInit900f8cefe6f24fb76e69c5c37058d680 { // 全局唯一加載器實例, private static $loader; // 加載ClassLoader.php文件中的Composer\Autoload'ClassLoader類 public static function loadClassLoader($class) { if ('Composer\Autoload\ClassLoader' === $class) { require __DIR__ . '/ClassLoader.php'; } } // 生成加載器 public static function getLoader() { // 單例模式生成全局唯一加載器 if (null !== self::$loader) { return self::$loader; } // 注冊加載器 檢測自動加載器的存在 spl_autoload_register(array('ComposerAutoloaderInit900f8cefe6f24fb76e69c5c37058d680', 'loadClassLoader'), true, true); // 生成加載器實例 self::$loader = $loader = new \Composer\Autoload\ClassLoader(); // 注銷自動加載器 對應上面的檢查過程,下面會再次注冊 spl_autoload_unregister(array('ComposerAutoloaderInit900f8cefe6f24fb76e69c5c37058d680', 'loadClassLoader')); // 加載 命名空間映射文件。分析見下 $map = require __DIR__ . '/autoload_namespaces.php'; // 調用$loader->set() 設置命名空間別名路徑 foreach ($map as $namespace => $path) { $loader->set($namespace, $path); } // 加載 psr4規范修正文件 $map = require __DIR__ . '/autoload_psr4.php'; // 調用$laoder->setPsr4()設置命名空間別名路徑 foreach ($map as $namespace => $path) { $loader->setPsr4($namespace, $path); } // 加載 類映射文件 $classMap = require __DIR__ . '/autoload_classmap.php'; // 調用$loader->addClassMap() 設置類的別名 if ($classMap) { $loader->addClassMap($classMap); } // 注冊加載器。 $loader->register(true); // 加載 需要包含的文件 $includeFiles = require __DIR__ . '/autoload_files.php'; // 調用下面的函數依次加載需要包含的文件 foreach ($includeFiles as $fileIdentifier => $file) { composerRequire900f8cefe6f24fb76e69c5c37058d680($fileIdentifier, $file); } return $loader; } } // 加載目標文件,并保存加載信息到全局變量 $GLOBALS['_composer_autolod_files'],防止重復加載 function composerRequire900f8cefe6f24fb76e69c5c37058d680($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; } } ~~~ >[info] 2 ClassLoader.php composer自動加載器核心 * * * * * >[info] 成員變量 ~~~ PSR-4規范 private $prefixLengthsPsr4 = array(); private $prefixDirsPsr4 = array(); private $fallbackDirsPsr4 = array(); PSR-0規范 private $prefixesPsr0 = array(); private $fallbackDirsPsr0 = array(); private $useIncludePath = false; private $classMap = array(); private $classMapAuthoritative = false; ~~~ * * * * * >[info] 成員方法 PSR-0 > getPrefixes() 獲取前綴設置 `public function getPrefixes()` > getFallbackDirs() 獲取搜索目錄 `public function getFallbackDirs()` > add() 添加搜索目錄 `public function add($prefix, $paths, $prepend = false)` > setPsr4() 修改搜索目錄前綴索引 `public function set($prefix, $paths)` PSR-4 > getPrefixesPsr4() 獲取前綴設置 ` public function getPrefixesPsr4()` > getFallbackDirsPsr4() 獲取搜索目錄 `public function getFallbackDirsPsr4()` > addPsr4() 添加搜索目錄 `public function addPsr4($prefix, $paths, $prepend = false)` > setPsr4() 修改搜索目錄前綴索引 `public function setPsr4($prefix, $paths)` 其他 > getClassMap() 獲取類名映射信息 `public function getClassMap()` > addClassMap() 添加類名映射信息 `public function addClassMap(array $classMap)` > setUseIncludePath() 設置是否搜索include_path `public function setUseIncludePath($useIncludePath)` > getUseInlcudePath() 獲取是否搜索include_path public function getUseIncludePath() > register() 注冊加載函數 `public function register($prepend = false)` > unregister() 注銷加載函數 public function unregister() > loadClsss() 加載目標類 `public function loadClass($class)` > findFile() 搜索類目標文件 `public function findFile($class)` > findFileWithExtension() 指定擴展名搜索文件 `private function findFileWithExtension($class, $ext)` >[info] 3 其他文件 autoload_classmap.php autoload_files.php autoload_namespaces.php autolaod_psr4.php 以**數組形式**返回需要操作的**映射信息**。 ## 5 tp5的自動加載實現 thinkphp5的自動加載實現在Loader.php文件 分析見 [附:(Loader.php)自動加載](http://www.hmoore.net/zmwtp/tp5/119431)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看