2

I'm trying to build my own framework for internal usage. I got structure like this:

index.php
boot /
    booter.php
application /
     controllers /
           indexcontroller.php
core /
    template.class.php
    model.class.php
    controller.class.php
    cache / 
         memcached.php
    something /
         something.php

Booter.php contains: (it's currently working only with files located in core directory):

class Booter
{
private static $controller_path, $model_path, $class_path;

public static function setDirs($controller_path = 'application/controllers', $model_path = 'application/models', $classes_path = 'core')
{
    self::$controller_path = $controller_path;
    self::$model_path      = $model_path;
    self::$class_path      = $classes_path;

    spl_autoload_register(array('Booter', 'LoadClass'));
    if ( DEBUG ) 
        Debugger::log('Setting dirs...');
}

protected static function LoadClass($className) 
{
    $className = strtolower($className);

    if ( file_exists(DIR . '/' . self::$model_path . '/' . $className . '.php') ) 
    {
        require(DIR . '/' . self::$model_path . '/' . $className . '.php');
    }       
    else if ( file_exists(DIR . '/' . self::$class_path . '/' . $className . '.class.php') ) 
    {
        require(DIR . '/' . self::$class_path . '/' . $className . '.class.php');
    }
    else if ( file_exists(DIR . '/' . self::$controller_path . '/' . $className . '.php') )
    {
        require(DIR . '/' . self::$controller_path . '/' . $className . '.php');
    }

    if ( DEBUG )
        Debugger::log('AutoLoading classname: '.$className);
}
}

My application/controllers/indexcontroller looks like this:

<?
class IndexController extends Controller
{
     public function ActionIndex()
     {
          $a = new Model; // It works
          $a = new Controller; //It works too
     }
}

?>

And here comes my questions:

[Question 1]

My code is working currently like this:

$a = new Model; // Class Model gets included from core/model.class.php

How I can implement including files by classes with namespaces? For example:

$a = new Cache\Memcached; // I would like to include file from /core/CACHE/Memcached.php
$a = new AnotherNS\smth; // i would like to include file from /core/AnotherNS/smth.php 

and so on. How I can produce the handling of the namespace?

[Question 2]

Is it a good practice to use single autoload for Classes, Controllers and models or I should define 3 different spl_autoload_register with 3 different methods and why?

2 Answers 2

3

I normally have a bootstrap.php file inside a folder conf that is in the application root. My code is normally located inside an src folder, also located in the root, so, this works fine for me:

<?php

define('APP_ROOT', dirname(__DIR__) . DIRECTORY_SEPARATOR);

set_include_path(
    implode(PATH_SEPARATOR,
        array_unique(
            array_merge(
                array(
                    APP_ROOT . 'src', 
                    APP_ROOT . 'test'
                ),
                explode(PATH_SEPARATOR, get_include_path())
            )
        )
    )
);

spl_autoload_register(function ($class) {
    $file = sprintf("%s.php", str_replace('\\', DIRECTORY_SEPARATOR, $class));
    if (($classPath = stream_resolve_include_path($file)) != false) {
        require $classPath;
    }
}, true);

You can generalize this into your "Booter" class and append directories to the include path. If you have well defined namespace names, there will be no problems with colisions.

Edit: This works if you follow PSR-1.

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

Comments

2

Question 1:

In your autoloader, change the \ (for the namespace) into DIRECTORY_SEPARATOR. This should work:

protected static function LoadClass($className) 
{
    $className = strtolower($className);
    $className = str_replace('\\', DIRECTORY_SEPARATOR, $className);
...
}

Always use DIRECTORY_SEPARATOR, especially if the software has the potential to be used on other platforms.

Question 2:

I would use one and separate your classes by namespace. However, I think that comes down to how you want to structure your framework and how you separate your code. Someone else may be able to better answer that question.

Comments

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.