php - Instantiating a namedspaced class within another namespaced class

785

I do not know if I got the title of the question right but I have a doubt I am facing while creating objects from namespaced classes.

So, this project has an index.php and an Inc folder inside the root of the project. The inc folder has folders - Base ( with Enqueue.php), Pages (with Admin.php) and Init.php .In the index.php we are autoloading the Inc folder( which has a namespace of Inc ) and calling register_services() in the Init class

Here is the index.php file :

<?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();
        }
}

The Inc/Base/Enqueue.php

<?php 

namespace Inc\Base;

class Enqueue
{
    public function register() {
        echo 'enque register';
    }

The Inc/Pages/Admin.php :

<?php
namespace Inc\Pages;

class Admin
{
    public function register() {
        echo 'admin register';
    }

}

The 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;
    }
}

So in the Init class, we have :

public static function get_services() 
    {
        return [
            Pages\Admin::class,  
            Base\Enqueue::class
        ];
    }

This returns as an array both the Qualified Names of the class that is Inc\Pages \Admin and Inc\Base\Enqueue . Later we instantiate the class like below in the Init class :

private static function instantiate( $class )
    {
        echo $class;
                $service = new $class();
        return $service;
    }

My question is since we are already in the namespace Inc in the Init class , wont instantiating the class by calling it starting from Inc again ( that is Inc \Pages\Admin or Inc\Base\Enqueue ) lead it to search for the class in the namespace 'Inc\Inc\Pages\Admin' or 'Inc\Inc\Pages\Enqueue'? My code works all right though. Is my understanding of how namespaces work not right or am I missing

647

Answer

Solution:

Literals are resolved against the current namespace, strings are always assumed/expected/required to be the fully qualified name.

This is your literal:

namespace Inc;

Pages\Admin::class

This literalPages\Admin is resolved against the current namespace and resolves toInc\Pages\Admin. So the value ofPages\Admin::class here is'Inc\Pages\Admin'. You then pass this string around and end up doing:

new $class()  // where $class = 'Inc\Pages\Admin'

Since you're instantiating from a string, that string is treated as being the fully qualified name and is not resolved against the current namespace. Precisely because strings can be passed around between namespaces, and it would be impossible to clearly know what namespace they're supposed to belong to.

People are also looking for solutions to the problem: php - Roll out static folder as plugin and access via domainname.com/anyname

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.