2010-03-18 14 views
2

我是一個越來越多的PHP + QuickBooks相關代碼庫的作者。我想利用PHP __autoload()函數,但是我的代碼是一個庫,其他人可以包含()到他們自己的應用程序中,所以我不能依賴__autoload()尚未定義。PHP多個__autoload函數*沒有使用spl_register_autoload?

有沒有辦法讓多個__autoload()函數?

我在PHP手冊看到spl_autoload_register(),不是我的所有用戶都安裝了SPL擴展,所以我不能依靠這一點。如果有一種方法可以回退到使用它並默認使用正常的require/include語句,我可能會考慮這一點。

有沒有其他人有任何其他聰明的解決方案來解決這個問題?這似乎是一個明顯的監督,只能有一個單一的__autoload()函數...

+0

嗯,我認爲問題的答案(一個__autoload)是spl_autoload_register。現在已經很標準了 –

回答

7

我看到PHP手冊spl_autoload_register(),但不是所有的用戶都安裝了SPL擴展,所以我不能依靠這一點。

忽略它們,默認編譯它,甚至在5.3.0中都不能被禁用。不要爲了取悅少數人而犧牲你的框架。

+1

這不是一個選項,也不是答案。可能有50%的用戶沒有啓用SPL,並且無法自行升級PHP(共享主機)。兼容性是最重要的類庫,尤其是那些讓我付錢的類庫。 –

+3

用一些常識將他們指向託管服務提供商。我很想聽聽他們禁用SPL的原因。更好的是,向主機提供商投訴並索取。 –

+3

相信我,我已經抱怨,並得到旁邊沒有有用的迴應。其中一些人安裝了使用與SPL衝突的類名稱的應用程序,其中一些人擁有愚蠢的託管服務提供商,一些託管服務提供商懶得進行升級等等等等。如果我按照自己的方式,每個人都會在5.3.0上,我不必擔心這一點。但是,這並不是我可以強迫他們做出的決定,不會丟失一堆錢,也不會讓很多人感到不安。 Soooo ...我需要一個不依賴於SPL的解決方案。 –

3

我已經決定要走這條路並且保持向後兼容性的方法是編寫我自己的「Loader」類。

而不是使用require_once'TheFile.php',我現在使用Loader :: load('TheFile.php');.該裝載機:: load()方法執行以下操作:

if (the function spl_autoload_register exists) 
    register an autoloader 
    return true 
else 
    check if the file has already been included (static array var with a list of files) 
    if not included yet 
     require $file 
    return true 

這讓我使用自動加載磁帶機,如果他們的PHP安裝都支持它,否則回落到只是做正常需要$文件中的靈活性;類型的東西。

+0

Loader :: load('TheFile.php');'over'require_once'TheFile.php';'?自動加載器的意義在於它們省略了PHP文件的顯式加載。 – niutech

+0

如果他們的PHP安裝支持自動加載器,它將使用自動加載器(例如,在這種情況下,Loader :: load(..)什麼都不做)。如果它不*支持自動加載器,那麼它確實require_once。如果可以使用自動加載器,則可以顯着提高性能,但仍然保持向後兼容。 –

1

您可以編寫一個__autoload函數,該函數只需循環執行實際類加載的回調數組,直到找到該類或列表已耗盡。

function loader1 ($className) 
{ 
    if (is_file ('foo/' . $clasName)) 
    { 
     include ('foo/' . $className); 
     return (true); 
    } 
} 

function loader2 ($className) 
{ 
    if (is_file ('bar/' . $clasName)) 
    { 
     include ('bar/' . $className); 
     return (true); 
    } 
} 

function loader3 ($className) 
{ 
    if (is_file ('baz/' . $clasName)) 
    { 
     include ('baz/' . $className); 
     return (true); 
    } 
} 

function __autoload ($className) 
{ 
    $autoloaders = array (
     'loader1', 
     'loader2', 
     'loader3' 
    ); 
    foreach ($autoloaders as $loader) 
    { 
     if ($loader ($className)) 
     return (true); 
    } 
    throw new Exception ('Failed to find class ' . $className); 
} 

注意:這是「關閉袖口」,我沒有測試過它。