我不知道我的问题标题是否正确,但是我怀疑从命名空间类创建对象时会遇到什么问题。
因此,该项目在项目的根目录内有一个index.php和一个Inc文件夹。 inc文件夹包含以下文件夹-基本(带有 Enqueue.php),Pages(带有Admin.php)和Init.php。在index.php中,我们是 自动加载Inc文件夹(具有Inc的命名空间)并调用 Init类中的register_services()
这是index.php文件:
<?php
if ( file_exists( dirname( __FILE__ ) . '/vendor/autoload.php' ) ) {
require_once dirname( __FILE__ ) . '/vendor/autoload.php';
if ( class_exists( 'Inc\\Init' ) ) {
Inc\Init::register_services();
}
}
Inc / Base / Enqueue.php
<?php
namespace Inc\Base;
class Enqueue
{
public function register() {
echo 'enque register';
}
Inc / Pages / Admin.php:
<?php
namespace Inc\Pages;
class Admin
{
public function register() {
echo 'admin register';
}
}
Inc / Init.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 [
Pages\Admin::class, // why Pages\Admin
Base\Enqueue::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 [
Pages\Admin::class,
Base\Enqueue::class
];
}
这将作为数组的类的合格名称返回为Inc \ Pages \ Admin和Inc \ Base \ Enqueue。稍后,我们在下面的示例中实例化该类。 初始化类:
private static function instantiate( $class )
{
echo $class;
$service = new $class();
return $service;
}
我的问题是,因为我们已经在Init类的名称空间Inc中,所以不会通过再次从Inc开始调用该类来实例化该类(即Inc \ Pages \ Admin或Inc \ Base \ Enqueue)使它在名称空间“ Inc \ Inc \ Pages \ Admin”或“ Inc \ Inc \ Pages \ Enqueue”中搜索类?我的代码可以正常工作。是我对名称空间的工作方式了解不正确,还是缺少
答案 0 :(得分:1)
文字是针对当前名称空间解析的,始终假定/期望/要求字符串为完全限定名称。
这是你的文字:
namespace Inc;
Pages\Admin::class
此文字Pages\Admin
针对当前名称空间进行解析,并解析为Inc\Pages\Admin
。因此这里的Pages\Admin::class
的值为'Inc\Pages\Admin'
。然后,您将该字符串传递给周围并最终完成:
new $class() // where $class = 'Inc\Pages\Admin'
由于您是从字符串实例化的,因此该字符串被视为完全限定的名称,并且不会根据当前名称空间解析 。正是因为可以在名称空间之间传递字符串,并且不可能清楚地知道它们应该属于哪个名称空间。