Force autoloading of a specific class

This previous question shows how to force autoloading of all classes.

However, I only need to force load one class. How can i do this?

He must not:

  • Apply class source change
  • Rely on any part of the source code of the class (methods, variables, modifiers, for example, they should freely change from concrete to abstract, without affecting it).

Also, it is desirable that it does not include encoding the class name as a string. (To help with IDE refactoring, etc.).

The best option I've found so far would be to simply use spl_autoload_call()

:

spl_autoload_call("Jodes\\MyClass");

      

or for classes without names:

spl_autoload_call("MyClass");

      

+3


source to share


2 answers


I took a different approach to this, maybe not the best, but this is one of the best that made sense to me. However, this is due to modification of the source code, but it is quite simple to implement.

I usually have a primary class aptly named Core

<?php
require_once("{$_SERVER['DOCUMENT_ROOT']}\Matilda\class\Settings.class.php");
require_once("{$_SERVER['DOCUMENT_ROOT']}\Matilda\class\Auth.class.php");
require_once("{$_SERVER['DOCUMENT_ROOT']}\Matilda\class\Permissions.class.php");
require_once("{$_SERVER['DOCUMENT_ROOT']}\Matilda\class\Procedures.class.php");
require_once("{$_SERVER['DOCUMENT_ROOT']}\Matilda\class\Audit.class.php");

class Core {

    /**
     * @var External class
     */
    public $Settings,$Sql,$Auth,$Permissions,$Payroll,$Customers,$Plans,$Billing,$Engin,$AAPT,$Stock,$Prospects,$Freeside,$Audit;

    /**
     * @var Base Config
     */
    private $InitConfig = array(
        'Payroll'           => false,
        'Customers'     => false,
        'Plans'             => false,
        'Billing'           => false,
        'Engin'             => false,
        'AAPT'          => false,
        'Stock'             => false,
        'Prospects'         => false,
        'Freeside'      => false,
    );

    public function __construct($Config = array()) {    
        // Session instantiation
        if (!isset($_SESSION)) session_start();

        if (!is_array($Config)) die('Core instantiation parameter must be an array, even if its empty');
        $this->InitConfig = array_merge($this->InitConfig, $Config);

        // Base classes
        $this->Settings             = new Settings();
        $this->Sql                  = new MySQLi(/* Mysql info */)
        $this->Audit                = new Audit($this->Settings, $this->Sql);
        $this->Auth                 = new Auth($this->Settings, $this->Sql, $this->Audit);
        $this->Permissions          = new Permissions($this->Settings, $this->Sql, $this->Auth, $this->Audit);

        // Optional class handling
        foreach ($this->InitConfig as $Dependency => $State) {
            if ($State == true) {
                require_once($this->Settings->RootDir . "/class/{$Dependency}.class.php");
                $this->$Dependency = new $Dependency($this->Settings, $this->Sql, $this->Auth, $this->Permissions, $this->Audit);
            }
        }

    }

      

This pretty much shows how I can provide additional boot configuration.

It has 5 default classes that it requires and therefore always loads no matter what: Settings, Out, Permissions, Procedures and Audit



Then I can create additional classes: $Core = new Core(array('Payroll' => true))

which will instantiate Payroll.class.php

and will be accessible via$Core->Payroll

This is pretty much just a good way to store tree level functions

 $Core->Members->FetchMemberByID($ID);
 $Core->Plans->CreateNewPlan($PlanName, $Monthly, $Attributes = array())
 etc etc.

      

Some people will probably beat me for this, but personally I find it a relatively decent way to accomplish what you want, but not in the method you usually prefer (without changing the code).

It's also more convenient to skip so that plugins are created for everything you do :)

0


source


I've had the same need lately. Execution was require_once

not an option, because the class really had to be set by the autoloader due to more complex rules, there was no way to know the exact path to the file with the class.

Even though the function is spl_autoload_call($classname)

designed to do just that, it has a fundamental flaw: it will throw a FATAL ERROR if you call it twice for the same class name, or even if some of the child classes of that class are already loaded. This is because overriding classes in PHP is not possible:

<?php

spl_autoload_call('TheClass');
// no problem

spl_autoload_call('TheClass');
// PHP Fatal error:  Cannot declare class TheClass, because the name is already in use in ... on line ...

      

My solution for this problem is not a side effect class_exists($classname)

that was not designed for this purpose, but is more customizable and therefore offers more control over the startup of the autoloader.

Even better, it has absolutely no problem with multiple calls or if something has already been loaded into the inheritance chain. It just has the side effect (if you want) of needing a file if the class doesn't already exist!



<?php

class_exists('TheClass');
// no problem

class_exists('TheClass');
// already exists. No need to autoload it and no fatal errors!

      

That being said, you have a safe and idempotent way to load a class via an autoloader.

And, if you don't want to hard-code the string with the class name there since PHP 5.5, you can use a pseudo-constant ::class

that resolves at compile time for the string with the fully qualified class name (including namespaces):

<?php

class_exists(TheClass::class);

      

0


source







All Articles