Search code examples
phpcoding-stylepsr-0code-standards

PSR-0 Implementation on Class Loading


I'm not new to PHP but I'm new to PSR. I've read some of it and I want to give a try to follow this standards on coding but I'm a bit confused how can implement it. So I need a simple advice from you guys on how to implement it based on the example I will provide.

Directory Structure

 /models
    User.php
 /controller
    controller.php
 /view
    index.php

Model.php

Class User
{
  public function foo()
  {
    // Do something
  }
}

How can I call that class on my controller.php in PSR-0 approach? I've read something like

namespace, use

and this

   function autoload($className)
   {
    $className = ltrim($className, '\\');
    $fileName  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

    require $fileName;
   }

But i dunno how and where to put those codes.

Thanks!


Solution

  • It means you have a folder for every namespace you are using.

    So if you define a class in a namespace say:

    <?php
    namespace Nicemodels;
    
    class Niceuser { ... }
    

    Then the file Niceuser.php needs to be in .../models/Nicemodels/

    You still need to make sure you handle the models directory correctly. You could start one on a higher level and put all your models in the Models namespace (recommended).

    So above example becomes:

    <?php
    namespace Models\Nicemodels;
    
    class Niceuser { ... }
    

    The use statement is used to import classes from another namespace:

    <?php
    namespace Models\Nicemodels;
    
    use Models\Normaluser
    
    class Niceuser extends Normaluser { ... }
    

    You autoloader reflects this namespace to directory behaviour in the line

    $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    

    Here you convert namespace separators '\' into directory separators.

    You need to tell your autoload the starting point of all this. So you if you don't use the Models namespace you need to point to your models/ folder as start. And you need to make sure of the case you start your filenames with. Otherwise the autoloader will not find your classes.


    If you want to use such a class in your controllers you do:

    $user = new \Models\Nicemodels\Niceuser();
    

    You can shorten that, if you import the class:

    use Models\Nicemodels\Niceuser;
    ...
    $user = new Niceuser();