2015-04-07 121 views
1

我已經設置了一個簡單的自動加載來了解與命名空間一起工作時的原則。PHP - 命名空間和自動加載問題

test.php的:

namespace House; 

function __autoload($classname) 
{ 
    $parts = explode('\\', $classname); 

    $class = 'Room/'.end($parts).'.php'; 

    require_once($class); 
} 


$Toy = new Toy(); 
echo $Toy->hello(); 

房/ Toy.php:

namespace House; 

class Toy 
{ 
    public function hello() { return "HELLO"; } 
} 

在聲明$玩具我得到致命錯誤:類 '樓\玩具' 未找到在線18 test.php

我在這裏沒有什麼錯?

當拆卸__autoload功能,而不是僅僅在

require_once('Room/Toy.php'); 

它的工作原理把!

回答

1

test.php應該是這樣的:

use House\Toy as Toy; 

function __autoload($classname) 
{ 
    $parts = explode('\\', $classname); 
    $class = 'Room/'.end($parts).'.php'; 
    require_once($class); 
} 

$Toy = new Toy(); 
echo $Toy->hello(); 

如果您在文件的頂部將namespace House,在該文件中聲明的所有功能,將屬於命名空間House。含義__autoload()得到的House\__autoload(),並將其鬆動的魔術的含義。

另一件事,將名稱空間House的文件存儲在名爲House的文件夾中不是更好嗎? (您目前正在使用Room)。使用

function __autoload($classname) 
{ 
    $parts = explode('\\', $classname); 
    $path = implode('/', $parts) . '.php'; 
    require_once($path); 
} 
+0

您的意思是說__autoload根本就沒有被調用,如果之前聲明瞭名稱空間呢?我知道結構很糟糕,這是我試着真正理解命名空間。 – DJJQ

+0

是的,我的意思是。它沒有被調用,因爲它沒有被執行。你只實現了'House \ __ autoload()',但PHP會調用'\ __ autoload()',這意味着在全局命名空間中定義的'__autoload()'。然而,你可以使用'spl_autoload_register()'來使用你希望的任何名字空間(和/或類)的任何函數。 – hek2mgl

+0

好了,現在我明白了。感謝您的幫助! – DJJQ

0

試試這個自動加載,而不是:)和目錄間的絕對路徑添加到您的包含路徑:如果你這樣做,__autoload()功能可以更一般寫。 Inside Room裏有另外一個叫做House的地方,其中的Toy.php將被定位。

<?php 

spl_autoload_register (function ($className, $fileExtensions = null) { 
    $className = str_replace ('_', '/', $className); 
    $className = str_replace ('\\', '/', $className); 
    $file = stream_resolve_include_path ($className . '.php'); 
    if ($file !== false) { 
     include $file; 
     return true; 
    } 
    return false; 
});