php spl_autoload_register vs __autoload?
__autoload
is generally considered obsolete. It only allows for a single autoloader. Generally you should only use __autoload
if you're using a version of PHP without support for spl_autload_register
.
spl_autoload_register
allows several autoloaders to be registered which will be run through in turn until a matching class/interface/trait is found and loaded, or until all autoloading options have been exhausted. This means that if you're using framework code or other third party libraries that implement their own autoloaders you don't have to worry about yours causing conflicts.
UPDATE:
__autoload
is now officially deprecated as of PHP 7.2.0, which means it's now on the chopping block. If you want your code to be compatible with future versions of PHP you definitely should not use __autoload
Can php spl_autoload_register & composer autoloader work together?
After further research due to ideas that the both @Etki and @Sarah Wilson gave me I came up with the following solution. Thank You both for your input.
require 'vendor/autoload.php';
require 'functions/general.php';
require 'include/mailgun.php';
function autoLoader ($class) {
if (file_exists(__DIR__.'/classes/'.$class.'.php')) {
require __DIR__.'/classes/'.$class.'.php';
}
}
spl_autoload_register('autoLoader');
Hint: I added the __DIR__ to the beginning of the file paths inside the autoLoader function.
Should I prefer require instead of require_once inside spl_autoload_register() callback
I've created a primitive benchmark.
I wasn't be able to see significant difference betwen this two approaches (require
vs require_once
). Maybe problem in "benchmark" itself, feel free to send PR to fix it :)
Most visible changes in execution time had took place when some other process has used disk while test running.
Both approaches had shown ~0.062 for 300 classes on 7200rpm HDD.
> php -v
PHP 7.2.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
What is Autoloading; How do you use spl_autoload, __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 andspl_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.
spl_autoload_register vs __autoload
Autoload functions are called in sequential order, the first registered function is called first, the second one is called after and so on, until one of them finds the class
(unless $prepend
is used). If none do, a fatal error is triggered.
However, in your example, you are using require
instead of include
, so the first function will always fail with a fatal error if the file doesn't exist, so the second one will never be called. Even if you replace it with include
, if both files exist, only the first registered function will be invoked.
It's a good idea to use file_exists
or include
when using multiple autoload functions.
You can also throw exceptions in your autoload functions, so that you can handle undefined classes gracefully instead of killing the script if a class is not found. Per example:
function my_autoload($class) {
$filename = "class.{$class}.php";
if (!file_exists($filename))
throw new Exception("$class not found");
include_once $filename;
}
spl_autoload_register('my_autoload');
try {
$a = new Foo;
} catch (Exception $e) {
// Foo wasn't found
}
// continuing the script...
Obviously it depends on your needs, as throwing an exception will halt the execution of subsequent autoload functions.
Finally, it discouraged to use __autoload
at all, spl_autoload_register
providing a lot more flexibility that the former.
PHP spl_autoload_register class name in a function
I believe it just "clicked" after watching another tutorial. I believe this to be how this works in simple terms:
<?php
spl_autoload_register(function($class_name) {
//$class_name automatically passed into this and the class will be the name of the class as it runs.
});
?>
$Aclass = new Aclass;//$class_name will be Aclass
Edit: As per comment for more information.
The reference for my answer was found in this Youtube video :
https://www.youtube.com/watch?v=20nFAHJT2Qg
It was described as this
"Calls a function when a class is loaded. In other words, it says to
the computer.... (when you try to load a class can you please do
this)"
The important part where I was getting tripped up was that I wasn't recognizing the "$class_name" for what it was. We're using an anonymous function and the argument is the $class_name returned as an argument by the "spl_autoload_register" function as it fires when a class is loaded.
Using PSR4-Autoloading via Composer vs spl_autoload_register
The version with spl_autoload_register
could be faster, because it is directly suited to you. But because you are using Composer for autoloading your depenendecies, your version will be likely be as fast or even slower than the Composer implementation.
There is a principle called Don't repeat yourself so why making something new, when the people from Composer already thought about it and implemented it.
That being said, Composer also uses spl_autoload_register
internally
Conclusion: Use the Composer psr-4 autoload, its probably more robust than your implementation, and equally as fast performance-wise.
Related Topics
PHP Send Email with Attachment
Zend_Form - Array Based Elements
PHP - Implement Logging Mechanism to File in Several Classes
How to Access Static Member of a Class
Remove Zero Values from a PHP Array
In PHP, How to Call a Function Interpolated in String
Reload the Page on Hitting Back Button
Dirt-Simple PHP Templates... Can This Work Without 'Eval'
Pdo Catch and Output MySQL Errors
How to Format a Number to a Dollar Amount in PHP
[PHP Warning: Mail(): " Sendmail_From" Not Set in PHP.Ini or Custom "From:" Header Missing
Fatal Error: Call to Undefined Function Pg_Connect()
Fatal Error: Allowed Memory Size of 268435456 Bytes Exhausted (Tried to Allocate 71 Bytes)