2

I want to autoload my classes putting only the namespace + the filename.

Example:

directories skeleton:

\var\www
  |_ foo
  |  |_ A.php
  |  |_ B.php
  |  
  |_ index.php

A.php:

<?php

namespace foo\A;

class A {

   private $a;

   public function __construct($a) {
       $this->a = $a;
   }

}

B.php:

<?php

namespace foo\B;

use foo\A;

class B extends A {

    private $b;

    public function __construct($a, $b) {
        parent::__construct($a);
        $this->b = $b;
    }   

}

index.php:

<?php

use foo\B;

define('ROOT', __DIR__ . DIRECTORY_SEPARATOR);

$b = new B('s', 2);

function __autoload($classname) {
    $namespace = substr($classname, 0, strrpos($classname, '\\'));
    $namespace = str_replace('\\', DIRECTORY_SEPARATOR, $classname);
    $classPath = ROOT . str_replace('\\', '/', $namespace) . '.php';

    if(is_readable($classPath)) {
        require_once $classPath;
    }
}

The problem is that in the class A and B I declare the namespace with the classname, and when I use it I print the variables of the __autoload and are correct, bur when call the constructor, don't find the class.

error:

Fatal error: Class 'foo\A' not found in /var/www/foo/B.php on line 7

If I only instantiate A, and I don't use B, the problem is the same.

I need to do it like this, because I want that in class B, you can't use A if you don't put the use statement, to do it more strict.

I don't now if you understand my problem for my explanation, but thanks anyway for any suggestion!!

PD: Sorry for my english skills.

6
  • YOur namespace declarations are wrong. If you want to archive what you pictured in that tree, it has to be namespace foo for both classes - no classnames in namespace declarations. Commented Nov 13, 2013 at 0:00
  • I know, but I want that the namespace that I put is with the classname, to be more strict, because if I don't do it, I can use classes from the same namespace without importing with use statement. Commented Nov 13, 2013 at 0:08
  • The way you're doing it, the class names are actually foo\A\A and foo\B\B. SO the classloader is looking for the files ROOT/A/A.php and ROOT/B/B.php. DO they exist? Commented Nov 13, 2013 at 0:09
  • Yes, this is what happens, so there are any way to import only the class like java, and not the fully namespace? Commented Nov 13, 2013 at 0:12
  • you mean like use foo\B\B as B? ;) Commented Nov 13, 2013 at 0:13

1 Answer 1

4

Your code should be that in classes :

A.php

<?php

namespace foo;

class A {

   private $a;

   public function __construct($a) {
       $this->a = $a;
   }

}

B.php

<?php

namespace foo;

class B extends A {

    private $b;

    public function __construct($a, $b) {
        parent::__construct($a);
        $this->b = $b;
    }   

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

2 Comments

Exactly this. It's just the namespace-declarations that are wrong, so your autoloader doesn'T find the files it'S looking for. (see my comment on the question)
I want that the importing namespaces be like java, that you only import the class and not the package/namespace.

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.