Reputation: 15
So I set up an autoloader in PHP using spl_autoload_register() (and not composer).
I have made my custom plugin called my-plugin, refer to the attachment for reference of folder structure.
I have learned to include files like autoloader or trait-singleton.php, I need to include it in my main plugin file i.e., in my case my-plugin.php.
Now when I try to error_log() the parameter spl_autoload_register() accepts, I get a completely different thing.
<?php
spl_autoload_register( function ( $class_name ) {
error_log("Autoloader received: " . $class_name);
include $class_name . '.php';
}
[14-Feb-2025 00:08:23 UTC] Autoloader received: WP_Site_Health
I am unable to complete the autoloader function, the singleton file works great when i include it in the main plugin file.
How do I implement autoloader for my particular file structure, where most of my files would be located in \my-plugin\inc\classes\post-types for CPT and \my-plugin\inc\classes\taxonomies for taxonomies.
Upvotes: -1
Views: 72
Reputation: 198204
The spl_autoload_register() function registers your callback on a stack.
Now the problem you are confronted with is, that the callback receives most classes to load, including those unrelated to your plugin.
This requires you to differentiate between your plugins' classes and other classes.
Let's go through this step-by-step, starting with your classes directories:
\my-plugin\inc\classes\post-types # for CPT
\my-plugin\inc\classes\taxonomies # for taxonomies
For the easiest and most PHP (Standard PHP Library, SPL) compatible form, rename the post-types
directory so that it is compatible with namespace segments, e.g. use an underscore "_" instead of the hyphen-minus "-":
\my-plugin\inc\classes\post_types # for CPT
\my-plugin\inc\classes\taxonomies # for taxonomies
Then put the pathname of \my-plugin\inc
onto the include path. This is for the default implementation of class autoloading, spl_autoload().
Then put all of your classes into .php
files (with lower-case filenames) beneath it and the related namespaces in those files:
\my-plugin\inc\classes\post_types
aaa.php # namespace classes/post_types; class Aaa {}
bbb.php # namespace classes/post_types; trait bBb {}
ccc.php # namespace classes/post_types; interface ccC {}
...
\my-plugin\inc\classes\taxonomies
my_tax.php # namespace classes/taxonomies; class My_Tax {}
Finally register the default SPL autoloader callback instead of your own:
spl_autoload_register(); # Default SPL autoload implementation
This is the very basic setup. The namespaces guard SPL autoload to look into the right directories in the file-system (based on the include path names).
You use lower-case filenames in the file-system, so that the files are portable across file-systems (e.g. those with and without lower and upper-case characters, or not making a difference between them).
This is extensible, e.g. if you want to configure your plugin with a composer.json file, you can configure the base-directory from the include path as a class-map directory. (If you want to rely on PSR-1/4, you have to rename the files, as those autoloading standards are not portable across file systems.)
Upvotes: 1
Reputation: 446
You need to ensure that the autoloader knows where to look based on the class name.
a simple autoloader:
spl_autoload_register(function ($class_name) {
$base_dir = plugin_dir_path(__FILE__) . 'inc/classes/';
$class_name = str_replace('\\', '/', $class_name); //in case of using namespaces
$file = $base_dir . $class_name . '.php';
if (file_exists($file)) {
include $file;
} else {
error_log("Unable to load class $class_name");
}
});
now the autoloader will look for class files like my-plugin/inc/classes/post-types/ClassName.php
or my-plugin/inc/classes/taxonomies/ClassName.php
depending on where the class located
Upvotes: -1