1

Guys I'm facing a problem by using spl_autoload_register function. What I'm using is XAMPP in its htdocs directory there is another directory called boot. This directory has 2 files a Car class file and just a Main php file. That class using namespace boot. I want to load that class by using this function spl_autoload_register but error is coming like this. What I'm doing wrong.

Warning: require(boot\Car.php): failed to open stream: No such file or directory in C:\xampp\htdocs\boot\Main.php

Code Car.php

<?php
namespace boot;

class Car
{

    public function __construct()
    {
        echo 'Constructor has been created!';
    }
}

Code Main.php

<?php
spl_autoload_register(function ($className){
    require $className  . '.php';
});

use boot\Car;
$car = new Car;
Ven Nilson
  • 969
  • 4
  • 16
  • 42
  • can you confirm `C:\xampp\htdocs\boot\Main.php` is the exact path ? – Thamaraiselvam Sep 13 '17 at 13:26
  • Possible duplicate of [PHP - Failed to open stream : No such file or directory](https://stackoverflow.com/questions/36577020/php-failed-to-open-stream-no-such-file-or-directory) – Thamaraiselvam Sep 13 '17 at 13:27
  • @Thamaraiselvam yes – Ven Nilson Sep 13 '17 at 13:27
  • @Thamaraiselvam your duplicate marked question doesn't solve my issue – Ven Nilson Sep 13 '17 at 13:30
  • Have you checked all the cases in this answer? https://stackoverflow.com/a/36577021/2975952 – Thamaraiselvam Sep 13 '17 at 13:32
  • Just use `require 'path'` and check that file is accessible, if that works then the problem is somewhere else – Thamaraiselvam Sep 13 '17 at 13:34
  • @Thamaraiselvam I try to add this statement in `Main.php` and it's work fine `require 'Car.php';` no errors are coming. – Ven Nilson Sep 13 '17 at 13:38
  • Rather than giving relative paths use absolute paths like `C:\xampp\htdocs\boot\Car.php` – Thamaraiselvam Sep 13 '17 at 13:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/154349/discussion-between-ven-nilson-and-thamaraiselvam). – Ven Nilson Sep 13 '17 at 13:42
  • @Thamaraiselvam require 'C:\xampp\htdocs\boot\Car.php'; also executed without no error. – Ven Nilson Sep 13 '17 at 13:50
  • problem is in path, the file required is actually this one: `C:\xampp\htdocs\boot\boot\Car.php` – Kazz Sep 13 '17 at 14:00
  • @Kazz can you elaborate this – Ven Nilson Sep 13 '17 at 14:23
  • when you call `require` with relative path that is the same as `__DIR__ . DIRECTORY_SEPARATOR . $path` and `__DIR__` contains full path to the directory of php file where you use it, that means if you want to use this function you have to keep directory stucture same as namespaces because variable `$className` contains namespace as well, quick solution for you is remove `boot` from `$className` that will change project root as base for `boot` namespace... – Kazz Sep 13 '17 at 14:38
  • @VenNilson Basically what problem you facing is, Your class `Car` is not in `boot` directory. When you use statement like this `use boot\Car` then `require` statement will understood this path as an autoload path i.e `boot\boot\Car.php`. In that path second `boot\` is just a fictitious namespace name. So remove it. Code: spl_autoload_register(function ($className){ require str_replace('boot\\',"",$className) . '.php'; }); – Ahmad Hussnain Sep 13 '17 at 15:01
  • @Kazz Thanks for this. – Ven Nilson Sep 13 '17 at 15:05

1 Answers1

0

Few examples:

Directory structure:

project folder
- Main.php
- Car.php
- Test.php
- Foo
- - Bar.php
- - Baz
- - - Qux.php

Test.php

class Test {}

Foo\Bar.php

namespace boot\Foo;
class Bar {}

Foo\Baz\Qux.php

namespace Foo\Baz;
class Qux {}

Main.php

//__DIR__ === C:\xampp\htdocs\boot    

spl_autoload_register(function ($className){
    //__DIR__ . DIRECTORY_SEPARATOR .
    require_once preg_replace('/^[\\\\\/]?boot[\\\\\/]?/', '', $className). '.php';
});

// both require same file but namespace must be same as defined in file
$t = new boot\Car; // work
$t = new Car; // do not work because in Car.php is namespace `boot`
// required file: C:\xampp\htdocs\boot\Car.php

// both require same file but namespace must be same as defined in file
$t = new boot\Test; // do not work because in Test.php is no namespace 
$t = new Test; //work
// required file: C:\xampp\htdocs\boot\Test.php

// both require same file but namespace must be same as defined in file
$t = new boot\Foo\Bar; // work
$t = new Foo\Bar; // do not work because in Bar.php is namespace `boot\Foo`
// required file: C:\xampp\htdocs\boot\Foo\Bar.php

// both require same file but namespace must be same as defined in file
$t = new boot\Foo\Baz\Qux; // do not work because in Qux.php is namespace `Foo\Baz`
$t = new Foo\Baz\Qux; // work
// required file: C:\xampp\htdocs\boot\Foo\Baz\Qux.php
Kazz
  • 1,030
  • 8
  • 16