我不知道我是否正确理解了问题的标题,但我在从命名空间类创建对象时遇到了疑问。
因此,此项目在项目的根目录中有一个索引.php和一个 Inc 文件夹。inc 文件夹有文件夹 - 基本 ( 与 Enqueue.php)、Pages (with Admin.php) 和 Init.php .在指数中.php我们是 自动加载 Inc 文件夹(其命名空间为 Inc )并调用 register_services() 在 Init 类中
这是索引.php文件:
<?php
if ( file_exists( dirname( __FILE__ ) . '/vendor/autoload.php' ) ) {
require_once dirname( __FILE__ ) . '/vendor/autoload.php';
if ( class_exists( 'Inc\Init' ) ) {
IncInit::register_services();
}
}
Inc/Base/Enqueue.php
<?php
namespace IncBase;
class Enqueue
{
public function register() {
echo 'enque register';
}
Inc/Pages/Admin.php :
<?php
namespace IncPages;
class Admin
{
public function register() {
echo 'admin register';
}
}
公司/初始化.php :
<?php
namespace Inc;
final class Init
{
/**
* Store all the classes inside an array
* @return array Full list of classes
*/
public static function get_services()
{
return [
PagesAdmin::class, // why PagesAdmin
BaseEnqueue::class
];
}
/**
* Loop through the classes, initialize them,
* and call the register() method if it exists
* @return
*/
public static function register_services()
{
foreach ( self::get_services() as $class){
$service = self::instantiate( $class );
if ( method_exists( $service, 'register' ) ) {
$service->register();
}
}
}
/**
* Initialize the class
* @param class $class class from the services array
* @return class instance new instance of the class
*/
private static function instantiate( $class )
{
echo $class;
$service = new $class();
return $service;
}
}
所以在 Init 类中,我们有:
public static function get_services()
{
return [
PagesAdmin::class,
BaseEnqueue::class
];
}
这将以数组的形式返回 Inc\Pages 类的限定名称 \管理员和公司\基本\排队 。稍后我们将类实例化,如下所示 初始化类:
private static function instantiate( $class )
{
echo $class;
$service = new $class();
return $service;
}
我的问题是,由于我们已经在 Init 类的命名空间 Inc 中,不会通过再次从 Inc 开始调用它来实例化该类(即 Inc \Pages\Admin or Inc\Base\Enqueue ) 引导它在命名空间 'Inc\Inc\Pages\Admin' 或 'Inc\Inc\Pages\Enqueue' 中搜索类?不过我的代码工作正常。我对命名空间如何工作的理解不正确还是我错过了
文本是针对当前命名空间解析的,字符串始终假定/预期/要求是完全限定名。
这是你的文字:
namespace Inc;
PagesAdmin::class
此文本PagesAdmin
针对当前命名空间解析,并解析为IncPagesAdmin
。所以这里PagesAdmin::class
的价值是'IncPagesAdmin'
.然后,您传递此字符串并最终执行以下操作:
new $class() // where $class = 'IncPagesAdmin'
由于您是从字符串实例化的,因此该字符串被视为完全限定名称,并且不会针对当前命名空间进行解析。正是因为字符串可以在命名空间之间传递,并且不可能清楚地知道它们应该属于哪个命名空间。