4

How might I filter through the entire namespace hierarchy to see if my packages have auto-loaded successfully (and for additional processing on those classes)

I have looked for similar questions on SO but none seem to have answered for this specific case.

For example I want to obtain this listing of classes in a Laravel controller, after the whole framework has booted.

I am looking for custom namespaces that I have already autoloaded in composer.json or added to from packages.

CompanyNS\SpecificApplicationNS\Shazbat

How would I go through everything to see what classes have been loaded under Shazbat?

Is there some way I could do something with vendor/composer/autoload_psr4.php ?

These classes would have been loaded in from other external packages.

Thanks in anticipation.

HowApped
  • 1,001
  • 3
  • 12
  • 22
  • `var_dump(class_exists('CompanyNS\SpecificApplicationNS\Shazbat'));` – samayo Nov 04 '15 at 15:22
  • 1
    In this context `Shazbat` is the namespace not a class that I want to test existence – HowApped Nov 04 '15 at 15:26
  • well you need to add your class to the namespace to check if class exists – samayo Nov 04 '15 at 15:29
  • This question sounds useful for a wider audience than just Laravel users. How do you feel about removing the "in Laravel" part of the title and the Laravel tag? (Maybe replacing it with [composer]?) – HPierce Nov 04 '15 at 15:31
  • there will be a variety of classes where the name of them won't necessarily be known at runtime. That's why I want to know what classes are 'under the namespace' – HowApped Nov 04 '15 at 15:31
  • So if I get this right, you have a bunch of classes under that namespace, and you want to know their names just by using the namespace right? – samayo Nov 04 '15 at 15:33
  • yes, that's right @samayo – HowApped Nov 04 '15 at 15:36
  • Possible duplicate of [PHP - get all class names inside a particular namespace](http://stackoverflow.com/questions/22761554/php-get-all-class-names-inside-a-particular-namespace) – HPierce Nov 04 '15 at 15:41

1 Answers1

4

So, to get all the classes declared under a unique namespace, using only the namespace name in this case "foo\bar" you can do the following.

# lets assume this is the namespace, we don't know how many classes it has
# inside it, but we want to find them. 
namespace foo\bar{
   class foo_a{}
   class bar_a{}
}

# this is a namespace, we don't want to find these classes inside it. 
namespace tar\baz{
 class tar_a{}
 class baz_a{}  
}

namespace main{
    # this is the only code you need. wrap it in a function if you want
    $namespace = 'foo\bar';
    foreach(\get_declared_classes() as $class){
        if(strpos($class, $namespace) === 0){
            $c = substr($class, strlen($namespace));
            echo 'class ' . $c . ' exists in namespace '. $namespace . '<br/>'; 
        }
    }
}

output

class \foo_a exists in namespace foo\bar
class \bar_a exists in namespace foo\bar

samayo
  • 16,163
  • 12
  • 91
  • 106
  • 2
    It does not matter where they are defined. as long as you know the namespace in this case `$namespace = 'foo\bar';` you can find them – samayo Nov 04 '15 at 15:51
  • Thanks @samayo your code works however in Laravel it is only showing the service provider as opposed to the actual class. Do you have any idea why this might be? The class and service provider are in the same directories and under the same namespace. – HowApped Nov 04 '15 at 16:09
  • 2
    Wouldn't this only show classes that are autoloaded already? Autoloading allows PHP to determine at runtime where to load a class from, but until its loaded, I would think its not in `get_declared_classes`. – blockhead Nov 04 '15 at 16:11
  • @HowApped Why should it show you the service provider and not the actual classes found in the same directories? can you update the question with the directories and such so we can debug the problem – samayo Nov 04 '15 at 16:52
  • @blockhead if you see the example, there is no class instantiated. It only calls the classes that are declared. Nothing more nothing less – samayo Nov 04 '15 at 16:53
  • Loading a class and instantiating are not the same thing. For example if you did `use myclass` that would kick the autoloader in as well. However, unless you had that statement, I don't believe that class would be in `get_declared_classes`, even though its "autoloadable" – blockhead Nov 04 '15 at 17:17