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

时间:2019-07-16 04:24:20

标签: php namespaces

我不知道我的问题标题是否正确,但是我怀疑从命名空间类创建对象时会遇到什么问题。

因此,该项目在项目的根目录内有一个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”中搜索类?我的代码可以正常工作。是我对名称空间的工作方式了解不正确,还是缺少

1 个答案:

答案 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'

由于您是从字符串实例化的,因此该字符串被视为完全限定的名称,并且不会根据当前名称空间解析 。正是因为可以在名称空间之间传递字符串,并且不可能清楚地知道它们应该属于哪个名称空间。