zend ventajas tutorial framework español desventajas curso php model-view-controller zend-framework module

php - tutorial - zend framework ventajas y desventajas



¿Cómo usar los mismos modelos en diferentes módulos en Zend Framework? (5)

Estoy trabajando en la implementación de Zend Framework dentro de un proyecto existente que tiene un área de marketing público, un área de miembros privados, un sitio de administración y un sitio de administración de campañas de marketing. Actualmente estos están mal organizados con las secuencias de comandos del controlador para el área de marketing y los miembros están todos ubicados debajo de la raíz del sitio y luego en una carpeta separada para el administrador y otra carpeta para el sitio de la campaña de marketing.

Al implementar Zend Framework, me gustaría crear y dividir los controladores y las vistas en módulos (uno para el área de miembros, uno para el área de marketing público, uno para el sitio de administración y otro para el sitio de administración de campañas de marketing). pero necesito poder señalar cada módulo al mismo modelo, ya que los tres componentes funcionan en la misma base de datos y en los mismos objetos comerciales.

Sin embargo, no he podido encontrar ninguna información sobre cómo hacer esto en la documentación. ¿Alguien puede ayudar con un enlace sobre cómo hacer esto o con algunas instrucciones simples sobre cómo lograrlo?


Lo que hago es mantener las clases comunes en un directorio de "biblioteca" fuera de la jerarquía de módulos. Luego configure mi INCLUDE_PATH para usar el directorio "modelos" del módulo respectivo, más el directorio "biblioteca" común.

docroot/ index.php application/ library/ <-- common classes go here default/ controllers/ models/ views/ members/ controllers/ models/ views/ admin/ controllers/ models/ views/ . . .

En mi secuencia de comandos bootstrap, agregaba " application/library/ " a INCLUDE_PATH . Luego, en la función init() cada controlador, agregaría el directorio " models/ " de ese módulo a INCLUDE_PATH .

editar: las funciones como setControllerDirectory() y setModuleDirectory() no agregan los directorios de modelos respectivos a INCLUDE_PATH . Tienes que hacer esto tú mismo en cualquier caso. Aquí hay un ejemplo de cómo hacerlo:

$app = APPLICATION_HOME; // you should define this in your bootstrap $d = DIRECTORY_SEPARATOR; $module = $this->_request->getModuleName(); // available after routing set_include_path( join(PATH_SEPARATOR, array( "$app{$d}library", "$app{$d}$module{$d}models", get_include_path() ) ) );

Puede agregar la " library " a su ruta en el programa de arranque, pero no puede agregar el directorio " models " para el módulo correcto en el programa de arranque, porque el módulo depende del enrutamiento. Algunas personas hacen esto en el método init() de sus controladores, y algunas personas escriben un complemento para el gancho preDispatch del ActionController para establecer el INCLUDE_PATH .


Esto también se puede lograr a través de una convención de nombres para seguir a Zend_Loader . Mantenga sus archivos de modelo en la carpeta de modelos debajo de su carpeta de módulo. Module_Models_ModelName como Module_Models_ModelName y guárdelos en un nombre de archivo ModelName.php en la carpeta de modelos para ese módulo. Asegúrese de que la carpeta de la aplicación se encuentre en su ruta de inclusión y suponiendo que está utilizando Zend_Loader para la carga automática, puede simplemente hacer referencia a los modelos por su nombre de clase.

Esto tiene la ventaja de mantener el código de modelo agrupado con el módulo real para el que está. Esto mantiene el módulo dentro de una estructura de carpetas única que ayuda a fomentar la encapsulación. Esto también ayudará en el futuro si necesita transferir el módulo a otro proyecto.


Estoy teniendo el mismo problema. La respuesta de Bill no encaja para mí, porque tiendo a dividir mis módulos, no por ''quién los está viendo'', sino por ''lo que hacen''. Por ejemplo, un "módulo de foro" podría ser administrado tanto por el administrador como por el público. Estoy tratando de tener módulos frontales, como administradores, miembros, públicos, pero estos luego usan otros módulos como ''forum / validatepost'', ''forum / show users personal information''. Si alguien pudiera arrojar luz sobre cómo protegen un módulo de back-end del público, entonces sería útil. Creo que ACL puede ser la clave, pero todavía me pone nervioso tener acceso controlado por objetos en lugar de "file system / .htaccess", etc.

Para responder la pregunta de PHPoet: (i) Las rutas a los directorios del controlador del módulo pueden especificarse mediante llamadas al controlador frontal: por ejemplo, consulte: "12.11.2. Especificación de directorios del controlador del módulo" (Zend Framework Docs)

(ii) Las rutas a las vistas pueden establecerse usando ViewRenderer (Controller Action Helper), por ejemplo, consulte: ''Ejemplo 12.12. Elegir una secuencia de comandos de visualización diferente ''(Zend Framework Docs)

Al jugar, es posible alterar las rutas predeterminadas a las vistas y los controladores, lo que libera el autocargador para que se ejecute normalmente.

(No he estudiado la forma en que funciona el autocargador, pero tendría sentido que tuviera algún sistema mapeador para resolver este tipo de problema).


Acabo de crear este Action Helper personalizado para el problema que describes:

<?php class My_Controller_Action_Helper_GetModel extends Zend_Controller_Action_Helper_Abstract { /** * @var Zend_Loader_PluginLoader */ protected $_loader; /** * Initialize plugin loader for models * * @return void */ public function __construct() { // Get all models across all modules $front = Zend_Controller_Front::getInstance(); $curModule = $front->getRequest()->getModuleName(); // Get all module names, move default and current module to // back of the list so their models get precedence $modules = array_diff( array_keys($front->getDispatcher()->getControllerDirectory()), array(''default'', $curModule) ); $modules[] = ''default''; if ($curModule != ''default'') { $modules[] = $curModule; } // Generate namespaces and paths for plugin loader $pluginPaths = array(); foreach($modules as $module) { $pluginPaths[ucwords($module)] = $front->getModuleDirectory($module) . ''/models''; } // Load paths $this->_loader = new Zend_Loader_PluginLoader($pluginPaths); } /** * Load a model class and return an object instance * * @param string $model * @return object */ public function getModel($model) { $class = $this->_loader->load($model); return new $class; } /** * Proxy to getModel() * * @param string $model * @return object */ public function direct($model) { return $this->getModel($model); } }

Entonces en tu Bootstrap.php:

Zend_Controller_Action_HelperBroker::addPrefix(''My_Controller_Action_Helper'');

Y en cualquiera de tus controladores:

<?php class IndexController extends Zend_Controller_Action { public function indexAction() { $model = $this->_helper->getModel(''SomeModel''); } }

Y esto le permitirá acceder a los modelos en cualquier controlador en todos los módulos.


<?php return array( ''modules'' => array( ''Application'', ''DoctrineModule'', ''DoctrineORMModule'', ''Merchant'', ), ''module_listener_options'' => array( ''config_glob_paths'' => array( ''config/autoload/{,*.}{global,local}.php'', ), ''module_paths'' => array( ''./module'', ''../vendor'', // ''here we can load module'' ''comomonmodule'' ), ), );