Pautas de construcción en ZEND

LIBP-0106 (Libro de pautas)

A continuación se van a ofrecer un conjunto de pautas para normalizar buenas prácticas en el desarrollo de aplicaciones en PHP mediante el framework ZEND.

Pautas

TítuloCarácter
Mejorar la carga de clasesObligatoria
Eliminar las instrucciones require_once innecesariasRecomendada
Mejorar la carga de los plugins Obligatoria
Reducir la sobrecarga introducida por Zend_Db_Table para recuperar los metadatos de la tablaObligatoria
Mejorar el uso de los índices con Zend_Db_Select Obligatoria
Mejorar la resolución de los view helpersObligatoria
Mejorar la velocidad de las vistas parcialesObligatoria

Mejorar la carga de clases

Cualquiera que haya realizado perfiles de una aplicación de Zend Framework sabrá inmediatamente que la carga de clases es relativamente cara en Zend Framework. Una optimización trivial que puede hacer para aumentar la velocidad de carga de clases es prestar atención cuidadosa a su include_path. En particular, debe hacer cuatro cosas

  • Utilice la ruta absoluta (o rutas relativas a rutas absolutas),
  • Reducir el número de include_path a definir,
  • Tener el include_path lo antes posible,
  • Sólo incluir la ruta del directorio actual al final de su include_path.

Eliminar las instrucciones require_once innecesarias

Lazy loading es una técnica de optimización diseñada para impulsar la operación de hacer la carga de un archivo de clase esperando hasta el último momento ( es decir, cuando se instancia un objeto de esa clase, se llama a un método de clase estático, o hacen referencia a una propiedad de clase constante o estática). PHP soporta la carga automática a través de este tipo, que le permite definir uno o más callbacks para ejecutar con el fin de asignar un nombre de clase en un archivo.

Sin embargo, la mayoría de los beneficios que puede obtener de carga automática se eliminan si el código de la biblioteca sigue realizando llamadas del tipo require_once () (que es precisamente el caso de Zend Framework). Entonces, la pregunta es ¿cómo se puede eliminar esas llamadas require_once () a fin de maximizar el rendimiento del cargador automático?

Una manera simple de reducir las llamadas require_once() es utilizar las utilidades Unix en conjunción con comentar las llamadas. Un ejemplo:

% cd path/to/ZendFramework/library
      % find . -name '*.php' -not -wholename '*/Loader/Autoloader.php' \
        -not -wholename '*/Application.php' -print0 | \
        xargs -0 sed --regexp-extended --in-place 's/(require_once)/\/\/ \1/g'

Este código ,de una sola línea (separado en dos líneas para facilitar su lectura), recorre en iteración cada archivo PHP y reemplaza cada instancia de "require_once" por "/ / require_once ', efectivamente comentando cada uno . (Se mantiene selectivamente require_once () las llamadas dentro de Zend_Application y Zend_Loader_Autoloader, ya que en estas clases se producirá un error sin ellos.)

Este comando puede ser añadido a una construcción automatizada o liberar el proceso trivial, ayudando a mejorar el rendimiento en su aplicación de producción. Cabe señalar, sin embargo, que si utiliza esta técnica, debe utilizar la carga automática, puede hacerlo desde su archivo "public/index.php" con el siguiente código:

require_once 'Zend/Loader/Autoloader.php';
      Zend_Loader_Autoloader::getInstance();

Mejorar la carga de los plugins

Muchos componentes tienen plugins que permiten crear sus propias clases para utilizar el componente, incluso sobrescribiendo las existentes en el marco. Esto proporciona flexibilidad importante al marco pero a un precio: el proceso de cargar el plugin es una tarea bastante costosa.

El cargador de plugin permite registrar el par prefijo clase y path, permitiendole que especifique el fichero de clase en paths no estandars. Cada prefijo puede tener asociado varios path con el. Internamente, el cargador de plugins engancha cada prefijo, y entonces adjunta cada path comprobando que existe el fichero y esta en modo lectura en ese path. Entonces lo carga, comprueba que la clase que buscaba esta disponible. Como puede imaginar , esto provoca un numero muy elevado de llamadas al sistema

Si multiplicamos esto por el número de componentes que llaman al Plugin Loader, nos podemos hacer una idea de la importancia de mejorarlo. Estos son algunos de los componentes que hacen uso del Plugin loader.

  • Zend_Controller_Action_HelperBroker: helpers
  • Zend_Dojo: view helpers, elementos de formularios y decoradores
  • Zend_File_Transfer: adaptadores
  • Zend_Filter_Inflector: filtros
  • Zend_Filter_Input: filters and validators
  • Zend_Form: validadores, filtros, elementos, captcha
  • Zend_Paginator: adaptadores
  • Zend_View: helpers, filtros

