125369
125369

Reputation: 3657

Namespace usage in object orientated style PHP

I have been fiddling around with Namespace in PHP and was trying to make it work, but it fails

Let me show the example code:

test\views\classes\MainController.php

<?php
namespace test\views\classes;

class MainController
{
    public function echoData()
    {
        echo 'ECHOD';
    }
}

test\views\index.php

<?php
require_once '..\autoloader\autoloader.php';

use test\views\classes\MainController;

$cont = new MainController();

$cont->echoData();

test\autoloader\autoloader.php

<?php

spl_autoload_register(null, FALSE);

spl_autoload_extensions('.php');


function classLoader($class)
{
    $fileName = strtolower($class) . '.php';

    $file = 'classes/' . $fileName;

    if(!file_exists($file))
    {
        return FALSE;
    }

    include $file;
}

spl_autoload_register('classLoader');

Throws an error:

Fatal error: Class 'test\views\classes\MainController' not found in ..\test\views\index.php on line 6

Am Im missing something!

EDIT: The code works fine when both the index.php and maincontroller.php are in the same directory without using autoloader but using require_once('maincontroller.php'); Does not work if they are in different directories and with autoloader function. Can anyone sort this out.

Thanks

Upvotes: 0

Views: 202

Answers (2)

Cerad
Cerad

Reputation: 48865

Add a die statement to your class loader:

$file = 'classes/' . $fileName;

die('File ' . $file . "\n");

And you get

File classes/test\views\classes\maincontroller.php

Is that really where your main controller class lives?

Upvotes: 0

Shu
Shu

Reputation: 5119

Multiple problems in your code:

The namespace separator (\) is not a valid path separator in Linux/Unix. Your autoloader should do something like this:

$classPath = str_replace('\\', '/', strtolower($class)) . '.php';
if (!@include_once($classPath)) {
 throw new Exception('Unable to find class ' .$class);
}

Plus, the paths are all relative. You should set your include path. If your site structure is like this:

bootstrap.php
lib/
  test/
    views/
      index.php
      classes/
        maincontroller.php
  autoloader/
    autoloader.php

Your bootstrap.php should look similar to:

$root = dirname(__FILE__);
$paths = array(
    ".",
    $root."/lib",
    get_include_path()
);
set_include_path(implode(PATH_SEPARATOR, $paths));
include 'lib/test/autoloader/autoloader.php';

Now, in your test/views/index.php you can just include the bootstrap:

include '../../bootstrap.php';

Upvotes: 1

Related Questions