1

I have various classes, e.g.

<?php

namespace MyApp\Notifications;

class FirstNotification implements NotificationInterface {
    public function getMessage() {
        return 'first message';
    }
}

and

<?php

namespace MyApp\Notifications;

class SecondNotification implements NotificationInterface {
    public function getMessage() {
        return 'second message';
    }
}

I then have an array like: ['First','Second'].

I'm using:

foreach (['First','Second'] as $class_prefix) {

    $class = "MyApp\Notifications\\{$class_prefix}Notification";
    $object = new $class();
    echo $object->getMessage();
}

but it feels a bit hacky - is there a better/more standard way to do this? The array is supplied elsewhere and will be different depending on the user - my aim is to be able to easily create classes that implement my interface and know this loop will be able to show their messages if they exist.

I ideally don't want to have to add a use statement for all the classes upfront, or pass them into a constructor, I just want magic to happen!

2
  • The code you supplied looks actually pretty fine to me. What's not working? (you might need to add a backslash in front of MyApp though) Commented May 13, 2015 at 11:05
  • I guess it just feels a bit hacky - I don't really like using variable variables, but maybe there is not a better way. Commented May 13, 2015 at 11:06

1 Answer 1

3

I'm assuming you don't actually mean autoload but rather instantiate the class. Autoloading is the process of including all the files in your application so the contents (usually classes) can be used. If you are using Laravel 5 and you follow PSR-4 (namespace matches directory structure) you don't have to do anything to make those classes available.

The code you already have looks fine and probably works. However you could make use of Laravels Service Container to resolve the class. This has quite a few advantages, one being the availability of automatic dependency injection...

foreach (['First','Second'] as $class_prefix) {
    $object = app()->make("MyApp\Notifications\\{$class_prefix}Notification");
    echo $object->getMessage();
}

Or even this:

foreach (['First','Second'] as $class_prefix) {
    echo app()->callClass("MyApp\Notifications\\{$class_prefix}Notification@getMessage");
}

However, both will cause an exception if the class doesn't exist. You can check for that beforehand or just catch the exception:

foreach (['First','Second'] as $class_prefix) {
    try{
        $object = app()->make("MyApp\Notifications\\{$class_prefix}Notification");
        echo $object->getMessage();
    }
    catch(ReflectionException $e){
        // whooops
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

OK awesome - that seems more normal - you are right as well, I didn't mean autoload, but auto instantiation when needed. Thanks for your help!
Actually - a quick question - I don't consider the lack of this class to be an Exception - so I'd rather not throw one, but do an if class_exists first - is there a method from app() that does that, or would I just use a normal if (class_exists("MyApp\…")){} statement?
No unfortunately the container doesn't have such a method. You have to use class_exists (not that it would be a problem or anything)

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.