2011-07-07 12 views
10

Tengo un paquete de cargador (LoaderBundle) que debe registrar otros paquetes en el mismo directorio.¿Es posible registrar paquetes dinámicamente en Symfony2?

/Acme/LoaderBundle/... 
/Acme/ToBeLoadedBundle1/... 
/Acme/ToBeLoadedBundle2/... 

me gustaría evitar registrar manualmente cada nuevo paquete (en Acme directorio) en AppKernel::registerBundles(). De preferencia, me gustaría que algo en LoaderBundle se ejecute en cada solicitud y registrar dinámicamente ToBeLoadedBundle1 y ToBeLoadedBundle2. ¿Es posible?

+0

Intentar evite la necesidad de hacer que PHP abra directorios y/o archivos de estadísticas. Incluso con grandes cachés OS esto es perjudicial para el rendimiento. Por supuesto, podría ser bastante útil para el desarrollo. – PAStheLoD

Respuesta

7

no probado, pero podría intentar algo así como

use Symfony\Component\HttpKernel\Kernel; 
use Symfony\Component\Config\Loader\LoaderInterface; 
use Symfony\Component\Finder\Finder; 

class AppKernel extends Kernel 
{ 
    public function registerBundles() 
    { 
     $bundles = array(
      new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), 
      //... default bundles 
     ); 

     if (in_array($this->getEnvironment(), array('dev', 'test'))) { 
      $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); 
      // ... debug and development bundles 
     } 

     $searchPath = __DIR__.'/../src'; 
     $finder  = new Finder(); 
     $finder->files() 
       ->in($searchPath) 
       ->name('*Bundle.php'); 

     foreach ($finder as $file) { 
      $path  = substr($file->getRealpath(), strlen($searchPath) + 1, -4); 
      $parts  = explode('/', $path); 
      $class  = array_pop($parts); 
      $namespace = implode('\\', $parts); 
      $class  = $namespace.'\\'.$class; 
      $bundles[] = new $class(); 
     } 

     return $bundles; 
    } 

    public function registerContainerConfiguration(LoaderInterface $loader) 
    { 
     $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); 
    } 
} 
+0

Gracias. Me llevó a corregir la solución. No me di cuenta de que puedo trabajar con clases normalmente incluso si los paquetes aún no están registrados. –

-2

La respuesta anterior presenta un pequeño error en el que incluiría la clase con a/delante, aquí está el código actualizado

foreach ($finder as $file) { 
      $path  = substr($file->getRealpath(), strrpos($file->getRealpath(), "src") + 4); 
      $parts  = explode('/', $path); 
      $class  = array_pop($parts); 
      $namespace = implode('\\', $parts); 
      $class  = $namespace.'\\'.$class; 
      //remove first slash 
      $class = substr($class, 1, -4); 
      $bundles[] = new $class(); 
     } 
Cuestiones relacionadas