简体   繁体   中英

Using PHP namespaces on a subnamespace

Good day. I'm working on an example to understand exactly what namespces are, and what are their limitations. I have this structure (windows):

D:\\server\\sistemas\\tests\\phpNS\\exec.php

D:\\server\\sistemas\\tests\\phpNS\\Extra\\Call.php

D:\\server\\sistemas\\tests\\phpNS\\Extra\\exec.php --> (copy of the other one)

D:\\server\\sistemas\\tests\\phpNS\\Lib\\Base.php

Code for each one:

exec.php

<?php 
spl_autoload_register();

$a = new Extra\Call();
?>

Call.php

<?php
namespace Extra{
    spl_autoload_register();

    class Call{
        public function __construct(){
            $inst = new \Libs\Base();
            var_dump($inst);
        }
    }
}
?>

Base.php

<?php
namespace Libs{
    class Base{
        public $dac;
        public $doc;
        public function __construct(){

        }
    }
}
?>

If I work under this scenario, everything is totally ok. The problem is when I execute Extra\\exec.php

Extra\\exec.php

<?php 
namespace Extra{
    spl_autoload_register();

    $a = new Call();
}
?>

It's supposed that the filesystem context of this file is Extra so that's why I'm using that namespace but is not working. I got this error.

Fatal error: spl_autoload(): Class Extra\\Call could not be loaded in D:\\server\\sistemas\\tests\\phpNS\\Extra\\exec.php on line 5

Then I remember php classes are called by a trailing backslash (\\Iterator) so i tried this too:

Extra\\exec.php

<?php
    spl_autoload_register();

    $a = new \Extra\Call();

?>

But I got the same result... What am I doing wrong, and what should I do if I want to use this file in this or in any n-depth directory?

First off, it's not recommended you use namespace declarations as blocks. It's preferred simply declare the namespace and then go into your classes and place one class per file. This is how you would declare \\Extra\\Call

namespace Extra;

class Call{
    public function __construct(){
        $inst = new \Libs\Base();
        var_dump($inst);
    }
}

You typically use spl_autoload_register(); with the name of your callable function but you haven't provided any functions that could act as an autoloader. Your autoload function should have as its sole argument the name of the class you're trying to load. it should then find your class file and include or require that file. Here's an example from the PHP docs

spl_autoload_register(function ($class) {
    include 'classes/' . $class . '.class.php';
});

given the facts that Machavity needs explicitly I give "more concrete example" here is the result of his answer: as you said I need to use to register an autoload function inside of the spl_autoload_register so ok i did that and it works... but JUST for the exec.php that is in the root place.

exec.php

spl_autoload_register(function ($class) {
    include $class . '.php';
});

$a = new Extra\Call();

But this is not working for the Extra\\exec.php. I had to get the basename and use the namespace to load the class. But it keeps failing cause is asking me for non existant Extra\\Libs\\Base.php

Extra\\exec.php

spl_autoload_register(function ($class) {
    $f = basename($class);
    include __DIR__."\\".$f . '.php';
});

$a = new \Extra\Call();

It means I need to get all the root structure depending on each location and do many ugly tricks. As I said you never used my case even to get this conclusion, so I've marked this your answer as not useful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM