otro otra llamar incluir funcion desde conexion carpeta archivo php performance require-once

otra - llamar funcion php desde otro php



¿Por qué require_once es tan malo de usar? (14)

Todo lo que leo acerca de mejores prácticas de codificación PHP sigue diciendo que no use require_once debido a la velocidad.

¿Por qué es esto?

¿Cuál es la forma correcta / mejor de hacer lo mismo que require_once ? Si es importante, estoy usando PHP5.


¿Puede darnos algún enlace a estas prácticas de codificación que dicen evitarlo? En lo que a mí respecta, es un completo no problema . No he revisado el código fuente yo mismo, pero me imagino que la única diferencia entre include e include_once es que include_once agrega ese nombre de archivo a una matriz y comprueba la matriz cada vez. Sería fácil mantener ordenada esa matriz, por lo que buscarla debería ser O (log n), e incluso una aplicación medianamente grande solo tendría un par de docenas.


Creo que en la documentación de PEAR, hay una recomendación para require, require_once, include e include_once. Sí sigo esa pauta. Su aplicación sería más clara.


Este hilo me hace temblar, porque ya ha habido una "solución publicada", y es, para todos los efectos, incorrecta. Vamos a enumerar:

  1. Las definiciones son realmente caras en PHP. Puede buscarlo o probarlo usted mismo, pero la única forma eficiente de definir una constante global en PHP es a través de una extensión. (Las constantes de clase en realidad son bastante deficientes en cuanto al rendimiento, pero este es un punto discutible, debido a 2)

  2. Si está utilizando require_once() apropiadamente, es decir, para la inclusión de clases, ni siquiera necesita una definición; simplemente verifique si class_exists(''Classname'') . Si el archivo que está incluyendo contiene código, es decir, si lo está usando de manera procedimental, no hay absolutamente ninguna razón por la cual require_once() sea ​​necesario para usted; cada vez que incluya el archivo, suponga que está realizando una llamada de subrutina.

Entonces, durante un tiempo, mucha gente usó el método class_exists() para sus inclusiones. No me gusta porque es fugly, pero tenían buenas razones para: require_once() era bastante ineficiente antes de algunas de las versiones más recientes de PHP. Pero eso ha sido resuelto, y es mi opinión que el bytecode adicional que tendrías que compilar para el condicional, y la llamada al método extra, superarían con creces cualquier verificación interna de hashtable.

Ahora, una admisión: esto es difícil de probar, porque representa tan poco tiempo de ejecución.

Esta es la pregunta que debería tener en cuenta: incluye, como regla general, es costoso en PHP, porque cada vez que el intérprete le pega a uno tiene que volver al modo de análisis, generar los códigos de operación y luego retroceder. Si tiene más de 100, esto definitivamente tendrá un impacto en el rendimiento. La razón por la que usar o no el uso de require_once es una pregunta tan importante es porque dificulta la vida de los cachés de opcode. Una explicación para esto se puede encontrar aquí, pero a lo que se reduce esto es a que:

  • Si durante el análisis, usted sabe exactamente qué archivos de inclusión necesitará durante toda la vida de la solicitud, require() los mismos desde el principio y el caché del código de operación se encargará de todo lo demás por usted.

  • Si no está ejecutando un caché de código de operación, está en un lugar difícil. Inventar todas sus inclusiones en un solo archivo (no lo haga durante el desarrollo, solo en producción) sin duda puede ayudar a analizar el tiempo, pero es un dolor hacerlo, y también, necesita saber exactamente qué incluirá durante el proceso. solicitud.

  • Autoload es muy conveniente, pero lento, por la razón de que la lógica de autocarga debe ejecutarse cada vez que se realiza una inclusión. En la práctica, descubrí que la carga automática de varios archivos especializados para una solicitud no causa demasiado problema, pero no debe cargar automáticamente todos los archivos que necesitará.

  • Si tiene tal vez 10 incluye (esto es un cálculo muy atrás del sobre), toda esta masturbación no vale la pena: simplemente optimice las consultas de su base de datos o algo así.


Incluso si require_once e include_once son más lentos que require e include (o las alternativas que puedan existir), estamos hablando del menor nivel de micro-optimización aquí. Su tiempo se gasta mucho mejor al optimizar ese bucle mal escrito o la consulta de la base de datos que preocuparse por algo como require_once .

Ahora, uno podría argumentar que require_once permite prácticas de codificación deficientes porque no necesita prestar atención para mantener sus includes limpios y organizados, pero eso no tiene nada que ver con la función en y especialmente con su velocidad.

