Zend_Tool_Framework es un framework para exponer funcionalidades
comunes tales como la creación de esqueletos de proyecto, generación de
código, generación de índices de búsqueda, y mucho más. Se puede escribir y exponer
funcionalidad a través de clases de PHP colocadas en el
include_path de PHP, proporcionando una increíble
flexibilidad de implementación. La funcionalidad puede entonces ser consumida escribiendo
clientes específicos de implementación y/o protocolo -- tales como clientes
de consola, XML-RPC, SOAP, y mucho más.
Zend_Tool_Project se construye sobre y extiende las capacidades de
Zend_Tool_Framework hacia la de gestionar un "proyecto". En general,
un "proyecto" es un esfuerzo planificado o una iniciativa. En el mundo de la informática, los proyectos
generalmente son una colección de recursos. Estos recursos pueden ser archivos, directorios,
bases de datos, esquemas, imágenes, estilos, y más.
Zend_Tool_Framework proporciona lo siguiente:
Interfaces y abstracciones comunes que permiten a los desarrolladores crear funcionalidad y capacidades que son despachables por los clientes de herramientas.
Funcionalidad base de cliente y una implementación concreta de consola que conecta herramientas externas e interfaces con
Zend_Tool_Framework. El cliente de consola puede usarse en entornos de CLI tales como shells de unix y la consola de Windows.Interfaces "Provider" y "Manifest" que pueden ser utilizadas por el sistema de herramientas. Los "Providers" representan el aspecto funcional del framework, y definen las acciones que los clientes de herramientas pueden llamar. Los "Manifests" actúan como registros de metadatos que proporcionan contexto adicional para los distintos providers definidos.
Un sistema de carga introspectivo que explorará el entorno en busca de providers y determinará lo que se requiere para despacharlos.
Un conjunto estándar de providers de sistema que permite al sistema reportar cuáles son las capacidades completas del sistema, además de proporcionar información útil. Esto también incluye un "Sistema de Ayuda" completo.
Definiciones que debe conocer a lo largo de este manual con respecto
a Zend_Tool_Framework:
Zend_Tool_Framework- El framework que expone las capacidades de herramientas.Cliente de herramientas - Una herramienta de desarrollador que se conecta a y consume
Zend_Tool_Framework.Cliente - El subsistema de
Zend_Tool_Frameworkque expone una interfaz de tal manera que los clientes de herramientas puedan conectarse, consultar y ejecutar comandos.Cliente de Consola / Interfaz de línea de comandos /
zf.php- El cliente de herramientas para la línea de comandos.Provider - Un subsistema y una colección de funcionalidad incorporada que el framework exporta.
Manifest - Un subsistema para definir, organizar, y difundir los datos de requisitos de los providers.
Provider de
Zend_Tool_Project- Un conjunto de providers específicamente para crear y mantener proyectos basados en Zend Framework.
El CLI, o herramienta de línea de comandos (conocida internamente como la
herramienta de consola), es actualmente la interfaz principal para despachar
solicitudes de Zend_Tool. Con la herramienta CLI,
los desarrolladores pueden emitir solicitudes de herramientas dentro de la "ventana de línea de comandos", también
conocida comúnmente como una ventana "terminal". Este entorno predomina en el entorno
*nix, pero también tiene una implementación común en windows con
cmd.exe, console2 y también con el proyecto Cygwin.
Para emitir solicitudes de herramientas a través del cliente de línea de comandos, primero
necesita configurar el cliente de manera que su sistema pueda manejar el comando
"zf". El cliente de línea de comandos, para todos los propósitos, es
el archivo .sh o .bat que se proporciona
con su distribución de Zend Framework. En trunk, se puede encontrar aquí:
http://framework.zend.com/svn/framework/standard/trunk/bin/.
Como puede ver, hay 3 archivos en el directorio /bin/:
un zf.php, zf.sh, y
zf.bat. El zf.sh y el
zf.bat son los wrappers de cliente específicos del sistema
operativo: zf.sh para el entorno *nix, y
zf.bat para el entorno Win32. Estos wrappers de cliente son
responsables de encontrar el php.exe apropiado, encontrar
el zf.php, y pasar la solicitud del cliente. El
zf.php es el responsable de entender
su entorno, construir el include_path apropiado, y pasar
lo que se proporciona en la línea de comandos al componente de biblioteca
apropiado para el despacho.
En última instancia, quiere asegurar dos cosas para hacer que todo funcione sin importar en qué sistema operativo se encuentre:
zf.sh/zf.bates alcanzable desde el path de su sistema. Esta es la capacidad de invocar zf desde cualquier lugar en su línea de comandos, sin importar cuál sea su directorio de trabajo actual.ZendFramework/libraryestá en su include_path.
![]() |
Nota |
|---|---|
Nota: aunque lo anterior son los requisitos más ideales,
simplemente puede descargar Zend Framework y esperar que
funcione como |
La configuración más común en el entorno *nix es copiar
zf.sh y zf.php en el mismo
directorio que su binario de PHP. Este generalmente se puede encontrar en
uno de los siguientes lugares:
/usr/bin /usr/local/bin /usr/local/ZendServer/bin/ /Applications/ZendServer/bin/
Para averiguar la ubicación de su binario de PHP, puede ejecutar 'which php' en la línea de comandos. Esto devolverá la ubicación del binario de PHP que utilizará para ejecutar scripts de PHP en este entorno.
El siguiente asunto a atender es asegurar que la biblioteca
de Zend Framework esté correctamente configurada dentro del
include_path del sistema PHP. Para averiguar dónde
está ubicado su include_path, puede ejecutar
php -i y buscar la variable include_path,
o más sucintamente, ejecutar
php -i | grep include_path. Una vez que haya encontrado dónde
está ubicado su include_path (esto generalmente será
algo como /usr/lib/php,
/usr/share/php, /usr/local/lib/php, o
similar), asegúrese de que el contenido del directorio
/library/ se coloque dentro del directorio especificado
por su include_path.
Una vez que haya hecho esas dos cosas, debería poder emitir un comando y obtener la respuesta apropiada como esta:
Si no ve este tipo de salida, vuelva atrás y verifique su configuración para asegurarse de que tiene todas las piezas necesarias en el lugar apropiado.
Hay un par de configuraciones alternativas que podría querer emplear dependiendo de la configuración de sus servidores, su nivel de acceso, o por otras razones.
La configuración alternativa implica mantener la
descarga de Zend Framework junta tal como está, y crear un enlace desde una
ubicación de PATH hacia el zf.sh. Lo que esto
significa es que puede colocar el contenido de la descarga de ZendFramework en una
ubicación como /usr/local/share/ZendFramework, o de forma más
local como /home/username/lib/ZendFramework, y crear
un enlace simbólico al zf.sh.
Suponiendo que quiere colocar el enlace dentro de /usr/local/bin
(esto también podría funcionar para colocar el enlace dentro de
/home/username/bin/ por ejemplo) emitiría un
comando similar a este:
ln -s /usr/local/share/ZendFramework/bin/zf.sh /usr/local/bin/zf # OR (for example) ln -s /home/username/lib/ZendFramework/bin/zf.sh /home/username/bin/zf
Esto creará un enlace al cual debería poder acceder globalmente en la línea de comandos.
La configuración más común en el entorno Windows Win32 es copiar
zf.bat y zf.php en el mismo
directorio que su binario de PHP. Este generalmente se puede encontrar en
uno de los siguientes lugares:
C:\PHP C:\Program Files\ZendServer\bin\ C:\WAMP\PHP\bin
Debería poder ejecutar php.exe en la línea de comandos.
Si no puede, primero revise la documentación que vino con
su distribución de PHP, o asegúrese de que la ruta a
php.exe esté en su
variable de entorno PATH de Windows.
El siguiente asunto a atender es asegurar que la biblioteca
de Zend Framework esté correctamente configurada dentro del
include_path del sistema PHP. Para averiguar dónde
está ubicado su include_path, puede escribir
php -i y buscar la variable include_path,
o más sucintamente ejecutar
php -i | grep include_path si tiene Cygwin configurado con
grep disponible. Una vez que haya encontrado dónde
está ubicado su include_path (esto generalmente será
algo como C:\PHP\pear,
C:\PHP\share,
C:\Program%20Files\ZendServer\share o similar), asegúrese
de que el contenido del directorio library/ se coloque dentro de su
directorio especificado por include_path.
Una vez que haya hecho esas dos cosas, debería poder emitir un comando y obtener la respuesta apropiada como esta:
Si no ve este tipo de salida, vuelva atrás y verifique su configuración para asegurarse de que tiene todas las piezas necesarias en el lugar apropiado.
Hay un par de configuraciones alternativas que podría querer emplear dependiendo de la configuración de su servidor, su nivel de acceso, o por otras razones.
La configuración alternativa implica mantener la
descarga de Zend Framework junta tal como está, y alterar tanto su
PATH del sistema como el archivo php.ini.
En el entorno de su usuario, asegúrese de agregar
C:\Path\To\ZendFramework\bin, de manera que su
archivo zf.bat sea ejecutable. Además, altere el
archivo php.ini para asegurarse de que
C:\Path\To\ZendFramework\library esté en su
include_path.
Si por alguna razón no quiere la biblioteca de Zend Framework dentro de
su include_path, hay otra opción. Hay
dos variables de entorno especiales que zf.php va a
utilizar para determinar la ubicación de su instalación de Zend
Framework.
La primera es ZEND_TOOL_INCLUDE_PATH_PREPEND, que va a
anteponer el valor de esta variable de entorno al
include_path del sistema (php.ini) antes de cargar
el cliente.
Alternativamente, podría querer usar
ZEND_TOOL_INCLUDE_PATH para
reemplazar completamente el include_path del sistema
por uno que tenga sentido específicamente para la herramienta de línea de comandos
zf.
En general, un provider, por sí solo, no es más que el armazón para que un desarrollador empaquete algunas capacidades que desea despachar con la línea de comandos (u otros) clientes. Es un análogo de lo que es un "controller" dentro de su aplicación MVC.
Por defecto Zend_Tool usa el BasicLoader para encontrar
todos los providers que puede ejecutar. Itera recursivamente todos
los directorios del include path y abre todos los archivos que terminen
con "Manifest.php" o "Provider.php". Todas las clases en estos
archivos son inspeccionadas para ver si implementan
Zend_Tool_Framework_Provider_Interface
o Zend_Tool_Framework_Manifest_ProviderManifestable.
Las instancias de la interfaz provider constituyen la funcionalidad real
y todos sus métodos públicos son accesibles como acciones del provider.
La interfaz ProviderManifestable, sin embargo, requiere la implementación de un
método getProviders() que devuelve un array de
instancias de la interfaz provider ya instanciadas.
Las siguientes reglas de nomenclatura aplican en cuanto a cómo puede acceder a los providers que fueron encontrados por el IncludePathLoader:
La última parte de su nombre de clase dividido por guion bajo se usa para el nombre del provider, por ejemplo "My_Provider_Hello" hace que su provider sea accesible con el nombre "hello".
Si su provider tiene un método
getName()este se usará en lugar del método anterior para determinar el nombre.Si su provider tiene "Provider" como prefijo, por ejemplo se llama
My_HelloProvider, será eliminado del nombre de manera que el provider se llamará "hello".
![]() |
Nota |
|---|---|
El IncludePathLoader no sigue enlaces simbólicos, lo que significa que no puede enlazar funcionalidad de providers en sus include paths, tienen que estar físicamente presentes en los include paths. |
Ejemplo 71.1. Exponer sus providers con un Manifest
Puede exponer sus providers a Zend_Tool
ofreciendo un manifest con un nombre de archivo especial que termine en "Manifest.php".
Un Provider Manifest es una implementación de
Zend_Tool_Framework_Manifest_ProviderManifestable
y requiere que el método getProviders() devuelva
un array de providers instanciados. En anticipación a nuestro primer
provider propio My_Component_HelloProvider
crearemos el siguiente manifest:
class My_Component_Manifest
implements Zend_Tool_Framework_Manifest_ProviderManifestable
{
public function getProviders()
{
return array(
new My_Component_HelloProvider()
);
}
}
Como ejemplo, si un desarrollador quiere agregar la capacidad de mostrar
la versión de un archivo de datos con el que trabaja su componente de terceros,
solo hay una clase que el desarrollador necesitaría implementar.
Suponiendo que el componente se llama My_Component, crearía
una clase llamada My_Component_HelloProvider en un
archivo llamado HelloProvider.php en algún lugar del
include_path. Esta clase implementaría
Zend_Tool_Framework_Provider_Interface, y el cuerpo de
este archivo solo tendría que verse como lo siguiente:
class My_Component_HelloProvider
implements Zend_Tool_Framework_Provider_Interface
{
public function say()
{
echo 'Hello from my provider!';
}
}
Dado el código anterior, y suponiendo que el desarrollador desea acceder a esta funcionalidad a través del cliente de consola, la llamada se vería así:
% zf say hello Hello from my provider!
Como se comentó en la sección de arquitectura, Zend_Tool permite
conectar diferentes clientes para usar sus providers de Zend_Tool.
Para mantenerse compatible con diferentes clientes debería usar el objeto response
para devolver mensajes desde sus providers en lugar de usar
echo() o un mecanismo de salida similar. Reescribiendo nuestro
provider hello con este conocimiento se ve así:
class My_Component_HelloProvider
extends Zend_Tool_Framework_Provider_Abstract
{
public function say()
{
$this->_registry
->getResponse()
->appendContent("Hello from my provider!");
}
}
Como puede ver, uno tiene que extender
Zend_Tool_Framework_Provider_Abstract para ganar acceso a
el Registry que contiene la instancia de
Zend_Tool_Framework_Client_Response.
El ejemplo anterior de "Hello World" es excelente para comandos simples, pero ¿qué pasa con algo más avanzado? A medida que crecen sus necesidades de scripting y herramientas, podría descubrir que necesita la capacidad de aceptar variables. Así como las firmas de funciones tienen parámetros, sus solicitudes de herramientas también pueden aceptar parámetros.
Así como cada solicitud de herramienta puede aislarse en un método dentro de una clase, los parámetros de una solicitud de herramienta también pueden aislarse en un lugar muy conocido. Los parámetros de los métodos de acción de un provider pueden incluir los mismos parámetros que quiere que su cliente utilice al invocar esa combinación de provider y acción. Por ejemplo, si quisiera aceptar un nombre en el ejemplo anterior, probablemente haría esto en código OO:
class My_Component_HelloProvider
implements Zend_Tool_Framework_Provider_Interface
{
public function say($name = 'Ralph')
{
echo 'Hello' . $name . ', from my provider!';
}
}
El ejemplo anterior puede entonces invocarse a través de la línea de comandos zf say hello Joe. "Joe" será suministrado al provider como un parámetro de la llamada al método. Además note, como puede ver, que el parámetro es opcional, lo que significa que también es opcional en la línea de comandos, de manera que zf say hello seguirá funcionando, y por defecto usará el nombre "Ralph".
Hay casos en los que el flujo de trabajo de su provider requiere solicitar entrada al usuario. Esto puede hacerse pidiendo al cliente que pida más de la entrada requerida invocando:
class My_Component_HelloProvider
extends Zend_Tool_Framework_Provider_Abstract
{
public function say($name = 'Ralph')
{
$nameResponse = $this->_registry
->getClient()
->promptInteractiveInput("Whats your name?");
$name = $nameResponse->getContent();
echo 'Hello' . $name . ', from my provider!';
}
}
Este comando lanza una excepción si el cliente actual no es capaz de manejar solicitudes interactivas. En el caso del Console Client por defecto, sin embargo, se le pedirá que introduzca el nombre.
Otra característica interesante que podría desear implementar es la capacidad de simulación (pretendability). La capacidad de simulación es la habilidad de que su provider "simule" que está realizando la combinación solicitada de acción y provider y le dé al usuario tanta información como sea posible sobre lo que haría sin realmente hacerlo. Esto podría ser una noción importante cuando se realizan modificaciones intensivas de base de datos o del sistema de archivos que el usuario podría no querer hacer de otro modo.
La capacidad de simulación es fácil de implementar. Hay dos partes en esta característica: 1) marcar el provider como con capacidad de "simular", y 2) verificar la solicitud para asegurarse de que la solicitud actual efectivamente se pidió que fuera "simulada". Esta característica se demuestra en el ejemplo de código a continuación.
class My_Component_HelloProvider
extends Zend_Tool_Framework_Provider_Abstract
implements Zend_Tool_Framework_Provider_Pretendable
{
public function say($name = 'Ralph')
{
if ($this->_registry->getRequest()->isPretend()) {
echo 'I would say hello to ' . $name . '.';
} else {
echo 'Hello' . $name . ', from my provider!';
}
}
}
Para ejecutar el provider en modo de simulación simplemente llame a:
% zf --pretend say hello Ralph I would say hello Ralph.
También puede ejecutar las acciones de su provider en modos "verbose" o "debug". La semántica con respecto a estas acciones tiene que ser implementada por usted en el contexto de su provider. Puede acceder a los modos debug o verbose con:
class My_Component_HelloProvider
implements Zend_Tool_Framework_Provider_Interface
{
public function say($name = 'Ralph')
{
if($this->_registry->getRequest()->isVerbose()) {
echo "Hello::say has been called\n";
}
if($this->_registry->getRequest()->isDebug()) {
syslog(LOG_INFO, "Hello::say has been called\n");
}
}
}
Usando la variable de entorno ZF_CONFIG_FILE o el
.zf.ini en su directorio home puede inyectar parámetros de configuración en
cualquier provider de Zend_Tool. El acceso a esta configuración
está disponible a través del registry que se pasa a su provider si extiende
Zend_Tool_Framework_Provider_Abstract.
class My_Component_HelloProvider
extends Zend_Tool_Framework_Provider_Abstract
{
public function say()
{
$username = $this->_registry->getConfig()->username;
if(!empty($username)) {
echo "Hello $username!";
} else {
echo "Hello!";
}
}
}
La configuración devuelta es del tipo
Zend_Tool_Framework_Client_Config pero internamente los
métodos mágicos __get() y __set()
actúan como proxy hacia un Zend_Config del
tipo de configuración dado.
El almacenamiento permite guardar datos arbitrarios para referencia posterior. Esto puede ser útil para tareas de procesamiento por lotes o para reejecuciones de sus tareas. Puede acceder al almacenamiento de manera similar a la configuración:
class My_Component_HelloProvider
extends Zend_Tool_Framework_Provider_Abstract
{
public function say()
{
$aValue = $this->_registry->getStorage()->get("myUsername");
echo "Hello $aValue!";
}
}
La API del almacenamiento es muy simple:
class Zend_Tool_Framework_Client_Storage
{
public function setAdapter($adapter);
public function isEnabled();
public function put($name, $value);
public function get($name, $defaultValue=null);
public function has($name);
public function remove($name);
public function getStreamUri($name);
}
![]() |
Importante |
|---|---|
Al diseñar sus providers que sean conscientes de la configuración o el almacenamiento, recuerde verificar si las claves de configuración de usuario o almacenamiento requeridas realmente existen para un usuario. No se encontrará con errores fatales cuando ninguna de estas se proporcione, ya que se crean unas vacías cuando se solicitan. |
Zend_Tool_Project expone un rico conjunto de funcionalidad y
capacidades que hacen que la tarea de crear nuevos providers, específicamente aquellos dirigidos a
proyectos, sea más fácil y manejable.
Este mismo concepto se aplica a los proyectos de Zend Framework. En los proyectos de Zend Framework,
tiene controllers, actions, views, models, bases de datos y demás. En
términos de Zend_Tool, necesitamos una manera de rastrear estos tipos de
recursos - de ahí Zend_Tool_Project.
Zend_Tool_Project es capaz de rastrear los recursos de un proyecto
a lo largo del desarrollo de un proyecto. Así, por ejemplo, si en un comando
creó un controller, y en el siguiente comando desea crear una action dentro
de ese controller, Zend_Tool_Project va a tener que
saber sobre el archivo controller que creó para que pueda (en
la siguiente acción) agregar esa action al mismo. Esto es lo que mantiene nuestros
proyectos actualizados y con estado.
Otro punto importante para entender sobre los proyectos es que, típicamente, los recursos
se organizan de forma jerárquica. Con esto en mente,
Zend_Tool_Project es capaz de serializar el proyecto actual
en una representación interna que le permite hacer seguimiento no solo de
qué recursos son parte de un proyecto en un momento dado, sino
también dónde están en relación entre sí.
Los providers específicos de proyecto se crean de la misma manera que los providers
de framework simples, con una excepción: los providers de proyecto deben extender
Zend_Tool_Project_Provider_Abstract. Esta clase viene con
funcionalidad significativa que ayuda a los desarrolladores a cargar el proyecto existente, obtener
el objeto profile, y poder buscar en el profile, y luego almacenar cualquier cambio
en el profile del proyecto actual.
class My_Component_HelloProvider
extends Zend_Tool_Project_Provider_Abstract
{
public function say()
{
$profile = $this->_loadExistingProfile();
/* ... do project stuff here */
$this->_storeProfile();
}
}
![[Note]](images/note.png)
![[Important]](images/important.png)