1
votes

I, like many others it seems, am having trouble getting my head around when and how to use auto-loading. I think I understand the concept of composer and PSR-0/PSR-4 and directory structure that this requires. But if I'm building my own project using my own MVC framework

  • Should I now put all my class files in a src folder inside the vendor folder
  • Do I then edit the composer autoload file?
  • Or do I still keep the original structure and just use my own autoloader?

    -project
        -app
            -core /Main.php
            -controllers /Controller.php
            -models /User.php
        /index.php
    

Since composer comes with its own autoloader which will load all dependenies that I may want to include with my project and if I'm not going to make my website into a distributed project do I even need my own namespacing? Why don't I just stick with includes/requires?

And finally, if I do adopt namespacing using a closure like this

 function __autoload($class){
    require $class .'.php';
 });

do I need to require the autoload.php file in all pages where I load my classes as I do with the old include/require of the past. Is the above file correct? I think the namespace would be

<?php
namespace app\core;  //for Main.php
namespace app\controllers; //for Controller.php

use app\controllers\Controller; //if I call the class
1

1 Answers

3
votes

At the beginning of your main file (maybe /var/www/dist/index.php) you just include the Composer or whatever autoloader you use.

<?php
if ( file_exists( __DIR__.'/path/to/vendor/autoload.php' ) )
    require __DIR__.'/path/to/vendor/autoload.php';

Then you can either add shortcuts to the classes that you use in a file by making use of the use statement

use MyNamespace\Controller\Index,
    MyNamespace\Service\FooService;

use Zend\Foo\Bar;
use Symfony\Baz\Biz;
use Etc\Etc\Etc;

// Refers to \Zend\Foo\Bar
$bar = new Bar;

or just use the full path when instantiating a class

$bar = new \Zend\Foo\Bar;

To add your own namespace, just add it to your composer.json file

"autoload" : {
    "psr-4" : {
        "MyNamespace\\" : "src/"
    }
}

and open your command line interface/terminal/console and add the namespace to the autoloader

# local install of Composer in your project
php composer.php dump-autoload
# or global install and `composer` is in your $PATH
composer dump-autoload

There is a rule:

One class per file

And if your project really is (PSR-0 deprecated or) PSR-4 compatible, then you don't use more than one namespace in one file. A class name gets (in the PSR-4 FIG standard) defined as

A fully qualified class name has the following form:

\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>

The contiguous sub-namespace names after the "namespace prefix" [note: \ is the "root") correspond to a subdirectory within a "base directory", in which the namespace separators represent directory separators.

with the following example:

+------------------------------+------------------+------------------------+---------------------------------------+
| Fully Qualified Class Name   | Namespace Prefix | Base Directory         | Resulting File Path                   |
+------------------------------+------------------+------------------------+---------------------------------------+
| \Acme\Log\Writer\File_Writer | Acme\Log\Writer  | ./acme-log-writer/lib/ | ./acme-log-writer/lib/File_Writer.php |
+------------------------------+------------------+------------------------+---------------------------------------+