![](/img/trans.png)
[英]Why does PHP treat classes and functions differently regarding namespaces and autoload?
[英]PHP Autoload Classes Is Not Working With Namespaces
我試圖編寫以下代碼,但無法弄清楚為什么在 spl_autoload_register() 中找不到帶有命名空間的 class?
我得到的錯誤是:
警告:require_once(src/test\StringHelper.php):無法打開 stream:沒有這樣的文件或目錄
Autoloader.php 文件:
<?php
spl_autoload_register(function($classname){
require_once "src/$classname.php"; // NOT WORKING DYNAMICALLY
// require_once "src/StringHelper.php"; // WORKING WHEN HARD CODED
});
$stringHelper1 = new test\StringHelper(); // Class with namespace defined
echo $stringHelper1->hello() . PHP_EOL; // returns text
src 文件夾內的 StringHelper.php:
<?php namespace test;
class StringHelper{
function hello(){
echo "hello from string helper";
}
}
如果這有所作為,我也在使用 XAMPP。
正如評論中已經指出的那樣,除了 class 名稱之外,您需要刪除所有內容,如下所示:
$classname = substr($classname, strrpos($classname, "\\") + 1);
在自動加載 function 的上下文中:
spl_autoload_register(function($classname){
$classname = substr($classname, strrpos($classname, "\\") + 1);
require_once "src/{$classname}.php";
});
讓我們更進一步,利用自動加載 function 始終接收限定命名空間而不是相對命名空間這一事實:
<?php
namespace Acme;
$foo = new \Acme\Foo(); // Fully qualified namespace
$foo = new Acme\Foo(); // Qualified namespace
$foo = new Foo(); // Relative namespace
在所有三個實例中,我們的自動加載 function 總是以Acme\Foo
作為參數。 考慮到這一點,實現將命名空間和任何子命名空間映射到文件系統路徑的自動加載器策略相當容易 - 特別是如果我們在文件系統層次結構中包含頂級命名空間(在本例中為Acme
)。
例如,在我們的某個項目中給定這兩個類......
<?php
namespace Acme;
class Foo {}
Foo.php
<?php
namespace Acme\Bar;
class Bar {}
酒吧.php
...在此文件系統布局中...
my-project
`-- library
`-- Acme
|-- Bar
| `-- Bar.php
`-- Foo.php
...我們可以在命名空間 class 與其物理位置之間實現一個簡單的映射,如下所示:
<?php
namespace Acme;
const LIBRARY_DIR = __DIR__.'/lib'; // Where our classes reside
/**
* Autoload classes within the current namespace
*/
spl_autoload_register(function($qualified_class_name) {
$filepath = str_replace(
'\\', // Replace all namespace separators...
'/', // ...with their file system equivalents
LIBRARY_DIR."/{$qualified_class_name}.php"
);
if (is_file($filepath)) {
require_once $filepath;
}
});
new Foo();
new Bar\Bar();
另請注意,您可以注冊多個自動加載函數,例如,處理不同物理位置的不同頂級命名空間。 但是,在實際項目中,您可能希望熟悉 Composer 的自動加載機制:
在某些時候,您可能還想查看 PHP 的自動加載規范:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.