2008-11-25 15 views
14

Estoy agregando avatares a un motor de foro que estoy diseñando, y estoy debatiendo si hacer algo simple (la imagen del foro se llama .png) y uso PHP para verificar si el archivo existe antes de mostrarlo, o para hacer algo un poco más complicado (pero no mucho) y use un campo de base de datos para contener el nombre de la imagen que se mostrará.¿File_exist() en PHP es una operación muy costosa?

Prefiero ir con el método file_exists() personalmente, ya que eso me da una manera fácil de recurrir a un avatar "predeterminado" si el actual no existe (aún), y es simple de implementar código sabio Sin embargo, me preocupa el rendimiento, ya que se ejecutará una vez por usuario, que se mostrará por página en las páginas de lectura del foro. Entonces, me gustaría saber si la función file_exists() en PHP causa alguna desaceleración importante que causaría importantes impactos de rendimiento en condiciones de mucho tráfico.

Si no, genial. Si lo hace, ¿cuál es su opinión sobre las alternativas para realizar un seguimiento de una imagen subida por el usuario? ¡Gracias!

PD: Las diferencias de código que puedo ver son que las versiones de comprobación de archivos permiten que los archivos hablen, mientras que el formulario de base de datos confía en que la base de datos es precisa y no se molesta en verificar. (es solo una URL que se pasa al navegador, por supuesto.)

Respuesta

12

Además de lo que han dicho los otros carteles, el resultado de file_exists() es almacenado en caché automáticamente por PHP para mejorar el rendimiento.

Sin embargo, si ya está leyendo la información del usuario de la base de datos, también puede almacenar la información allí. Si el usuario solo tiene permitido un avatar, puede almacenar un solo bit en una columna para "tiene avatar" (1/0), y luego tener el nombre de archivo igual que el ID de usuario, y usar algo como SELECT CONCAT(IF(has_avatar, id, 'default'), '.png') AS avatar FROM users

También podría considerar almacenar la imagen real en la base de datos como un BLOB. Póngalo en su propia tabla en lugar de adjuntarlo como una columna a la tabla del usuario. Esto tiene la ventaja de que hace que su foro sea muy fácil de realizar; solo exporta la base de datos.

+0

La información del caché es muy tranquilizadora, terminé yendo con la solución file_exists. Sin embargo, la idea de BLOB parece muy interesante, podría intentarlo más adelante. ¡Gracias! –

+6

pero BLOB no es bueno para el rendimiento. Usted obtiene sobrecarga de ejecutar PHP, MySQL, y tendrá que escribir soporte para la validación de caché HTTP, de lo contrario, los navegadores seguirán descargando avatares innecesariamente. – Kornel

+4

Es importante tener en cuenta que PHP solo almacenará en caché los resultados de los archivos que existen, no almacenará en caché los resultados de los archivos que no existen. Ver: http://www.php.net/manual/en/function.clearstatcache.php – Brian

7

Dado que su servidor web ya estará haciendo muchas (el equivalente de) operaciones file_exists() en el proceso de mostrar su página web, una más ejecutar su script probablemente no tendrá un impacto mensurable. El servidor web probablemente hará al menos:

  • uno para cada subdirectorio de la raíz de la tela (para comprobar la existencia y para enlaces)
  • uno para comprobar si hay un archivo .htaccess para cada subdirectorio de la raíz web
  • uno para la existencia de la secuencia de comandos

Esto no está considerando más de ellos que PHP puede hacer en sí.

0

file_exists() no es lento per se. El problema real es cómo se configura su sistema y dónde están los cuellos de botella de rendimiento. Recuerde que las bases de datos también deben almacenar cosas en el disco, de modo que puede estar enfrentando la actividad del disco. Por otro lado, tanto las bases de datos como los sistemas de archivos generalmente tienen algún tipo de almacenamiento en caché transparente para optimizar el acceso repetido.

