php - 在另一个命名空间类中实例化命名空间类

标签 php namespaces

我不知道我是否正确理解了问题的标题,但我怀疑我在从命名空间类创建对象时面临的问题。

所以,这个项目在项目的根目录中有一个 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/

相关文章:

c++ - 命名空间问题 : forward declaration and mixing namespaces

java - settHeader ("content type"、 "") - 困惑

php - 通过javascript将html信息传递给php

php - 使用 Selenium 通过测试帐户登录 Facebook

php - Pootle 导出不正确的 PHP 数组文件

PHP 命名空间和接口(interface)

Javascript AJAX PHP if 语句不起作用

namespaces - Clojure:函数的全限定名

r - 如何定义导出包中的哪些变量或函数

php - 如何在前端 Controller 情况下使用 PHP 命名空间