2013-09-27 22 views
2

最近我正在學習Zend框架2,而且也討厭我很長一段時間的問題,事情是這樣的:Zend的framework2請問怎麼自動加載功能工作

<?php 
namespace Album\Model; 

// Add these import statements 
use Zend\InputFilter\InputFilter; 
use Zend\InputFilter\InputFilterAwareInterface; 
use Zend\InputFilter\InputFilterInterface; 

class Album implements InputFilterAwareInterface 
{ 
    public $id; 
    public $artist; 
    public $title; 
    protected $inputFilter; 

    public function exchangeArray($data) 
    { 
     $this->id  = (isset($data['id']))  ? $data['id']  : null; 
     $this->artist = (isset($data['artist'])) ? $data['artist'] : null; 
     $this->title = (isset($data['title'])) ? $data['title'] : null; 
    } 

    // Add content to these methods: 
    public function setInputFilter(InputFilterInterface $inputFilter) 
    { 
     throw new \Exception("Not used"); 
    } 

    //.... 
    ?> 

此代碼是A項「骨架應用程序「程序,這是ZF2的教程。我第一次看到這個程序,我不明白「namespace」和「use」的用法是什麼,因爲這兩個關鍵字在php5.2中不存在(在早期版本中也一樣),所以我去了看手冊,並試圖瞭解它。我寫一個程序來模擬到底發生了什麼:

<?php 
use script\lib\test; 

$o = new test(); 
echo $o->getWelcome(); 

function __autoload($className) { 
$classname = strtolower($classname); 
require_once(dirname(__FILE__) . '/' . $classname . '.php'); 
} 
?> 

上面的程序效果很好,當然我創建了一個名爲腳本和lib兩個文件夾,並有一個測試文件命名.PHP。 似乎每一件事情都很清楚,zend框架還具有自動加載功能,但是當我注意到「骨架應用程序」中的代碼時,開始時有一個名稱空間,所以我也將該名稱空間添加到我的程序中:

<?php 
namespace test; 
use script\lib\test; 

$o = new test(); 
echo $o->getWelcome(); 

function __autoload($className) { 
$classname = strtolower($classname); 
require_once(dirname(__FILE__) . '/' . $classname . '.php'); 
} 
?> 

返回的頁面我inforamtion如下: 致命錯誤:類 '腳本\ LIB \測試' 在電子商務未發現:\ WAMP \ WWW \第6行

我試圖測試\ test_29.php更改命名空間的名稱,如腳本\ lib,腳本\ lib \ test ... 但它沒用。

任何答案將不勝感激,謝謝。


現在,我會給你這個問題的詳細信息: 要了解的「命名空間」的使用和「使用」,我看了材料相比於php.net: http://php.net/manual/en/language.namespaces.importing.php 在這個頁面中,有是一段代碼如下所示:

Example #1 importing/aliasing with the use operator

<?php 
namespace foo; 
use My\Full\Classname as Another; 

// this is the same as use My\Full\NSname as NSname 
use My\Full\NSname; 

// importing a global class 
use ArrayObject; 

$obj = new namespace\Another; // instantiates object of class foo\Another 
$obj = new Another; // instantiates object of class My\Full\Classname 
NSname\subns\func(); // calls function My\Full\NSname\subns\func 
$a = new ArrayObject(array(1)); // instantiates object of class ArrayObject 
// without the "use ArrayObject" we would instantiate an object of class 
?> 

現在讓我們回顧一下我在上面寫程序:

<?php 
namespace test; 
use script\lib\test; 

$o = new test(); 
echo $o->getWelcome(); 

function __autoload($className) { 
$classname = strtolower($classname); 
require_once(dirname(__FILE__) . '/' . $classname . '.php'); 
} 
?> 

這是一樣的,我想,以模擬例如,如果我們不使用自動加載功能:

<?php 
namespace test; 
use script\lib\test; 
require_once 'script/lib/test.php'; 

$o = new test(); 
echo $o->getWelcome(); 
?> 

它的工作原理也很好,但是當我使用__autoload函數加載類文件, 這裏有些不對勁。 我不知道問題出在哪裏,或者任何機構試圖編寫一個實例來將「Example#1」付諸實踐?我會等待你的回答。

+1

你可能想[瞭解PHP命名空間](http://www.youtube.com/watch?v=d1kDT8YFAhI) – Sam

回答

1

ZF2 docu

Zend\Loader\StandardAutoloader is designed as a PSR-0-compliant autoloader. It assumes a 1:1 mapping of the namespace+classname to the filesystem, wherein namespace separators and underscores are translated to directory separators.

瞭解更多關於:PSR-0

所以,如果你使用的命名空間獲取發送到磁帶自動加載並不像test類名。它看起來像YOUR_NAMESPACE\test。 YOUR_NAMESPACE是您在類中定義的名稱空間,namespace YOUR_NAMESPACE;

PSR-0是一個標準:您的名稱空間應反映您的文件系統。您只需用正斜槓替換反斜槓即可。或者_/,如果您使用ZF1中的僞命名空間。 (Album_Model_Album)

所以輸出發送到磁帶自動加載機,你會看到$className ..

4

我想你誤會這是怎麼回事的。

命名空間允許您或多或少地爲您的類創建「目錄」。因此,您可以創建\ Foo類和\ Test \ Foo類(其中\代表應用程序的「根」)。 自動加載工作的方式是您的文件鏡像您的命名空間。因此,foo.php將在您的自動加載的根源中,但您會爲\ Test \ Foo創建/test/foo.php use關鍵字有兩個用途。一個是alias class files,另一個是PHP 5.4或更高版本,將Trait引入當前課程。

現在,你的問題。首先,讓我們看看你的代碼

<?php 
namespace test; 
use script\lib\test; 

$o = new test(); 
echo $o->getWelcome(); 

這很混亂。你聲明瞭一個名字空間(你不需要在這裏做),但是你將它別名到腳本\ lib \ test。 PHP現在正在尋找一個名爲/script/lib/test.php的文件,您的錯誤消息說這個文件不存在。但你說文件確實存在讓我們來看看

public function getWelcome() { 
    return 'welcome'; 
} 

這不是一個類。這是一個功能。對於這個例子,你需要一個完整的類

<?php 
namespace script\lib; 
class test { 
    public function getWelcome() { 
     return 'welcome'; 
    } 
} 

最後,讓我們來談談自動加載。您不需要使用使用自動加載。您的自動加載器應該爲您負責。但是,您應該使用spl_autoload_register(),因爲__autoload()即將折舊。

+0

但也有一些不明確的,當然我知道沒有必要在我的程序中使用命名空間,我想要做的就是模擬ZF2來理解爲什麼在ZF2中我們可以用這種方式編寫代碼(比如我的線程中的第一個程序),那麼你能解釋一下ZF2中真正發生了什麼,爲什麼使用名稱空間沒有問題,在ZF2中一起使用,但我的程序不工作?或者你可以舉個例子嗎?非常感謝。 –

+0

如果您查看ZF2中的public/index.php,您會看到它不使用名稱空間。命名空間是一種面向對象的編程原則,正如@Machavity所說,它允許邏輯分隔你的類。 PHP本質上不是純粹的面向對象的。因此,與請求交互的第一件事(本例中爲index.php)通常沒有名稱空間,因爲它不是一個類,只是一個程序化文件來實例化自動加載器和應用程序對象。 – Adrian

+0

謝謝阿德里安,我想你給我一個很好的答案。 –