Obviamente, la carga automática es mejor en aras de la limpieza del código y la facilidad de mantenimiento, pero quiero dejar en claro que esto no tiene nada que ver con la velocidad .


La wiki de PEAR2 (cuando existía) solía enumerar buenas razones para abandonar todas las directivas de requerir / incluir a favor de la carga automática , al menos para el código de la biblioteca. Estos lo atan a estructuras de directorio rígidas cuando los modelos de empaque alternativos como phar están en el horizonte.

Actualización: como la versión archivada en la web de la wiki es fea, he copiado las razones más convincentes a continuación:

  • include_path es necesario para usar un paquete (PEAR). Esto hace que sea difícil agrupar un paquete PEAR dentro de otra aplicación con su propio include_path, para crear un único archivo que contenga las clases necesarias, para mover un paquete PEAR a un archivo phar sin una modificación extensa del código fuente.
  • cuando require_once de nivel superior se mezcla con require_once condicional, esto puede dar como resultado un código que no se puede descartar por cachés de opcode como APC, que se combinarán con PHP 6.
  • relative require_once requiere que include_path ya esté configurado con el valor correcto, por lo que es imposible usar un paquete sin include_path adecuado

Las *_once() cada directorio principal para garantizar que el archivo que está incluyendo no sea el mismo que el que ya se ha incluido. Esa es parte de la razón de la desaceleración.

Recomiendo usar una herramienta como Siege para el benchmarking. Puede probar todas las metodologías sugeridas y comparar los tiempos de respuesta.

Más sobre require_once() en Tech Your Universe .


Mi opinión personal es que el uso de require_once (o include_once) es una mala práctica porque require_once comprueba si ya incluiste ese archivo y suprime los errores de los archivos dobles incluidos, lo que resulta en errores fatales (como la declaración duplicada de funciones / clases / etc.) .

Debe saber si necesita incluir un archivo.


No está usando la función que está mal. Es una comprensión incorrecta de cómo y cuándo usarlo, en una base de código general. Añadiré un poco más de contexto a esa noción posiblemente malentendida:

La gente no debería pensar que require_once es una función lenta. Tienes que incluir tu código de una forma u otra. require_once() vs. require() ''s velocidad no es el problema. Se trata del rendimiento que obstaculiza las advertencias que pueden resultar para usarlo a ciegas. Si se usa ampliamente sin tener en cuenta el contexto, puede generar un gran desperdicio de memoria o un código inútil.

Lo que he visto que es realmente malo es cuando enormes frameworks monolíticos usan require_once() de todas las maneras incorrectas, especialmente en un entorno complejo orientado a objetos.

Tome el ejemplo de usar require_once() en la parte superior de cada clase como se ve en muchas bibliotecas:

