PHP中Autoload使用中的一些問題
PHP中提供了Autoload來幫助我們方便的進行檔案的包含,但是autoload並非想象的那樣能夠處理所有的情況,今天就來記錄一下前幾天遇到的autoload存在的一些問題。
為什麼要使用 Autoload。
在PHP中使用類時,我們必須在使用前載入進來,不管是通過 require 的方式還是 include 的方式,但是會有兩個問題影響我們做出載入的決定。
首先是不知道這個類檔案存放在什麼地方,另外一個就是不知道什麼時候需要用到這個檔案。特別是專案檔案特別多時,不可能每個檔案都在開始的部分寫很長一串的 require ….
在PHP5之後,我們可以通過 __autoload來解決這個問題。 而且在PHP5.1之後,還提供了 spl_autoload_register() 來提供更完善的載入機制。
通過閱讀了 Autoloading in PHP 這篇文章,我理解的 Autoload 的載入機制,當通過 new 來例項化一個類時,PHP會通過定義的__autoload 函式載入相應的檔案,如果這個類檔案使用了 extends 或者 implements 需要用到其他的類檔案,php會重新執行 autoload 去進行類檔案的查詢和載入,如果發生了兩次對同一類檔案的請求,就會報錯。原文作者提供了三個很有趣的例子來說明這個問題,可以通過 這裡 下載原始碼檢視。
一般情況下,有很多種方法來解決載入時到相應位置查詢檔案的方法。用的最多的就是指定特定的命名標準。
Zend的方法。
zend推薦了一種最流行的辦法,在檔名中包含路徑。例如下面的例子:
// Main.class
function __autoload($class_name) {
$path = str_replace(`_`, DIRECTORY_SEPARATOR, $class_name);
require_once $path.`.php`;
}
$temp = new Main_Super_Class();
所有的下劃線都會被替換成路徑中的分隔符,上例中就會去 Main/Super/Class.php檔案
這種方法的缺點是在編碼過程中,我們必須明確的知道程式碼檔案應當所處的位置,而且由於
將檔案路徑硬編碼在了類名中,如果需要修改資料夾的結構時,我們必須手工修改所有的類名。
`Include All’方法
如果是在一個開發環境中,並且對於速度不是很在意的話,使用這個方法是非常方便的。通過將所有類檔案放在一個或幾個特定資料夾中,然後通過遍歷的方式查詢載入。
例如:
<?php
$arr = array (`Project/Classes`,
`Project/Classes/Children`,
`Project/Interfaces`
);
foreach($arr as $dir) {
$dir_list = opendir($dir);while ($file = readdir($dir_list)) {
$path = $dir.DIRECTORY_SEPARATOR.$file;if(in_array($file, array(`.`, `..`)) || is_dir($path))
continue;
if (strpos($file, “.class.php”))
require_once $path;}
}
?>
關聯檔案和位置
另外一個方法是在類檔案和他的位置之間建立關聯的配置檔案,例如:
// configuration.php
array_of_associations = array(`MainSuperClass` = `C:/Main/Super/Class.php`,
`MainPoorClass` = `C:/blablabla/gy.php`
);
呼叫的檔案
<?php
require `autoload_generated.php`;function __autoload($className) {
global $autoload_list;require_once $autoload_list[$className];
}
$x = new A();
?>
當然,如果檔案特別多的時候,維護起來會是一件麻煩事,但是與在類名中硬編碼位置,哪個更好呢? ?
我們當然不希望手工來維護這個列表,那麼可以使用自動生成這個檔案來實現,這個對應關係的檔案可以是phpxmljson等等。原文的作者實現了一個這樣的工具,仔細考慮一下的話,這個不是很難實現,原文作者甚至發展了一個小型的 Autoload 框架,值得學習。
參考資料:
2、Autoloading Classes
3、Autoload problem with static variables
4、Class autoloades earlier when using APC
相關文章
- JavaScript 中的一些奇怪問題JavaScript
- 教你如何解決PostgreSQL Array使用中的一些小問題SQL
- 面試中遇到的一些問題面試
- PHP中 mkdir: Permission denied 問題PHP
- 使用springboot中的springdatajpa寫一個demo遇到一些問題Spring Boot
- 小程式專案中的一些小問題
- vue工作中遇到的一些小問題Vue
- 分散式系統中的一些問題分散式
- Leetcode刷題中關於java的一些小問題LeetCodeJava
- Filebeat和logstash 使用過程中遇到的一些小問題記錄
- laravel使用中遇到的問題Laravel
- 專案中遇到的一些問題小結
- CRM系統實施中的一些問題?
- weex使用中的問題記錄
- Typora 使用中的幾個問題
- thrift使用過程中的問題
- php中foreach的使用PHP
- 工作中遇到的一些問題和處理
- 阿里面試中遇到的一些架構問題阿里面試架構
- 關於Java中分層中遇到的一些問題Java
- 單例模式中可能存在的一些問題(執行緒安全問題)單例模式執行緒
- Vue使用中遇到的程式碼問題Vue
- 聊聊使用FURPS模型做資料庫選型評估中的一些問題模型資料庫
- 當前NLP遷移學習中的一些問題遷移學習
- 前端開發中遇到的一些問題----持續更新前端
- LVGL 中圖片使用問題
- Deployer 使用過程的一些問題
- PHP flock 檔案鎖的使用問題PHP
- Docker實踐過程中遇到的一些問題總結(持續更新中)Docker
- pycharm+python使用中的相關問題PyCharmPython
- autohotkey qt程式中無法使用的問題QT
- 在 React 中處理資料流問題的一些思考React
- 整理debian安裝過程中的一些問題與方法
- OAuth2學習中的一些高頻問題的QAOAuth
- PHP 執行時 Composer dump-autoload 安全替代PHP
- Redis中的問題Redis
- 關於轉義符 在php正則中的匹配問題PHP
- html檔案中的php程式碼被註釋掉的問題HTMLPHP
- PHP中Trait的使用總結PHPAI