2015-06-17 32 views
3

我看到這些,如何自動加載文件名與類名不同的類?

How to autoload class with a different filename? PHP

Load a class with a different name than the one passed to the autoloader as argument

我可以改變,但在我的MV *結構,我有:

/models 
    customer.class.php 
    order.class.php 
/controllers 
    customer.controller.php 
    order.controller.php 
/views 
... 

在實際階級是這樣,

class CustomerController {} 
class OrderController{} 
class CustomerModel{} 
class OrderModel{} 

我試圖與名稱保持一致。如果我不把類名稱後綴(控制器,模型),我不能加載類,因爲這是重新聲明。

如果我把我的類的名稱,自動加載失敗,因爲它會尋找名爲

CustomerController 

當文件名是一個真正的類文件,

customer.controller.php 

是我的唯一途徑(在無順序):

  • 使用create_alias
  • 重命名我的文件(customer.model.php到customermodel.php)
  • 重命名我的班
  • 使用正則表達式
  • 使用的包含文件的引導(includerequire_once等)

示例代碼,

function model_autoloader($class) { 
    include MODEL_PATH . $class . '.model.php'; 
} 

spl_autoload_register('model_autoloader'); 

看來我要重命名文件,

http://www.php-fig.org/psr/psr-4/

「的終端類名稱對應於.php結尾的文件名,文件名必須匹配終止類名稱的情況。「

+2

嗯,是的,無論是讓你命名簡單或使你的自動加載磁帶機足夠的智能來處理您的複雜的名字。你可以在自動加載器中做任何你需要的事情;如果您的命名模式可以用代碼表示,您可以在自動加載器中實現它。 – deceze

+0

您的自動加載器不需要符合PSR-4。您不使用Composer,而是通過'spl_autoload_register()'定製函數。您可以考慮在自動加載函數中使用'file_exists()'檢查兩者。 –

+0

@deceze我希望有一個神奇的PHP方式來做到這一點。我做得太難了。感謝幫助。 – johnny

回答

1

在我看來這可以用一些基本的字符串操作來處理和一些約定。

define('CLASS_PATH_ROOT', '/'); 

function splitCamelCase($str) { 
    return preg_split('/(?<=\\w)(?=[A-Z])/', $str); 
} 

function makeFileName($segments) { 
    if(count($segments) === 1) { // a "model" 
     return CLASS_PATH_ROOT . 'models/' . strtolower($segments[0]) . '.php'; 
    } 

    // else get type/folder name from last segment 
    $type = strtolower(array_pop($segments)); 

    if($type === 'controller') { 
     $folderName = 'controllers'; 
    } 
    else { 
     $folderName = $type; 
    } 

    $fileName = strtolower(join($segments, '.')); 

    return CLASS_PATH_ROOT . $folderName . '/' . $fileName . '.' . $type . '.php'; 
} 

$classNames = array('Customer', 'CustomerController'); 

foreach($classNames as $className) { 
    $parts = splitCamelCase($className); 

    $fileName = makeFileName($parts); 

    echo $className . ' -> '. $fileName . PHP_EOL; 
} 

輸出是

客戶 - > /models/customer.php

CustomerController - > /controllers/customer.controller.php

現在,您需要在自動加載器功能中使用makeFileName

我自己強烈反對這樣的東西。我會使用反映命名空間和類名的命名空間和文件名。我也會用Composer

(我發現splitCamelCasehere

+0

你能解釋一下你對命名空間的意思嗎?我知道什麼是命名空間,但我不確定你要做什麼。我如何命名我的類,所以我不必使用字符串操作? – johnny

+1

我不清楚。使用該命名方案和文件夾結構命名空間將是毫無意義的。有一個'Controllers'命名空間,用於轉儲應用程序中的控制器是無用的。我的意思是,我會盡快切換到有意義的命名空間('Customers \\ Controllers - > Customer')和Composer默認處理的文件名('customers/controllers/customer.php')。 –