require_once("includes/usergroups.php"); require_once("includes/permissions.php"); require_once("includes/revisions.php"); class User{ //user functions }

Entonces, la clase de User está diseñada para usar las otras 3 clases. ¡Lo suficientemente justo! Pero ahora, ¿qué require_once("includes/user.php"); si un visitante está navegando por el sitio y ni siquiera ha iniciado sesión y el marco carga: require_once("includes/user.php"); para cada solicitud individual.

Incluye 1 + 3 clases innecesarias que nunca usará durante esa solicitud en particular. Así es como los marcos inflados terminan utilizando 40 MB por solicitud en lugar de 5 MB o menos.

¡Las otras formas en que puede ser mal utilizado, es cuando una clase es reutilizada por muchos otros! Supongamos que tiene alrededor de 50 clases que usan funciones helper . Para asegurarte de que los helpers estén disponibles para esas clases cuando se cargan, obtienes:

require_once("includes/helpers.php"); class MyClass{ //Helper::functions();//etc.. }

No hay nada malo aquí per se. Sin embargo, si una solicitud de una página incluye 15 clases similares. Está ejecutando require_once 15 veces, o para un buen visual:

require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php"); require_once("includes/helpers.php");

El uso de require_once () afecta técnicamente el rendimiento para ejecutar esa función 14 veces, además de tener que analizar esas líneas innecesarias. Con solo otras 10 clases muy usadas con ese problema similar, podría dar cuenta de más de 100 líneas de dicho código repetitivo bastante inútil.

Con eso, probablemente valga la pena usar require("includes/helpers.php"); en el arranque de su aplicación o marco, en su lugar. Pero dado que todo es relativo, todo depende de si vale la pena guardar 15-100 líneas de require_once() frecuencia de uso del peso de la clase de helpers . Pero si la probabilidad de no usar el archivo helpers en cualquier solicitud dada es ninguna, entonces require definitivamente debe estar en su clase principal. Tener require_once en cada clase por separado se convierte en un desperdicio de recursos.

La función require_once es útil cuando es necesario, pero no debe considerarse como una solución monolítica para usar en todas partes para cargar todas las clases.


No tiene nada que ver con la velocidad. Se trata de fallar con gracia.

Si require_once () falla, su script está hecho. Nada más es procesado. Si usa include_once (), el resto de la secuencia de comandos tratará de seguir procesando, por lo que los usuarios podrían no ser acertados en algo que haya fallado en la secuencia de comandos.


Sí, es un poco más caro que simple ol ''require (). Creo que el punto es que si puede mantener su código lo suficientemente organizado como para no duplicarlo, no use las funciones * _once (), ya que le ahorrará algunos ciclos.

Pero usar las funciones _once () no va a matar tu aplicación. Básicamente, simplemente no lo use como una excusa para no tener que organizar sus inclusiones . En algunos casos, usarlo todavía es inevitable, y no es gran cosa.


Sentí curiosidad y revisé el enlace de Adam Backstrom con Tech Your Universe . Este artículo describe una de las razones que requieren que se use en lugar de require_once. Sin embargo, sus afirmaciones no resistieron mi análisis. Me interesaría ver dónde puedo haber mal analizado la solución. Utilicé php 5.2.0 para las comparaciones.

Comencé creando 100 archivos de encabezado que usaban require_once para incluir otro archivo de encabezado. Cada uno de estos archivos se veía algo así como:

<?php // /home/fbarnes/phpperf/hdr0.php require_once "../phpperf/common_hdr.php"; ?>

Creé estos usando un truco rápido de bash:

for i in /home/fbarnes/phpperf/hdr{00..99}.php; do echo "<?php // $i" > $i cat helper.php >> $i; done

De esta manera podría intercambiar fácilmente entre require_once y require al incluir los archivos de encabezado. Luego creé un app.php para cargar los cien archivos. Esto se veía así:

<?php // Load all of the php hdrs that were created previously for($i=0; $i < 100; $i++) { require_once "/home/fbarnes/phpperf/hdr$i.php"; } // Read the /proc file system to get some simple stats $pid = getmypid(); $fp = fopen("/proc/$pid/stat", "r"); $line = fread($fp, 2048); $array = split(" ", $line); // write out the statistics; on RedHat 4.5 w/ kernel 2.6.9 // 14 is user jiffies; 15 is system jiffies $cntr = 0; foreach($array as $elem) { $cntr++; echo "stat[$cntr]: $elem/n"; } fclose($fp); ?>

Comparé los encabezados require_once con los encabezados obligatorios que usaban un archivo de encabezado con el siguiente aspecto:

<?php // /home/fbarnes/phpperf/h/hdr0.php if(!defined(''CommonHdr'')) { require "../phpperf/common_hdr.php"; define(''CommonHdr'', 1); } ?>

No encontré mucha diferencia al ejecutar esto con require vs. require_once. De hecho, mis pruebas iniciales parecían implicar que require_once era un poco más rápido, pero no creo necesariamente eso. Repetí el experimento con 10000 archivos de entrada. Aquí vi una diferencia consistente. Ejecuté la prueba varias veces, los resultados están cerca pero el uso de require_once usa en promedio 30.8 jiffies de usuario y 72.6 jiffies del sistema; el uso requiere usos en promedio de 39.4 jiffies de usuario y 72.0 jiffies del sistema. Por lo tanto, parece que la carga es ligeramente inferior usando require_once. Sin embargo, el reloj de pared se incrementa ligeramente. Las 10,000 llamadas require_once usan 10.15 segundos para completar en promedio y 10,000 requieren llamadas usan 9.84 segundos en promedio.

El siguiente paso es analizar estas diferencias. Usé strace para analizar las llamadas al sistema que se están realizando.

Antes de abrir un archivo desde require_once, se realizan las siguientes llamadas al sistema:

time(NULL) = 1223772434 lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat64("/home/fbarnes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat64("/home/fbarnes/phpperf", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat64("/home/fbarnes/phpperf/h", {st_mode=S_IFDIR|0755, st_size=270336, ...}) = 0 lstat64("/home/fbarnes/phpperf/h/hdr0.php", {st_mode=S_IFREG|0644, st_size=88, ...}) = 0 time(NULL) = 1223772434 open("/home/fbarnes/phpperf/h/hdr0.php", O_RDONLY) = 3

Esto contrasta con require:

time(NULL) = 1223772905 lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat64("/home/fbarnes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat64("/home/fbarnes/phpperf", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat64("/home/fbarnes/phpperf/h", {st_mode=S_IFDIR|0755, st_size=270336, ...}) = 0 lstat64("/home/fbarnes/phpperf/h/hdr0.php", {st_mode=S_IFREG|0644, st_size=146, ...}) = 0 time(NULL) = 1223772905 open("/home/fbarnes/phpperf/h/hdr0.php", O_RDONLY) = 3

Tech Your Universe implica que require_once debe realizar más llamadas lstat64. Sin embargo, ambos hacen la misma cantidad de llamadas lstat64. Posiblemente, la diferencia es que no estoy ejecutando APC para optimizar el código anterior. Sin embargo, lo siguiente que hice fue comparar el rendimiento de strace para todas las ejecuciones:

[fbarnes@myhost phpperf]$ wc -l strace_1000r.out strace_1000ro.out 190709 strace_1000r.out 210707 strace_1000ro.out 401416 total

Efectivamente hay aproximadamente dos llamadas al sistema más por archivo de encabezado cuando se usa require_once. Una diferencia es que require_once tiene una llamada adicional a la función time ():

[fbarnes@myhost phpperf]$ grep -c time strace_1000r.out strace_1000ro.out strace_1000r.out:20009 strace_1000ro.out:30008

La otra llamada al sistema es getcwd ():

[fbarnes@myhost phpperf]$ grep -c getcwd strace_1000r.out strace_1000ro.out strace_1000r.out:5 strace_1000ro.out:10004

Esto se llama porque decidí la ruta relativa a la que se hace referencia en los archivos hdrXXX. Si hago de esto una referencia absoluta, la única diferencia es la llamada de tiempo adicional (NULL) realizada en el código:

[fbarnes@myhost phpperf]$ wc -l strace_1000r.out strace_1000ro.out 190705 strace_1000r.out 200705 strace_1000ro.out 391410 total [fbarnes@myhost phpperf]$ grep -c time strace_1000r.out strace_1000ro.out strace_1000r.out:20008 strace_1000ro.out:30008

Esto parece implicar que puede reducir el número de llamadas al sistema utilizando rutas absolutas en lugar de rutas relativas. La única diferencia fuera de eso son las llamadas de tiempo (NULL) que parecen usarse para instrumentar el código para comparar lo que es más rápido.

Otra nota es que el paquete de optimización de APC tiene una opción llamada "apc.include_once_override" que afirma que reduce el número de llamadas al sistema realizadas por require_once y include_once calls (consulte los documentos de PHP ).

Perdón por la larga publicación. Tengo curiosidad.


Una mejor manera de hacer las cosas es usar un enfoque orientado a objetos y usar __autoload() .


Usted prueba, usando include, la alternativa de oli y __autoload (); y probarlo con algo como APC instalado.

Dudo que usar constante acelere las cosas.


require_once e include_once requieren que el sistema mantenga un registro de lo que ya se ha incluido / requerido. Cada *_once llamada *_once significa verificar ese registro. ¿Entonces definitivamente se está haciendo algo de trabajo adicional pero lo suficiente como para perjudicar la velocidad de toda la aplicación?

... Realmente lo dudo ... No a menos que tengas un hardware realmente viejo o lo hagas mucho .

Si está haciendo miles de *_once , podría hacer el trabajo usted mismo de una manera más ligera. Para aplicaciones simples, basta con asegurarse de que solo lo haya incluido una vez , pero si aún está redefiniendo los errores, podría hacer algo como esto:

if (!defined(''MyIncludeName'')) { require(''MyIncludeName''); define(''MyIncludeName'', 1); }

Personalmente me quedaré con las declaraciones de *_once pero en un punto de referencia de millones de pases, puedes ver la diferencia entre los dos:

php hhvm if defined 0.18587779998779 0.046600103378296 require_once 1.2219581604004 3.2908599376678

10-100 veces más lento con require_once y es curioso que require_once sea ​​aparentemente más lento en hhvm . De nuevo, esto solo es relevante para tu código si estás ejecutando *_once miles de veces.

<?php // test.php $LIMIT = 1000000; $start = microtime(true); for ($i=0; $i<$LIMIT; $i++) if (!defined(''include.php'')) { require(''include.php''); define(''include.php'', 1); } $mid = microtime(true); for ($i=0; $i<$LIMIT; $i++) require_once(''include.php''); $end = microtime(true); printf("if defined/t%s/nrequire_once/t%s/n", $mid-$start, $end-$mid);

<?php // include.php // do nothing.