我不知道我是否正确理解了问题的标题,但我怀疑我在从命名空间类创建对象时面临的问题。
所以,这个项目在项目的根目录中有一个 index.php 和一个 Inc 文件夹。 inc 文件夹有文件夹 - Base(带有
Enqueue.php), Pages (with 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' 中搜索类?不过我的代码工作正常。我对命名空间如何工作的理解不正确还是我错过了
最佳答案
文字是针对当前命名空间解析的,字符串总是被假定/期望/要求是完全限定的名称。
这是你的文字:
namespace Inc;
Pages\Admin::class
这个文字
Pages\Admin
针对当前命名空间解析并解析为 Inc\Pages\Admin
.所以Pages\Admin::class
的值这是'Inc\Pages\Admin'
.然后你传递这个字符串并最终做:new $class() // where $class = 'Inc\Pages\Admin'
由于您是从字符串实例化,因此该字符串被视为完全限定名称,并且不会针对当前命名空间进行解析。正是因为字符串可以在命名空间之间传递,并且不可能清楚地知道它们应该属于哪个命名空间。
关于php - 在另一个命名空间类中实例化命名空间类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57050023/