2009-07-19 2 views
5

En el pasado, he manejado la subida de imágenes de usuario de dos maneras diferentes:arquitectura recomendada para el manejo de archivos de imagen de usuario

  • guardar los datos de imagen en una tabla de base de datos, y lo carga a través de un script PHP
  • Sube la imagen, convertirlo a JPEG, lo puso en un directorio y cargarlo a través de las etiquetas HTML

la primera opción funcionó bastante bien, pero que tenía que mantener las restricciones de tamaño bastante restrictivos en las imágenes cargadas. La segunda opción que funcionaba, a excepción de la biblioteca de imágenes de PHP, a menudo arruinaba la conversión del archivo (creo que se puede solucionar utilizando ImageMagick en su lugar).

Ahora tengo que hacer esto por tercera vez, en una escala potencialmente mayor de usuarios. Ya planeo usar ImageMagick para hacer un procesamiento posterior a la imagen después de la carga. Me encantaría mantener las restricciones sobre la carga de imágenes lo más pequeña posible e incluso retener cada foto que alguien carga.

Habrá momentos en que cientos de cargas de fotos del usuario se mostrarán en la pantalla como una miniatura a la vez. Almacenarlos en una base de datos y extraerlos para cada uno y mostrarlos a través de PHP no parece una buena forma de hacerlo, pero tampoco todas las imágenes en un solo directorio.

¿Cuál es su recomendación en esta situación? ¿Vas con una de las opciones anteriores o tienes una solución diferente?

Respuesta

5

Almacenar estos en una base de datos y extraerlos para cada uno y mostrar a través de PHP no parece una buena manera de hacerlo, pero tampoco todas las imágenes en un solo directorio.

Puede adoptar un enfoque híbrido.

Almacene las imágenes en una jerarquía de carpetas (según el esquema que determine que sea apropiado para su aplicación). Almacene la ruta completa a cada imagen en su base de datos.

En un trabajo de fondo, tenga miniaturas de las imágenes producidas (digamos con ImageMagick) cuyos nombres de archivo difieren ligeramente de las imágenes mismas (por ejemplo: agregue 'thumb-' en el frente) pero que se almacenan junto a las imágenes reales. Puede tener un campo en la base de datos para cada imagen, lo que significa que "Mi miniatura está lista, así que inclúyame en las galerías".

Cuando obtiene una solicitud para una galería, corte y suelte el grupo de imágenes usando los campos de la base de datos, y luego genere un fragmento de HTML que haga referencia a las rutas de imagen y miniatura correspondientes.


Editar: Qué dice Aaron F es importante cuando se necesita para manejar un gran número de solicitudes. La partición de los datos de imagen/sql es un buen camino para la escalabilidad. Tendrá que ver los patrones de acceso en su aplicación para determinar dónde se encuentran los puntos de partición. Algo que puede hacer incluso antes es almacenar en caché el HTML generado para las galerías a fin de reducir la carga de SQL.

2

Los dos ejemplos que cita no aclaran la parte más importante: la partición.

p. Ej. si se almacenan en una base de datos, ¿residen las imágenes completamente en una tabla, en un servidor de base de datos? ¿O está la tabla particionada en varios servidores/clusters?

p. Ej. si está almacenado en un directorio, ¿todas las imágenes residen en un disco duro? ¿O las imágenes se asignan a unidades [RAID] separadas, según la primera letra del nombre de inicio de sesión del usuario?

Se necesita un buen esquema de partición para la escalabilidad.

En cuanto a la visualización de miniaturas a granel, es probable que desee una precomputación aquí. es decir, crear las miniaturas (quizás mediante un trabajo poco sofisticado, que se inició justo después de cargar la imagen) y colocarlas en un servidor dedicado. Así es como Youtube hace instantáneas de imágenes de videos subidos.

1

En mi humilde opinión, la solución de David es el mejor para la mayoría de los casos, pero modificaría dos detalles:

almacenar la ruta completa a cada imagen en su base de datos.

No creo que necesita para almacenar la ruta completa , ya que si por alguna razón el directorio de las imágenes cambia, que complicaría su vida un poco. Almacenar solo el nombre de archivo debería ser suficiente. Siempre puede incluir la ruta completa directamente en el html.

tienen miniaturas de las imágenes producidas (digamos con ImageMagick) cuyos nombres de archivo difieren ligeramente de las imágenes pero que se almacenan junto a las imágenes reales.

Prefiero poner las miniaturas en un directorio diferente, un directorio para cada pulgar que cree y con exactamente el mismo nombre de archivo. Una vez trabajé en un sitio con miles de imágenes de usuario y cometí el error de ponerlas todas en el mismo directorio. El directorio creció tanto que es casi imposible abrir este directorio sin tener que esperar varios minutos.

biblioteca de imágenes de PHP a menudo fracasar en la conversión de archivos

Sugiero para aumentar el límite de memoria en el guión donde se crea el pulgar, especialmente si se permite la carga de archivos de gran tamaño (2 MB +).

Puede hacerlo con ini_set('memory_limit', '30M');. Por supuesto, el número real depende de usted. 30M me ha funcionado en sitios de miniaturas pesadas.

0

uhm para crear miniaturas, use phpthumb ... es absolutamente perfecto para ese asunto ... y tiene algunos extras, pero probablemente no los necesite ... crea automáticamente un caché local en su sistema de archivos , por lo que es muy ahorro de recursos ...

Creo que el enfoque híbrido es probablemente el más escalable, es decir, almacenar archivos en el sistema de archivos y ubicaciones de archivos en una base de datos ... de esa manera, puede almacenar algunos metadatos con el archivo (como creador, título, etiquetas, etc.), y mantenga su base de datos pequeña ... además, puede almacenar sus imágenes en ubicaciones arbitrarias (incluso en otras máquinas, etc.), para que pueda distribuir fácilmente toda esa carga útil ...

greetz

back2dos

1

Hace algunos años escribí un archivo de imágenes intranet destinado a almacenar en última instancia, algunos 340 mil exploraciones más miniaturas relativas.Buscando en Google descubrí que no hay ninguna razón para no volcarlos a todos en un solo directorio, siempre y cuando no le pidas al sistema operativo subyacente que haga una lista de carpetas. En otras palabras, pedir un ls/dir colgaría la máquina, pero el solo hecho de recuperar los archivos de una sola imagen por su nombre de archivo (de la base de datos) no implicaría ninguna penalización en el rendimiento.

Ese archivo se ha estado ejecutando durante un par de años y puedo confirmar que funciona bien con algo más de 60k imágenes realmente almacenadas en una carpeta.

Nunca he tenido ningún tipo de problema para convertir cosas a jpeg con GD, pero para ese trabajo en particular fui de la forma de ImageMagick con MagicWand como extensión de ayuda (principalmente debido a la documentación decente).

Cuestiones relacionadas