2010-09-04 8 views
11

Ho avuto un piccolo problema con il caricamento automatico nel mio spazio dei nomi. Come mostrato nel manuale PHP qui: http://us.php.net/manual/en/language.namespaces.rules.php dovresti essere in grado di caricare automaticamente le funzioni dello spazio dei nomi con un nome completo completo, ad es. \ Colla \ common \ is_email().PHP Autoloading in Namespaces

In questo caso, ho una funzione spl_autoload_register (array ($ import, "load")); all'interno dello spazio dei nomi iniziale ma ogni volta che provo a chiamare \ glue \ common \ is_email() dallo spazio dei nomi iniziale non passerà la funzione autoload ma quando si usa new_email() (nel contesto di una classe) lo farà. Non capisco il manuale dice che posso caricare automaticamente da nomi completi ma non posso:.

Ecco il mio codice:

namespace glue; 

require_once 'import.php'; 

use glue\import as import; 
use glue\core\router as router; 

$import = new import(); 

spl_autoload_register(array($import, "load")); 

/** Works and echos glue\router **/ 
$router = new router(); 

/** Don't do nothing **/ 
$cheese = \glue\common\is_email($email); 

Ho provato anche questo codice così:

namespace glue; 

require_once 'import.php'; 

use glue\import as import; 
use glue\core\router as router; 
use glue\common; 

$import = new import(); 

spl_autoload_register(array($import, "load")); 

/** Works and echos glue\router **/ 
$router = new router(); 

/** Don't do nothing **/ 
$cheese = common\is_email($email); 

e alla fine di questo codice:

namespace glue; 

require_once 'import.php'; 

use glue\import as import; 
use glue\core\router as router; 
use glue\common\is_email as F; 

$import = new import(); 

spl_autoload_register(array($import, "load")); 

/** Works and echos glue\router **/ 
$router = new router(); 

/** Don't do nothing **/ 
$cheese = F($email); 
+1

rimarcato come PHP5.3 come questo è un 5,3-unica domanda. –

risposta

13

Ecco l'unica risposta giusta.

Ogni spazio dei nomi ha bisogno della propria funzione spl_autoload_register().

anche, spl_autoload_register() sintassi cambiato in 5.3:

spl_autoload_register(__NAMESPACE__ . "\\className::functionName")); 

Il seguente dovrebbe funzionare:

namespace glue; 

require_once 'import.php'; 

use glue\import as import; 
use glue\core\router as router; 

$import = new import(); 

spl_autoload_register(__NAMESPACE__ . "\\$import::load")); 

/** Works and echos glue\router **/ 
$router = new router(); 

/** Don't do nothing **/ 
$cheese = \glue\common\is_email($email); 

Ecco alcune codice vivo che Just lavori!

in ../WebPageConsolidator.inc.php:

class WebPageConsolidator 
{ 
    public function __construct() { echo "PHP 5.2 constructor.\n"; } 
} 

in test.php:

<?php 

namespace WebPage; 

class MyAutoloader 
{ 
    public static function load($className) 
    { 
     require '../' . __NAMESPACE__ . $className . '.inc.php'; 
    } 
} 

spl_autoload_register(__NAMESPACE__ . "\\MyAutoloader::load"); 

class Consolidator extends \WebpageConsolidator 
{ 
    public function __construct() 
    { 
     echo "PHP 5.3 constructor.\n"; 

     parent::__construct(); 
    } 
} 

// Output: 
// PHP 5.3 constructor. 
// PHP 5.2 constructor. 

quindi so che funziona.

+0

Sembrava potesse funzionare ma non caricava ancora la mia funzione. Sto iniziando a pensare che PHP continui a sovrascrivere questa funzionalità con il suo bind di runtime ... il che farebbe schifo. – Sammaye

+0

Si entra in spl_autoload solo quando si usa la nuova parola chiave ........ grrr perché il manuale PHP dice che posso eseguire il caricamento automatico delle funzioni se non riesco a farlo, potrebbe doverle portare a loro. – Sammaye

+4

Autload ** ** funziona solo con ** classi **. –

0

L'idea sbagliata nella questione dell'OP è probabilmente che le funzioni/i metodi sarebbero soggetti all'autoloading - che non lo sono. L'autocaricamento è attivato solo dalle classi di riferimento.

questo detto rimane ancora la domanda sulle classi caricamento automatico nei namespace:

Come del 2017 standard attuale PHP-FIG per autoloading è PSR-4 che prevede il seguente codice caricatore automatico per classi namespace:

<?php 
/** 
* An example of a project-specific implementation. 
* 
* After registering this autoload function with SPL, the following line 
* would cause the function to attempt to load the \Foo\Bar\Baz\Qux class 
* from /path/to/project/src/Baz/Qux.php: 
* 
*  new \Foo\Bar\Baz\Qux; 
* 
* @param string $class The fully-qualified class name. 
* @return void 
*/ 
spl_autoload_register(function ($class) { 

    // project-specific namespace prefix 
    $prefix = 'Foo\\Bar\\'; 

    // base directory for the namespace prefix 
    $base_dir = __DIR__ . '/src/'; 

    // does the class use the namespace prefix? 
    $len = strlen($prefix); 
    if (strncmp($prefix, $class, $len) !== 0) { 
     // no, move to the next registered autoloader 
     return; 
    } 

    // get the relative class name 
    $relative_class = substr($class, $len); 

    // replace the namespace prefix with the base directory, replace namespace 
    // separators with directory separators in the relative class name, append 
    // with .php 
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; 

    // if the file exists, require it 
    if (file_exists($file)) { 
     require $file; 
    } 
}); 

Il testo completo delle specifiche è disponibile su PSR-4: Autoloader.

L'esempio di codice sopra (ed un altro per caricare automaticamente da multipli namespace) può essere trovato alla Example Implementations of PSR-4 (o GitHub: fig-standards/accepted/PSR-4-autoloader-examples.md).

+0

Attualmente PHP7 consente l'autoloading di funzioni e metodi direttamente nello spazio dei nomi – Sammaye

+0

Ciao @Sammaye, grazie per il suggerimento. Avete qualche link con maggiori informazioni a portata di mano? Non riesco a trovare nulla su questo cambiamento. – Jpsy

2

Utilizzare Composer per caricare automaticamente le classi PHP.

Partenza come farlo nel mio recente post sul blog: https://enterprise-level-php.com/2017/12/25/the-magic-behind-autoloading-php-files-using-composer.html

+0

Il motivo per cui questo funzionerebbe ora è perché php ora consente l'autoload delle funzioni dello spazio dei nomi – Sammaye

+0

Sicuro. 7 anni dopo molte cose sono cambiate haha. Volevo mettere qui un riferimento al nuovo modo di farlo, mentre sono arrivato a questa domanda io stesso da Google. – EnchanterIO

Problemi correlati