Puede ir fácilmente en cualquier dirección, ya que es probable que su cuello de botella de rendimiento esté en otra parte. El único lugar donde puedo ver que es una opción obvia sería si estás en un tipo de hosting compartido sobrevendido donde hay una tonelada de contención de disco, pero tal vez el acceso a la base de datos está en un clúster separado y más rápido (o viceversa).

0

En el pasado he almacenado los metadatos de la imagen en una base de datos (incluido su nombre) para poder generar estadísticas útiles. Más importante aún, el almacenamiento de datos de imagen (no el archivo en sí, solo los metadatos) es propicio para el cambio. ¿Qué pasa si en el futuro necesita "aprobar" la imagen, o si desea eliminarla sin eliminar el archivo?

Según el avatar "predeterminado" ... bueno, si el registro no se encuentra para ese usuario, simplemente use el predeterminado.

De cualquier manera, file_exists() o db, no debería ser un cuello de botella de que preocuparse. Una solución, sin embargo, es mucho más ampliable.

+0

Has votado negativamente y no estoy seguro de por qué, esta es una buena respuesta y nunca pensé en ello. –

+0

He adoptado algunos seguidores que rechazaron todo lo que hago. –

+0

No puedo comentar en la respuesta correcta, pero una cosa más: NO ALMACENE LAS IMÁGENES COMO BLOB. Es un rendimiento realmente malo.Créanme, ha sido discutido ad infinitum en toda la web. –

0

Si el rendimiento es su única consideración, file_exists() será mucho menos costoso que una búsqueda en la base de datos.

Después de todo esto es solo una búsqueda en el directorio usando llamadas al sistema. Después de la primera ejecución del script, la mayor parte del directorio relevante se almacenará en caché en el almacenamiento, por lo que hay muy poca E/S real involucrada, y "file_exists()" es una operación tan común que tanto él como las llamadas al sistema subyacentes serán altamente optimizado en cualquier combinación común de php/os.

Como señaló John II. Si la funcionalidad adicional y las funciones de interfaz de usuario son una prioridad, una base de datos sería el camino a seguir.

8

En las pruebas de rendimiento reales, descubrirá que file_exists es muy rápido. Tal como está, en php, cuando la misma url es "stat" 'd dos veces, la segunda llamada se extrae de la memoria caché de estadísticas interna de php.

Y eso es solo en el ámbito de ejecución de php. Incluso entre ejecuciones, el sistema de archivos/os tenderá a poner agresivamente el archivo en la caché del sistema de archivos, y si el archivo es lo suficientemente pequeño, la prueba de archivo no solo saldrá directamente de la memoria, sino que también lo hará todo el archivo.

He aquí algunos datos reales para respaldar mi teoría:

Estaba haciendo algunas pruebas de rendimiento de las utilidades de línea de comandos de Linux "encontrar" y "xargs". En las ganancias, realicé una prueba de archivo existente en 13000 archivos, 100 veces cada uno, en menos de 30 segundos, lo que equivale a un promedio de 43,000 pruebas estadísticas por segundo, así que seguro, en la escala fina es lento si lo comparas para decir, el tiempo se necesita dividir 9 por 8, pero en un escenario del mundo real, necesitarías hacer esto horrible muchas veces para ver un problema de rendimiento notable.

Si tiene 43 usuarios al mismo tiempo el acceso a su página, durante el período de un segundo, creo que va a tener problemas mucho más grandes que el tiempo que se necesita para copiar el estado de la existencia de un archivo más -o menos memoria en el escenario de caso promedio.

1

Al menos con PHP4, he encontrado que una llamada a un archivo_exists definitivamente estaba matando nuestra aplicación, se hizo muy repetitivamente en una biblioteca, así que realmente tuvimos que usar un generador de perfiles para encontrarla. La eliminación de la llamada aumentó el cálculo de algunas páginas una docena de veces (la llamada se hizo verrry repetidamente).

Es posible que en PHP5 queden en caché file_exists, pero al menos con PHP4 no fue el caso.

Ahora, si no está en un bucle, obviamente, file_exists no será un gran problema.

Cuestiones relacionadas