How do namespaces work when using SPL_AUTOLOAD_REGISTER?

I am learning how to use namespaces and autoload in PHP today, and I seem to be in the checkpoint. Everything seems to work when I don't use spl_autoload_register , but require_once instead.

The structure of my folder is minimal:

 - index.php - class/ - Users.php 

In my index.php file, I have:

 <?php require_once('class/Users.php'); echo User::get(1); 

In my class/Users.php file, I have:

 <?php Class User { function get($id) { return $id; } } 

and this works absolutely fine, returning id 1

Ideally, I want to use the autoload function, and I discovered spl_autoload_* , and this is what I tried to do, but without success:

In my class/Users.php file, I have:

 <?php namespace Users; // Added a namespace Class User { function get($id) { return $id; } } 

In my index.php file, I have:

 <?php // Changed to using spl_autoload_register using an anonymous function to load the class spl_autoload_register(function($class){ include('class/' . $class . '.php'); }); echo Users\User::get(1); // Added the Users namespace 

but I get an error:

 `Class 'Users\User' not found in /Applications/MAMP/htdocs/index.php on line 7` 

Not sure what I'm doing wrong.

+4
source share
2 answers

I think you should add \ infront namespace paths.

Example

 \Users\User::get(1); 

If you need to use a base path like Traversable (), you will also need to do

 new \Traversable() 
+1
source

The autoloader is called with the fully qualified class name as an argument, including the namespace. In your example, this is Users\User , so you end up doing

 include('class/Users\User.php'); 

This fails because the class definition is not in the directory named Users (by the way, include will give a warning that it cannot find a file that includes the extended file name, and this warning will make it all the more understandable - - You have disabled the report about bugs?)

It would probably be nice if the autoloader worked on the spot when the file was not found, so that the failure mode became more obvious. For example, you can change it to

 require('class/' . $class . '.php'); // require will end the script if file not found 

or something like

 $result = @include('class/' . $class . '.php'); // see documentation for include if ($result === false) { die("Could not include: 'class/$class.php'"); } 
+1
source

Source: https://habr.com/ru/post/1432519/


All Articles