开发者

What is Autoloading; How do you use spl_autoload, __autoload and spl_autoload_register?

I am learning advanced PHP standards and trying to implement new and useful methods. Earlier I was using __autoload just to escape including multiple files on each page, but recently I have seen a tip on __autoload manual

spl_autoload_register() provides a more flexible alternative fo开发者_运维百科r autoloading classes. For this reason, using __autoload() is discouraged and may be deprecated or removed in the future.

but I really can't figure out how to implement spl_autoload and spl_autoload_register


spl_autoload_register() allows you to register multiple functions (or static methods from your own Autoload class) that PHP will put into a stack/queue and call sequentially when a "new Class" is declared.

So for example:

spl_autoload_register('myAutoloader');

function myAutoloader($className)
{
    $path = '/path/to/class/';

    include $path.$className.'.php';
}

//-------------------------------------

$myClass = new MyClass();

In the example above, "MyClass" is the name of the class that you are trying to instantiate, PHP passes this name as a string to spl_autoload_register(), which allows you to pick up the variable and use it to "include" the appropriate class/file. As a result you don't specifically need to include that class via an include/require statement...

Just simply call the class you want to instantiate like in the example above, and since you registered a function (via spl_autoload_register()) of your own that will figure out where all your class are located, PHP will use that function.

The benefit of using spl_autoload_register() is that unlike __autoload() you don't need to implement an autoload function in every file that you create. spl_autoload_register() also allows you to register multiple autoload functions to speed up autoloading and make it even easier.

Example:

spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');

class MyAutoloader
{
    public static function ClassLoader($className)
    {
         //your loading logic here
    }


    public static function LibraryLoader($className)
    {
         //your loading logic here
    }

With regards to spl_autoload, the manual states:

This function is intended to be used as a default implementation for __autoload(). If nothing else is specified and spl_autoload_register() is called without any parameters then this functions will be used for any later call to __autoload().

In more practical terms, if all your files are located in a single directory and your application uses not only .php files, but custom configuration files with .inc extensions for example, then one strategy you could use would be to add your directory containing all files to PHP's include path (via set_include_path()).
And since you require your configuration files as well, you would use spl_autoload_extensions() to list the extensions that you want PHP to look for.

Example:

set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();

Since spl_autoload is the default implementation of the __autoload() magic method, PHP will call spl_autoload when you try and instantiate a new class.


Since PHP 5.3, you can use spl_autoload_register() with namespaces, which means that you can organize your project and autoload your php classes without any require or include and without redefining an __autoload() function.

To demonstrate this behaviour, just create a file called index.php :

<?php
spl_autoload_register();
var_dump(new Main\Application);

Then create a folder named Main located right next to the index.php file. Finally, creates a file called Application.php located into Main and paste the following code into it :

<?php namespace Main;
class Application{}


Here is the way I do use Autoload. In the given example I wanto to load classes form 3 diferent directories.

function namespaceAutoload($rawClass){
    $class = str_replace('\\', DIRECTORY_SEPARATOR, $rawClass);

    $possiblePaths[] = '..\sys\class\file.php';
    $possiblePaths[] = '..\sys\class\lib\file.php';
    $possiblePaths[] = '..\sys\class\class.file.inc.php';

    foreach ($possiblePaths as $templatePath) {
        $path = str_replace(["\\", "file"], [DIRECTORY_SEPARATOR, $class], $templatePath);
        if (file_exists($path)) {
            require_once "$path";
            break;
        }
    }
}

spl_autoload_register("namespaceAutoload"); 

I the given example, the PHP will look for the namespace\class in these three directories using these three different filename formats.


Working with OOP in php, spl_autoload_register() lets you register multiple function, classes, trait etc to your php script.

Heres a use case on /test folder structure

/.htaccess
/index.php
/autoload.php
/controller/test.php

Inside autoload.php file:

spl_autoload_register(function ($classname) {
    include_once dirname(__FILE__) . "/" . str_replace("\\", "/", $classname) . '.php';
});

Inside .htaccess

DirectoryIndex index.php

# php_value auto_prepend_file 
php_value auto_prepend_file "/xampp/htdocs/test/autoload.php"

Inside controller/test.php

namespace controller;

class test {
   public static function sayHello () {
     echo "hello";
   }
}

Inside index.php

use controller/test;

echo test::sayHello();

The autoload.php can be included or like the example above prepend on all script. It loads the class test and lets you use it directly without having to include the test.php script by pathname.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