Para reducir el numero de llamadas es recomendable usar la cache de archivos que incluye PluginLoader. Esta funcionalidad escribe llamadas a " include_once()" al fichero, que podrá incluir en su arranque. Si bien esto crea llamadas include_once() en su código, también asegura que los beneficios PluginLoader se obtienen lo antes posible.

Reducir la sobrecarga introducida por Zend_Db_Table para recuperar los metadatos de la tabla

A fin de mantener el uso de lo más simple posible, y también para apoyar el soporte de cambios durante el desarrollo de esquemas, Zend_Db_Table primero obtiene el esquema de la tabla y lo guarda dentro de los miembros del objeto. Esta operación suele ser cara, independientemente de la base de datos y pueden contribuir a los cuellos de botella en la producción.

Afortunadamente hay técnicas que permiten mejorar la situación

  • Zend_Db_Table puede utilizar la Zend_Cache para cachear tablas de metadatos. Esto normalmente es mas rápido en el acceso y mas barato que buscar el dato en la base de datos directamente.
  • Codificar los datos en la definición de la tabla. Zend_Db_Table también provee de soporte para codificar los metadatos en la definición de la tabla. Esto es un avance en el uso y solo debe de usarse cuando estamos seguro que el esquema no va a cambiar o se es capaz de guardar las definiciones a actualizar.

Mejorar el uso de los índices con Zend_Db_Select

Zend_Db_Select es relativamente buena en su trabajo. Sin embargo, si va a realizar consultas complejas que requieren joins o sub-selecciones, a menudo puede ser bastante ingenuo. Se puede mejorar su uso.

La única respuesta real es escribir su propio SQL; Zend_Db no requiere el uso de Zend_Db_Select, por lo que proporcionar su propia sintaxis de declaraciones Select SQL es un método perfectamente legítimo, ejecutar EXPLAIN en sus consultas, y probar una variedad de enfoques de forma fiable hasta que se puede obtener su índices con mayor rendimiento (y luego codificar el SQL como una propiedad de clase o constante).

Si el SQL requiere argumentos variables, proporcione marcadores de posición en el SQL, y utilice una combinación de vsprintf () y array_walk () para inyectar los valores en el código SQL:

// $adapter is the DB adapter. In Zend_Db_Table, retrieve
// it using $this->getAdapter().
$sql = vsprintf(
self::SELECT_FOO,
array_walk($values, array($adapter, 'quoteInto'))
      );

Mejorar la resolución de los view helpers

La mayoría de "métodos" Zend_View son realmente proporcionados a través de la sobrecarga en el sistema auxiliar. Esto proporciona una flexibilidad importante a Zend_View, y ademas de la necesidad de ampliar Zend_View y proporcionar todos los métodos helpers que pueden utilizar en su aplicación, puede definir sus métodos helpers en clases separadas y consumir a voluntad como si fueran métodos directos de Zend_View. Esto mantiene el punto de vista propio del objeto relativamente débil, y asegura que los objetos se crean sólo cuando sea necesario.

Internamente,Zend_View utiliza el PluginLoader para buscar a las clases helpers. Esto significa que por cada helper que se llama, Zend_View necesita pasar el nombre del helper al PluginLoader, que entonces necesita determinar el nombre de la clase, cargar la clase si es necesario y entonces devolver el nombre de la clase para que sea instanciada. Como consecuencia el uso de helper es mucho mas rápido pero es necesario que su resolución sea rápida Es recomendable seguir una consideración previamente vista, utilizar la cache de archivos que incluye PluginLoader

Mejorar la velocidad de las vistas parciales

Aquellos que usan vistas parciales pesadas , se vuelve evidente que el partial() view helper incurre en un montón de gastos generales, debido a la necesidad de clonar el objeto de vista.Es necesario mejorar esta situación.

En primer lugar, es recomendable utilizar partial() solo cuando realmente sea justificado. El partial() view helper acepta tres argumentos:

  • $name:nombre de la vista a renderizar
  • $module:Nombre del modulo donde reside la vista
  • $model:un array o objeto a pasar a la representación parcial para limpiar los datos a asignar a la vista.

El poder de usar partial() proviene del segundo y tercer argumento. El argumento $module permite a partial() añadir temporalmente la ruta a un script para el módulo dado para que el script de vista parciales se resuelva en ese módulo; el argumento $model te permite pasar variables explicitas para usarlas con la vista parcial. Básicamente, a menos que estés pasando variables a partial y necesites limpiar el ámbito de la variable, o renderizar un script vista de otro módulo, no hay razon para incurrir en sobreuso de partial()