在php中,自動(dòng)加載一般都是通過魔術(shù)方法__autoload來實(shí)現(xiàn)的,在程序中,當(dāng)需要一個(gè)類的定義文件時(shí)(如實(shí)例化一個(gè)對(duì)象,集成自一個(gè)類),如找不到類定義文件時(shí),就會(huì)自動(dòng)觸發(fā)__autoload方法,所以我們可以在該方法中編寫代碼完成類的加載。要編寫代碼實(shí)現(xiàn)類的自動(dòng)加載,很重要的兩點(diǎn)一是文件結(jié)構(gòu)規(guī)劃,二是類的命名,尤其是命名,從命名中要體現(xiàn)出該類的所屬文件,比如PersonController,一看就知道是一個(gè)控制器,UserModel,一看便知是模型,這樣就可以到對(duì)應(yīng)的目錄下去加載該類。針對(duì)你所列出的文件結(jié)構(gòu)和文件命名,顯然不符合上述規(guī)則,所以想通過__autoload實(shí)現(xiàn)自動(dòng)加載有難度。
創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比尋烏網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式尋烏網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋尋烏地區(qū)。費(fèi)用合理售后完善,10余年實(shí)體公司更值得信賴。
很多開發(fā)者寫面向?qū)ο蟮膽?yīng)用程序時(shí)對(duì)每個(gè)類的定義建立一個(gè) PHP 源文件。一個(gè)很大的煩惱是不得不在每個(gè)腳本開頭寫一個(gè)長(zhǎng)長(zhǎng)的包含文件列表(每個(gè)類一個(gè)文件)。
在 PHP 5 中,不再需要這樣了。可以定義一個(gè) __autoload() 函數(shù),它會(huì)在試圖使用尚未被定義的類時(shí)自動(dòng)調(diào)用。通過調(diào)用此函數(shù),腳本引擎在 PHP 出錯(cuò)失敗前有了最后一個(gè)機(jī)會(huì)加載所需的類。
Tip
spl_autoload_register() 提供了一種更加靈活的方式來實(shí)現(xiàn)類的自動(dòng)加載。因此,不再建議使用 __autoload() 函數(shù),在以后的版本中它可能被棄用。
Note:
在 5.3.0 版之前,__autoload 函數(shù)拋出的異常不能被 catch 語(yǔ)句塊捕獲并會(huì)導(dǎo)致一個(gè)致命錯(cuò)誤。從 5.3.0+ 之后,__autoload 函數(shù)拋出的異常可以被 catch 語(yǔ)句塊捕獲,但需要遵循一個(gè)條件。如果拋出的是一個(gè)自定義異常,那么必須存在相應(yīng)的自定義異常類。__autoload 函數(shù)可以遞歸的自動(dòng)加載自定義異常類。
Note:
自動(dòng)加載不可用于 PHP 的 CLI 交互模式。
Note:
如果類名比如被用于 call_user_func(),則它可能包含一些危險(xiǎn)的字符,比如 ../。 建議您在這樣的函數(shù)中不要使用用戶的輸入,起碼需要在__autoload() 時(shí)驗(yàn)證下輸入。
Example #1 自動(dòng)加載示例
本例嘗試分別從 MyClass1.php 和 MyClass2.php 文件中加載 MyClass1 和 MyClass2 類。
?php
function __autoload($class_name) {
require_once $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?
Example #2 另一個(gè)例子
本例嘗試加載接口 ITest。
?php
function __autoload($name) {
var_dump($name);
}
class Foo implements ITest {
}
/*
string(5) "ITest"
Fatal error: Interface 'ITest' not found in ...
*/
?
Example #3 自動(dòng)加載在 PHP 5.3.0+ 中的異常處理
本例拋出一個(gè)異常并在 try/catch 語(yǔ)句塊中演示。
?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";
}
?
以上例程會(huì)輸出:
Want to load NonLoadableClass.
Unable to load NonLoadableClass.
Example #4 自動(dòng)加載在 PHP 5.3.0+ 中的異常處理 - 沒有自定義異常機(jī)制
本例將一個(gè)異常拋給不存在的自定義異常處理函數(shù)。
?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";
}
?
以上例程會(huì)輸出:
Want to load NonLoadableClass.
Want to load MissingException.
Fatal error: Class 'MissingException' not found in testMissingException.php on line 4
不僅僅thinkphp,MVC框架思路是一樣的。主要在一個(gè)核心類完成。
tp 是在App.class.php里完成。
1,讀取配置
配置文件里的配置
2,自動(dòng)加載
核心類文件比如數(shù)據(jù)庫(kù)類文件,模板文件等,模型類文件等
自動(dòng)加載,模塊,控制器等。
3,請(qǐng)求分發(fā)
實(shí)例化控制器。執(zhí)行邏輯業(yè)務(wù)。
總之,這個(gè)文件完成把得到數(shù)據(jù)層數(shù)據(jù),再分發(fā)到模板層。
說來簡(jiǎn)單,其實(shí)也有點(diǎn)小復(fù)雜。
php 中有個(gè)魔術(shù)方法__autoload ,這個(gè)函數(shù)在找不到類的時(shí)候就會(huì)調(diào)用,自動(dòng)加載就是在這里實(shí)現(xiàn)的。通過指定自動(dòng)加載類的路徑,只要保證文件名和類名一樣。就可以自動(dòng)加載。這也是為什么你看很多源碼中類的名字和文件名一樣的原因,這樣可以實(shí)現(xiàn)自動(dòng)加載,不需要include.
這個(gè)和ajax技術(shù)密切相關(guān).
ajax技術(shù)通俗來講 就是保證頁(yè)面不刷新的情況下.吧數(shù)據(jù)通過服務(wù)端展現(xiàn)給瀏覽器.
所以這里樓主可以使用ajax來實(shí)現(xiàn).一下給出一個(gè)ajax例子
select?id="select"
option/option
/select
//此時(shí)select框是沒有任何數(shù)據(jù)的
給他加上value值改變觸發(fā)的事件
$("#select").change(function(){
$.get('index.php',data,function(res){
$("#select").append('option?value="'+res.val+'"'+res.content+'/option');//把獲取到的信息append到select框下
},'json');
});
//或者樓主是要這種情況.選中select的其中某個(gè)選項(xiàng)在加載數(shù)據(jù)
select?id="select"
option?value="1"/option
/select
$("#select").change(function(){
//這里假設(shè)選中了value?=1的option
var?val?=?$("#select").val();
$.get('index.php',{value:val},function(res){
sonsole.log(res);//打印從服務(wù)器獲取到的信息
},'json');
});
傳統(tǒng)上,在PHP里,當(dāng)我們要用到一個(gè)class文件的時(shí)候,我們都得在文檔頭部require或者include一下:
?php
require_once('../includes/functions.php');
require_once('../includes/database.php');
require_once('../includes/user.php');
...
但是一旦要調(diào)用的文檔多了,就得每次都寫一行,瞅著也不美觀,有什么辦法能讓PHP文檔自動(dòng)加載呢?
?php
function
__autoload($class_name)
{
require
"./{$class_name}.php";
}
對(duì),可以使用PHP的魔法函數(shù)__autoload(),上面的示例就是自動(dòng)加載當(dāng)前目錄下的PHP文件。當(dāng)然,實(shí)際當(dāng)中,我們更可能會(huì)這么來使用:
?php
function
__autoload($class_name)
{
$name
=
strtolower($class_name);
$path
=
"../includes/{$name}.php";
if(file_exists($path)){
require_once($path);
}else{
die("the
file
{$class_name}
could
not
be
found");
}
}
也即是做了一定的文件名大小寫處理,然后在require之前檢查文件是否存在,不存在的話顯示自定義的信息。
類似用法經(jīng)常在私人項(xiàng)目,或者說是單一項(xiàng)目的框架中見到,為什么呢?因?yàn)槟阒荒芏x一個(gè)__autoload
function,在多人開發(fā)中,做不到不同的developer使用不同的自定義的autoloader,除非大家都提前說好了,都使用一個(gè)__autoload,涉及到改動(dòng)了就進(jìn)行版本同步,這很麻煩。
也主要是因?yàn)榇耍袀€(gè)好消息,就是這個(gè)__autoload函數(shù)馬上要在7.2版本的PHP中棄用了。
Warning
This
feature
has
been
DEPRECATED
as
of
PHP
7.2.0.
Relying
on
this
feature
is
highly
discouraged.
那么取而代之的是一個(gè)叫spl_autoload_register()的東東,它的好處是可以自定義多個(gè)autoloader.
//使用匿名函數(shù)來autoload
spl_autoload_register(function($class_name){
require_once('...');
});
//使用一個(gè)全局函數(shù)
function
Custom()
{
require_once('...');
}
spl_autoload_register('Custom');
//使用一個(gè)class當(dāng)中的static方法
class
MyCustomAutoloader
{
static
public
function
myLoader($class_name)
{
require_once('...');
}
}
//傳array進(jìn)來,第一個(gè)是class名,第二個(gè)是方法名
spl_autoload_register(['MyCustomAutoloader','myLoader']);
//甚至也可以用在實(shí)例化的object上
class
MyCustomAutoloader
{
public
function
myLoader($class_name)
{
}
}
$object
=
new
MyCustomAutoloader;
spl_autoload_register([$object,'myLoader']);
值得一提的是,使用autoload,無論是__autoload(),還是spl_autoload_register(),相比于require或include,好處就是autoload機(jī)制是lazy
loading,也即是并不是你一運(yùn)行就給你調(diào)用所有的那些文件,而是只有你用到了哪個(gè),比如說new了哪個(gè)文件以后,才會(huì)通過autoload機(jī)制去加載相應(yīng)文件。
當(dāng)然,laravel包括各個(gè)package里也是經(jīng)常用到spl_autoload_register,比如這里:
/**
*
Prepend
the
load
method
to
the
auto-loader
stack.
*
*
@return
void
*/
protected
function
prependToLoaderStack()
{
spl_autoload_register([$this,
'load'],
true,
true);
}