is it possible to get list of defined namespaces

前端 未结 2 829
后悔当初
后悔当初 2020-12-13 06:29

HI there,

I was wondering if there is a way in php 5.3+ to get a list of defined namespaces within an application. so

if file 1 has namespace F

相关标签:
2条回答
  • 2020-12-13 07:15

    I know this question already has an answer, but I wanted to provide a more realistic solution to what I believe your problem is. Had I had more time yesterday when I made my comment I would have posted this. Sorry that I didn't.

    It sounds like OP has a module system that he needs to know if a particular module is loaded prior to allowing a call to it.

    First, I'd like to say that using namespaces simply to declare modules active is, IMO, abusing what they are for. If you follow the purpose of namespacing to the letter, your structure might look more like this:

    Your entire system should be in its own namespace. Let's call that namespace System. Then, modules would likely be under the System\Module namespace. Then, depending on the complexity, it would be possible that each module might have a namespace under System\Module. Taking your examples, System\Module\FOO and System\Module\BAR.

    Now, let's get into making a module system that registers itself on load.

    First, we need a place to register to. Let's call that System\Module\Registry and, since there are likely to be a lot of different registries, it will implement the System\iRegistry. For brevity, I'm only posting System\Module\Registry. In all likelihood, it will also implement some sort of global consistency model, like a singleton, but I'm not showing that either. Here it is:

    <?php
    namespace System\Module
    {
        class Registry extends System\Registry
        {
            protected $registered = array();
    
            public function register( $name=null )
            {
                $this->registered[] = $name;
            }
    
            public function isRegistered( $module )
            {
                // Code to find module
            }
    
            public function getModule( $module )
            {
                // Code to find module
    
                // OR, if you can't find it...
                throw new ModuleNotRegisteredException("Module named \"{$module}\" could not be found in the registry.");
            }
        }
    }
    ?>
    

    Now, in each module you'd need to call this register function when the file is loaded. There are a couple of ways to do this. The first is to have some code in your module's namespace that run on load similar to typical proceedural code:

    namespace System\Module\FOO
    {
        // Load this module
        $system->module->register("FOO");
    }
    

    The above would mean code duplication though. You might also use autoload for this instead, that way the "registering" code is all in one place. Here's a very basic concept of doing that:

    spl_autoload_register(
        function ($className)
        {
            // Code to load files.
            // Once loaded register our modules.
            if( $namespace = "System\\Module" )
            {
                $system->module->register( $classname );
            }
        }
    ); 
    

    Another possible way of doing this would be to define an interface for modules with a specific function for registering when the module is initialized. This, however, means the module needs to be loaded first and might cause it's own issues depending on your needs.

    After doing this:

    • you have a consistent namespace for modules to live in
    • you have a consistent interface which allows any module to know how to register itself
    • you can easily expand the module or registry interfaces in the future for new things, while keeping your code clean and easy to understand.
    • and, most importantly, you will know that your modules will actually declare that they are loaded and/or ready instead of relying on black magic to do it for you.
    0 讨论(0)
  • 2020-12-13 07:22

    Firstly, to see if a class exists, used class_exists.

    Secondly, you can get a list of classes with namespace using get_declared_classes.

    In the simplest case, you can use this to find a matching namespace from all declared class names:

    function namespaceExists($namespace) {
        $namespace .= "\\";
        foreach(get_declared_classes() as $name)
            if(strpos($name, $namespace) === 0) return true;
        return false;
    }
    

    Another example, the following script produces a hierarchical array structure of declared namespaces:

    <?php
    namespace FirstNamespace;
    class Bar {}
    
    namespace SecondNamespace;
    class Bar {}
    
    namespace ThirdNamespace\FirstSubNamespace;
    class Bar {}
    
    namespace ThirdNamespace\SecondSubNamespace;
    class Bar {}
    
    namespace SecondNamespace\FirstSubNamespace;
    class Bar {}
    
    $namespaces=array();
    foreach(get_declared_classes() as $name) {
        if(preg_match_all("@[^\\\]+(?=\\\)@iU", $name, $matches)) {
            $matches = $matches[0];
            $parent =&$namespaces;
            while(count($matches)) {
                $match = array_shift($matches);
                if(!isset($parent[$match]) && count($matches))
                    $parent[$match] = array();
                $parent =&$parent[$match];
    
            }
        }
    }
    
    print_r($namespaces);
    

    Gives:

    Array
    (
        [FirstNamespace] => 
        [SecondNamespace] => Array
            (
                [FirstSubNamespace] => 
            )
        [ThirdNamespace] => Array
            (
                [FirstSubNamespace] => 
                [SecondSubNamespace] => 
    
            )
    )
    
    0 讨论(0)
提交回复
热议问题