2009-07-31 8 views
5

Tengo una página includes.php que cargo al inicio de cada página de mi sitio web. A medida que desarrollo el sitio web, el número de clases que estoy usando va en aumento. Así que terminan con algo como esto:rendimiento de la carga de clases php y el uso de 'extends'

$db = new DB($config); 
$login = new Login($db, $config); 
$form = new Form($db, $config); 

Y la lista sigue y sigue. Tengo dos preguntas sobre esta práctica:

Primero, considerando que podría no estar usando una clase en una página determinada (es posible que no tenga un formulario $ en cada página), ¿cuánto realmente importa, el rendimiento- sabio, para cargar esta clase cada vez que se carga una página dada?

En segundo lugar, puede haber notado que estoy pasando la instancia de clase $ db a todas las otras clases, así como una variable $ config. En el código php de todas las clases, hago algo como esto:

public $db; 
public $config; 

public function __construct($db, $config, $smarty){ 
    $this->db = $db; 
    $this->config = $config; 
} 

luego en los métodos de la clase, que abordan los archivos de base de datos y de configuración con 'esto' como tal:

public function myfunction(){ 
    $this->db; 
    $this->config; 
} 

Cuándo debe Uso 'extends' en lugar de pasar $ db a la clase, suponiendo que cada clase usa el db? ¿Pasar $ db a cada clase duele de alguna manera en términos de rendimiento?

Gracias!

Respuesta

7

Cuando debo usar 'extiende' en lugar de pasar $ db a la clase, asumiendo cada clase utiliza el PP?

Cuando tiene sentido, ¡y solo cuando lo hace!

usted tiene por lo menos dos cosas a considerar:

  • "class A extends B" tipo de medios "class A **is a** B"
    • más claramente, un Car es un MotorVehicule; un MotorVehicule es un Vehicule; un Bus es un MotorVehicule; Una bicicleta es sin embargo un Vehicule
    • , un Ball no es un Vehicule
    • En su caso, una Form sin duda no es un DataBase! Tampoco es un Login
  • En PHP, una clase sólo puede extenduno clase
    • No se puede tener algo que es tanto un Vehicule y un Animal
    • Sin embargo, un Cares unMotorVehicule , que, en sí mismo, es unVehicule:-)

En el caso de un objeto de base de datos (en su caso, se trata más de una conexión a una base de datos), mosts de sus clases serán ellos mismos no "ser" una conexión de base de datos. Entonces, no deberían extender esa clase.

Sin embargo, se utiliza una conexión DB (a Form "tiene una" conexión DB); por lo tanto, deberían tener una propiedad que represente esa conexión DB. Eso es lo que estás haciendo.


En lugar de pasar $db a cada constructor, es posible utilizar

  • ya sea el patrón Singleton diseño
  • o el patrón de diseño Registro
  • o algún tipo de variable global, pero eso es casi lo lo mismo ... simplemente empeorando (no OOP y todo eso)!

Pero pasar el objeto $db es ideal para probar unidades, simular objetos y todo eso ...
creo que podría ser considerado como el patrón de diseño inyección de dependencias, por cierto (no estoy seguro, pero parece que)


sobre cómo cargar un montón de clases, otras personas dieron respuestas:

  • uso carga automática si se puede
  • utilizar una caché de código de operación, como APC, si es posible

Ambos son grandes sugerencias que se deben tener en cuenta ;-)


Una última cosa:

¿El pasar $ db a todas las clases herido de ninguna manera en términos de rendimiento?

Tal vez hace un poco poco ; pero, honestamente, excepto si eres google y tienes millones de usuarios ... ¿a quién le importa?

Si está haciendo un par de consultas DB, éstas tomarán MUCHO tiempo, ¡comparando con pasar un parámetro más a incluso una docena de métodos!
Así, la pequeña cantidad de tiempo que pasa utilizado paremeters probablemente se puede descuidar :-)

+0

¡Excelente y completo! Muchas gracias. –

+0

De nada :-) Diviértete! –

+1

Ampliar las clases ha sido un pequeño misterio para mí desde hace un tiempo, esta es una gran y simple explicación que instantáneamente me dejó muy claro cuándo usarla. – Kokos

4

¿Has probado algo como esto?

function __autoload($class_name) { 
require_once("includes/php/class." . $class_name . ".php"); 
} 

Por lo tanto, solo carga el nombre de la clase cuando se encuentra el nombre de la clase. (Cambie la ruta para adaptarla a sus clases php ... las mías son como class.Object.php, con el nombre de clase "Object").

+1

añadir a esto lo jeyoung dijo: que realmente sólo debe cargar lo que necesita * * cuando lo necesite presente. Todavía hay algunas preguntas sin respuesta en esta publicación (cuándo usar extends), que podrían extraerse mejor en las nuevas preguntas de SO. –

+0

¿Pondré este código en mi archivo de inclusión o en mis clases? ¿No encontrará siempre la variable, sin embargo, ya que instanciaré la clase directamente después de cargar el archivo? Gracias! –

+0

Poner este código en su header.php (que está incluido en todos sus archivos). ¿Puedes explicar a qué te refieres con instanciar la clase inmediatamente después de cargar el archivo? – Dirk

1

¿Por qué no incluir solo los archivos que deben incluirse? Además, intente crear una instancia solo de los objetos que necesite donde los necesite. Tal como está, su includes.php está haciendo una gran cantidad de instancias que puede que no necesite todo el tiempo.

Si se pasa $db como referencia, no debería afectar el rendimiento. (No sé mucho acerca de PHP5, pero con PHP4 no había un concepto de referencia con la '&' modificador.)

+0

Siempre me he preguntado, ¿qué hace el símbolo de la y comercial (&) en PHP? –

+2

La & le da una referencia a una variable. En PHP5 no deberías tener que usar esto como método para mejorar el rendimiento (PHP hace copy-on-write). También en PHP5 las variables de objeto ya son referencias al objeto, por lo que los objetos no se copian a menos que use 'clone'. –

2

Si carga y análisis de los archivos de script se convierte en un cuello de botella se puede utilizar una caché de código de bytes como apc para acelerar esta parte del ciclo de vida.

+0

¿Qué hace exactamente la APC? –

+0

Cuando PHP carga un script, tiene que analizar los contenidos en códigos de operación. apc almacena estos códigos de operación así que la próxima vez no hay necesidad de ejecutar el analizador. Si deshabilita la comprobación de estadísticas, incluso es posible evitar el acceso a archivos (relativamente lento). – VolkerK

1

No estoy seguro de exactamente cómo le gustaría usar la herencia ('extends') aquí. Puede usarlo para definir los dos campos $db y $config, pero de lo contrario no cambiaría demasiado.

Además, podría limitarte cuando realmente quieras heredar algo útil de otra clase.

Dependiendo de su diseño, es posible que desee considerar la fabricación de $config global. ¿Hay una situación en la que hay más de 1 configuración activa al mismo tiempo? Sin embargo, probablemente no sea una buena idea introducir una variable global $db. Es concebible que pueda necesitar más de una conexión de base de datos al mismo tiempo, por ejemplo.

+0

La única razón por la que no uso $ config como global es porque escuché que es inseguro. El nombre de usuario y la contraseña de mi base de datos se almacenan en el archivo de configuración. ¿No hay un problema de seguridad real al declarar variables globales? –

Cuestiones relacionadas