I have had a slight problem with autoloading in my namespace. As shown on the PHP manual here: http://us.php.net/manual/en/language.namespaces.rules.php you should be able to autoload namespace functions with a full qualified name e.g. \glue\common\is_email().
Thing is I have a function spl_autoload_register(array($import, "load")); within the initial namespace but whenever I try and call \glue\common\is_email() from the initial namespace it will not pass that autoload function but when using new is_email() (in the context of a class) it will. I don't get it the manual says I can autoload from fully qualified names but I can't :.
Here's my code:
namespace glue;
require_once 'import.php';
use glue\import as import;
use glue\core\router as router;
$import = new import();
spl_autoload_register(array($import, "load"));
/** Works and echos glue\router **/
$router = new router();
/** Don't do nothing **/
$cheese = \glue\common\is_email($email);
I also tried this code as well:
namespace glue;
require_once 'import.php';
use glue\import as import;
use glue\core\router as router;
use glue\common;
$import = new import();
spl_autoload_register(array($import, "load"));
/** Works and echos glue\router **/
$router = new router();
/** Don't do nothing **/
$cheese = common\is_email($email);
and finally this code:
namespace glue;
require_once 'import.php';
use glue\import as import;
use glue\core\router as router;
use glue\common\is_email as F;
$import = new import();
spl_autoload_register(array($import, "load"));
/** Works and echos glue\router **/
$router = new router();
/** Don't do nothing **/
$cheese = F($email);
Basically it says: "inside this directory, all namespaces are represented by sub directories and classes are <ClassName>. php files." Autoloading is PHP's way to automatically find classes and their corresponding files without having to require all of them manually.
The spl_autoload_register() function registers any number of autoloaders, enabling for classes and interfaces to be automatically loaded if they are currently not defined. By registering autoloaders, PHP is given a last chance to load the class or interface before it fails with an error.
Autoloading is the process of automatically loading PHP classes without explicitly loading them with the require() , require_once() , include() , or include_once() functions. It's necessary to name your class files exactly the same as your classes. The class Views would be placed in Views.
The first thing to do is to define a namespace with the namespace keyword at the top of the PHP file. All the code underneath the namespace keyword becomes namespaced code. It's important to note that this keyword must be placed at the top of the file, making sure that nothing precedes it.
Here's the only right answer.
Every namespace needs its own spl_autoload_register() function.
also, spl_autoload_register() syntax changed in 5.3:
spl_autoload_register(__NAMESPACE__ . "\\className::functionName"));
The following should work:
namespace glue;
require_once 'import.php';
use glue\import as import;
use glue\core\router as router;
$import = new import();
spl_autoload_register(__NAMESPACE__ . "\\$import::load"));
/** Works and echos glue\router **/
$router = new router();
/** Don't do nothing **/
$cheese = \glue\common\is_email($email);
Here is some live code that Just works!
in ../WebPageConsolidator.inc.php:
class WebPageConsolidator
{
public function __construct() { echo "PHP 5.2 constructor.\n"; }
}
in test.php:
<?php
namespace WebPage;
class MyAutoloader
{
public static function load($className)
{
require '../' . __NAMESPACE__ . $className . '.inc.php';
}
}
spl_autoload_register(__NAMESPACE__ . "\\MyAutoloader::load");
class Consolidator extends \WebpageConsolidator
{
public function __construct()
{
echo "PHP 5.3 constructor.\n";
parent::__construct();
}
}
// Output:
// PHP 5.3 constructor.
// PHP 5.2 constructor.
So I know it works.
The misconception in the question of the OP is probably that functions/methods would be subject to autoloading – which they are not. Autoloading is only triggered by referencing classes.
This being said there still remains the question about autoloading classes in namespaces:
As of 2017 the current PHP-FIG standard for autoloading is PSR-4 which provides the following autoloader code for namespaced classes:
<?php
/**
* An example of a project-specific implementation.
*
* After registering this autoload function with SPL, the following line
* would cause the function to attempt to load the \Foo\Bar\Baz\Qux class
* from /path/to/project/src/Baz/Qux.php:
*
* new \Foo\Bar\Baz\Qux;
*
* @param string $class The fully-qualified class name.
* @return void
*/
spl_autoload_register(function ($class) {
// project-specific namespace prefix
$prefix = 'Foo\\Bar\\';
// base directory for the namespace prefix
$base_dir = __DIR__ . '/src/';
// does the class use the namespace prefix?
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
// no, move to the next registered autoloader
return;
}
// get the relative class name
$relative_class = substr($class, $len);
// replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {
require $file;
}
});
The full spec text can be found at PSR-4: Autoloader.
The code example above (and another one to autoload from multiple namespaces) can be found at Example Implementations of PSR-4 (or GitHub: fig-standards/accepted/PSR-4-autoloader-examples.md).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With