webentwicklung-frage-antwort-db.com.de

Beste Möglichkeit zum automatischen Laden von Klassen in PHP

Ich arbeite an einem Projekt mit folgender Dateistruktur:

index.php
|---lib
|--|lib|type|class_name.php
|--|lib|size|example_class.php

Ich möchte die Klassen class_name und example_class (benannt wie die Klassen PHP)) automatisch laden, damit die Klassen in index.php bereits instanziiert werden und ich Folgendes tun kann:

$class_name->getPrivateParam('name');

Ich habe im Internet nachgesehen, kann aber nicht die richtige Antwort finden - kann mir jemand helfen?

BEARBEITEN

Danke für die Antworten. Lassen Sie mich mein Szenario erweitern. Ich versuche, ein WordPress Plugin zu schreiben, das in ein Projekt eingefügt werden kann, und zusätzliche Funktionen, die hinzugefügt werden, indem eine Klasse in einen Ordner "Funktionalität" zum Beispiel im Plugin abgelegt wird. Es wird nie eine geben 1000 Klassen, bei einem Push vielleicht 10?

Ich konnte eine Methode schreiben, um die Ordnerstruktur des 'lib'-Ordners zu durchlaufen, einschließlich jeder Klasse, die sie dann einer Variablen (des Klassennamens) zuordnet, hielt dies jedoch nicht für eine sehr effiziente Methode, sondern für eine solche Vielleicht scheint das der beste Weg zu sein, um das zu erreichen, was ich brauche?

21
Sjwdavies

Wenn Sie Klassen automatisch laden müssen - verwenden Sie die Konventionen für Namespaces und Klassennamen mit SPL-Autoload, um Zeit für das Refactoring zu sparen. Und natürlich müssen Sie jede Klasse als Objekt instanziieren. Vielen Dank.

Wie in diesem Thread: PHP Autoloading in Namespaces

Wenn Sie eine komplexe Problemumgehung wünschen, schauen Sie sich bitte die Autoload-Klasse von Symfony an: https://github.com/symfony/ClassLoader/blob/master/ClassLoader.php

Oder so (ich habe es in einem meiner Projekte gemacht):

<?
spl_autoload_register(function($className)
{
    $namespace=str_replace("\\","/",__NAMESPACE__);
    $className=str_replace("\\","/",$className);
    $class=CORE_PATH."/classes/".(empty($namespace)?"":$namespace."/")."{$className}.class.php";
    include_once($class);
});
?>

und dann können Sie Ihre Klasse wie folgt instanziieren:

<?
$example=new NS1\NS2\ExampleClass($exampleConstructParam);
?>

und das ist deine Klasse (gefunden in /NS1/NS2/ExampleClass.class.php):

<?
namespace NS1\NS2
{
    class Symbols extends \DB\Table
    {
        public function __construct($param)
        {
            echo "hello!";
        }
    }
}
?>
31
Serge Velikanov

Wenn Sie Zugriff auf die Befehlszeile haben, können Sie es mit composer in der classMap-Sektion mit so etwas versuchen:

{
    "autoload": {
        "classmap": ["yourpath/", "anotherpath/"]
    }
}

dann musst du ein wordpress plugin aktivieren composer im wordpress cli: http: // wordpress .org/plugins/composer /

10
lilobase

http://php.net/manual/de/function.spl-autoload-register.php

spl_autoload_register(function ($class) {
    @require_once('lib/type/' . $class . '.php');   
    @require_once('lib/size/' . $class . '.php');
});
3
Daniel W.
function __autoload($class_name) {
   $class_name = strtolower($class_name);
   $path       = "{$class_name}.php";
   if (file_exists($path)) {
       require_once($path);
   } else {
       die("The file {$class_name}.php could not be found!");
   }
}

PDATE:__autoload() ist veraltet ab PHP 7.2

3
Hassan Azimi

Ich habe hier ein Beispiel, das ich zum automatischen Laden und Initialisieren verwende.
Grundsätzlich eine bessere Version von spl_autoload_register, da nur versucht wird, die Klassendatei zu benötigen, wenn Sie die Klasse initialisieren.
Hier bekommt es automatisch jede Datei in Ihrem Klassenordner, benötigt die Dateien und initialisiert sie. Sie müssen lediglich der Klasse den gleichen Namen geben wie der Datei.
index.php

<?php
require_once __DIR__ . '/app/autoload.php';

$loader = new Loader(false);

User::dump(['hello' => 'test']);

autoload.php

<?php
class Loader 
{

    public static $library;

    protected static $classPath = __DIR__ . "/classes/";

    protected static $interfacePath = __DIR__ . "/classes/interfaces/";

    public function __construct($requireInterface = true) 
    {
        if(!isset(static::$library)) {
            // Get all files inside the class folder
            foreach(array_map('basename', glob(static::$classPath . "*.php", GLOB_BRACE)) as $classExt) {
                // Make sure the class is not already declared
                if(!in_array($classExt, get_declared_classes())) {
                    // Get rid of php extension easily without pathinfo
                    $classNoExt = substr($classExt, 0, -4); 
                    $file = static::$path . $classExt;

                    if($requireInterface) {
                        // Get interface file
                        $interface = static::$interfacePath . $classExt;
                        // Check if interface file exists
                        if(!file_exists($interface)) {
                            // Throw exception
                            die("Unable to load interface file: " . $interface);
                        }

                        // Require interface
                        require_once $interface;
                        //Check if interface is set
                        if(!interface_exists("Interface" . $classNoExt)) {
                            // Throw exception
                            die("Unable to find interface: " . $interface);
                        }
                    }

                    // Require class
                    require_once $file;
                    // Check if class file exists
                    if(class_exists($classNoExt)) {
                        // Set class        // class.container.php
                        static::$library[$classNoExt] = new $classNoExt();
                    } else {
                        // Throw error
                        die("Unable to load class: " . $classNoExt);
                    }

                }
            }
        }
    }

    /*public function get($class) 
    {
        return (in_array($class, get_declared_classes()) ? static::$library[$class] : die("Class <b>{$class}</b> doesn't exist."));
    }*/
}

Sie können problemlos mit ein wenig Code umgehen, um auch Klassen in verschiedenen Ordnern zu benötigen.
Hoffentlich kann Ihnen das etwas nützen.

2
anttwuan

Mit diesem Autoloader können Sie ein für Namespaces geeignetes Autoloading festlegen.

<?php
spl_autoload_register(function($className) {
    $file = __DIR__ . '\\' . $className . '.php';
    $file = str_replace('\\', DIRECTORY_SEPARATOR, $file);
    if (file_exists($file)) {
        include $file;
    }
});

Stellen Sie sicher, dass Sie den Speicherort der Klassendatei korrekt angeben.

Quelle

0
Supun Kavinda