Searching for an elegant way in PHP for loading dependencies/services/configuration?

前端 未结 2 1653
慢半拍i
慢半拍i 2021-01-15 08:54

I\'m building a MVC PHP framework and I wonder which are the best practices to load what I need in my classes, be it other classes or plain configuration.

Till today

相关标签:
2条回答
  • 2021-01-15 09:10

    Why reinvent the wheel? Use Pimple as your DI container, and learn how to use it from its documentation.

    Or, use Silex microframework as a base to create your own framework. It extends Pimple functionality, so you can use dependency injection.

    To answer your question, this is how you use a DI without coupling your classes to it:

    interface ContainerInterface {
        public function getService($service_name);
        public function registerService($service_name,Closure $service_definition);
    }
    
    class Application {
        public function __construct(ContainerInterface $container) {
            $this->container= $container;
        }
    
        public function run() {
            // very simple to use!
            $this->container->getService('db')->someDatabaseQuery();
        }
    }
    
    $c = new My_DI_Container;
    
    // Service definitions could be in a separate file
    $c->registerService('db',function() { return new Database('some config'); });
    
    // Then you inject your DI container into the objects that need it
    $app = new Application($c);
    $app->run(); // or whatever
    

    This way, the DI container is decoupled and in the future you could use a different implementation. The only requirement is that it implements the ContainerInterface.

    Note that the container object is being pushed, and not pulled. Avoid using singleton. To get/set single-instance objects, use the container (that's its responsibility). And to get the container instance, just push it through constructors.

    0 讨论(0)
  • 2021-01-15 09:35

    Answer to your question; Look at PHP autoloading. Registering classes via autoloading makes it so you don't have to put require/includes everywhere, which really has a positive impact on RAD (rapid application development).

    My thoughts:

    Kudos for attempting such a daunting task, your approach appears to based on good practices such as singletons and factories.

    I don't care for dependency injection. OOP is based on encapsulation, injecting one object into another, imo, breaks that encapsulation. When you inject an object into another object, the target object has to 'trust' that nothing regarding the injected object has changed, otherwise you may get unusual behavior.

    Consider name-spacing your classes (not PHP name-spacing, but prefix your framework like Zend does, Zend_), this will help so you can register a namespace, then when a class is called the autoloader will ensure that the proper class is loaded. This is how Zend_Framework works. For specifics check out Zend_Loader_Autoloader. The Symfony framework actually takes this one step further; during the first request it will go through all known locations looking for class files, it will then build out an array of the classes and paths to the files then save the array to a file (file caching), so subsequent requests won't have the same overhead. Something to consider for your framework.

    As far as config files go, Symfony uses YAML files, which I have found to be extremely flexible. You can even include PHP code for increased flexibility. Symfony has provided a stand-alone YAML parser that is easy to use. You can increase performance by adding a caching layer and caching parsed YAML files so you don't have to parse the files for every request.

    I am assuming you are building your framework on top of an ORM. My recommendation would be not to any functionality specific to a version of the ORM, otherwise your framework becomes coupled with that version and you will have to upgrade both the ORM and the framework at the same time.

    I would suggest looking under the hood at other frameworks and see if you can pick the best of each; resulting in a solid, easy to use framework.

    0 讨论(0)
提交回复
热议问题