5

I'd like to get the names of all classes within a specific namespace in PHP. Currently, I'm attempting to do some magic via reflection on a specific list of named classes, but I'd like to do it without knowing the names ahead of time.

I've tried calling get_declared_classes(), but for whatever reason, classes that I do have available are not showing up. I can call get_declared_classes(), not see Event in the list, then immediately call $x = new Event() without a problem. Something like the following, which I would think should cause a problem...

if (! in_array('Event', get_declared_classes())) { $x = new Event(); }

...works fine. I'm wondering if namespacing these classes and retrieving that way would help alleviate the problem. Is this possible?

EDIT: For clarification, let me add that I am not currently using namespaces, and I am not specifically trying to achieve something from the above listed code. What I want is to get the names of all classes I have declared. Despite the fact the class declarations for all of them are being hit before I call get_declared_classes(), they are not all appearing in the list. I was hoping that namespacing might help solve the problem.

EDIT2: Several people have pointed out that the classes may be autoloaded. I tested this by doing the following. echo(class_exists('Event')) returned a value of 1. echo(class_exists('Event', FALSE)) returned a value of 0. The second, optional parameter to class_exists is whether or not to autoload. So, apparently the class is being autoloaded. That answers that.

So, next question - how do I prevent this? I'm using a framework that really doesn't give me much low-level control. Is there a way to force autoloading, THEN call get_declared_classes, or for get_declared_classes to fire an autoload first?

5
  • 1
    In this scenario in which get_declared_classes does not contain Event, has the Event code been loaded? In other words, has the file that contains Event's class declaration been included (or otherwise defined in the flow of code already)? Commented Dec 16, 2011 at 1:02
  • 1
    I havent bothered to test but i would think this could be because youve referenced a NS with a use statement and the class name in the array is going to be the Fully qualified one with the namespace. So that while new Event might work its really referencing \Some\OtherNamespace\Event. Commented Dec 16, 2011 at 1:03
  • @Corbin The Event code is definitely loaded. If not, $x = new Event() would fail, right? Commented Dec 16, 2011 at 1:07
  • @prodigitalson I'm not currently using namespaces. Commented Dec 16, 2011 at 1:07
  • 2
    @Ryan: No, calling $x = new Event() may use autoloading and then load Event class's code. Commented Dec 16, 2011 at 1:08

1 Answer 1

5

You do not need to hard code it in the code, you can use variable name:

$class_name = 'Event';
if (!in_array($class_name, get_declared_classes())) {
    $x = new $class_name();
};

See similar code in action here: codepad.org/hCLE4ToA.

Also some classes may not appear in get_declared_classes()'s result, because they may not be loaded at the time this function is called. It may be the case if they are autoloaded after you try to instantiate them. See more on autoloading classes here: php.net/autoload.

Does it answer some of your questions? Did it help?

Sign up to request clarification or add additional context in comments.

7 Comments

I'm not actually trying to do the example that I listed. That was more demonstrative of how the class name I want is not appearing in the list as I would expect, yet it is available for instantiation.
@Ryan: Are you sure it is available for instantiation not because it is autoloaded when you try to instantiate it? In other words: are you sure class has been defined before you called get_declared_classes()?
Do you know of a way to force autoloading though? I'm using a framework that doesn't give me much control, and I really need the names of those classes that are being autoloaded.
@Ryan: As the code responsible for autoloading may be quite complex I see no other option than to look through the places autoloading mechanism would look, and gather information about the classes. It can be usually done on the basis of file names (eg. file Zend/Validate/Callback.php contains definition of Zend_Validate_Callback class in Zend), but it may be tricky. You may be lucky if your framework caches these paths somehow, preferably associating class names to them. Generally autoloading is very useful sometimes, but in this case it could cause you some headache.
It's worth noting that if this is a significantly large set of classes spread across a significantly high number of files, if this is a frequently done operation, it may become very performance degrading. Loading files is fairly slow.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.