reemplazar - subir, mostrar, modificar y eliminar una imagen en mysql desde php
La mejor manera de almacenar en caché las imágenes redimensionadas usando PHP y MySQL (9)
¿Cuál sería la mejor manera de manejar el almacenamiento en caché de imágenes usando PHP?
El nombre del archivo se almacena actualmente en una base de datos MySQL que se renombra a un GUID en la carga, junto con el nombre de archivo original y la etiqueta alt.
Cuando la imagen se coloca en las páginas HTML, se hace usando una URL como ''/images/get/200x200/{guid}.jpg que se reescribe a un script php. Esto permite a mis diseñadores especificar (aproximadamente - la imagen de origen puede ser más pequeña) el tamaño del archivo.
El script php crea un hash del tamaño (200x200 en la url) y el nombre del archivo GUID y si el archivo se ha generado antes (el archivo con el nombre del hash existe en el directorio TMP) envía el archivo desde el directorio TMP de la aplicación. Si el nombre de archivo hash no existe, entonces se crea, se escribe en el disco y se sirve de la misma manera,
¿Es esto eficiente como podría ser? (También es compatible con las marcas de agua de las imágenes y las configuraciones de marca de agua también se almacenan en el hash, pero eso está fuera del alcance de esto).
Eso suena como una forma sólida de hacerlo. El siguiente paso puede ser ir más allá de PHP / MySQL.
Quizás, modifique sus encabezados :
Si usa PHP para enviar tipos MIME, también puede usar los encabezados ''Keep-alive'' y ''Cache-control'' para extender la vida de sus imágenes en el servidor y quitar parte de la carga de PHP / MySQL.
Además, considere los plugins de apache para el almacenamiento en caché también. Al igual que mod_expires .
Oh, una cosa más, ¿cuánto control tienes sobre tu servidor? ¿Deberíamos limitar esta conversación a PHP / MySQL?
Su enfoque parece bastante razonable: agregaría que debería establecerse algún mecanismo para verificar que la fecha en que se generó la versión en caché fue después de la última marca de tiempo modificada del archivo de imagen original (fuente) y si no se regenera la versión en caché / redimensionada . Esto asegurará que si los diseñadores modifican una imagen, la memoria caché se actualizará adecuadamente.
Una nota que vale la pena agregar es asegurarse de que su código no genere tamaños "no autorizados" de estas imágenes.
Por lo tanto, la siguiente URL creará una versión 200x200 de la imagen 1234 si aún no existe. Le sugiero que se asegure de que la URL solicitada contenga las dimensiones de la imagen que admite.
/images/get/200x200/1234.jpg
Una persona malintencionada podría comenzar a solicitar URL aleatorias, siempre alterando el alto y el ancho de la imagen. Esto causaría a su servidor algunos problemas serios b / c estará allí, esencialmente bajo ataque, generando imágenes de tamaños que no admite.
/images/get/0x1/1234.jpg
/images/get/0x2/1234.jpg
...
/images/get/0x9999999/1234.jpg
/images/get/1x1/1234.jpg
...
etc
Aquí hay un fragmento de código al azar que ilustra esto:
<?php
$pathOnDisk = getImageDiskPath($_SERVER[''REQUEST_URI'']);
if(file_exists($pathOnDisk)) {
// send header with image mime type
echo file_get_contents($pathOnDisk);
exit;
} else {
$matches = array();
$ok = preg_match(
''///images//get//(/d+)x(/d+)//(/w+)/.jpg/'',
$_SERVER[''REQUEST_URI''], $matches);
if(! $ok) {
// invalid url
handleInvalidRequest();
} else {
list(, $width, $height, $guid) = $matches;
// you should do this!
if(isSupportedSize($width, $height)) {
// size is supported. all good
// generate the resized image, save it & output it
} else {
// invalid size requested!!!
handleInvalidRequest();
}
}
}
// snip
function handleInvalidRequest() {
// do something w/ invalid request
// show a default graphic, log it etc
}
?>
Parece una gran publicación, pero mi problema sigue sin resolverse. No tengo acceso a htaccess en mi proveedor de host, por lo que no hay dudas sobre el ajuste de apache. ¿Hay realmente una manera de establecer el encabezado de control de cace para las imágenes?
He logrado hacer esto simplemente usando un encabezado de redirección en PHP:
if (!file_exists($filename)) {
// *** Insert code that generates image ***
// Content type
header(''Content-type: image/jpeg'');
// Output
readfile($filename);
} else {
// Redirect
$host = $_SERVER[''HTTP_HOST''];
$uri = rtrim(dirname($_SERVER[''PHP_SELF'']), ''///');
$extra = $filename;
header("Location: http://$host$uri/$extra");
}
Hay dos errores tipográficos en el ejemplo de reescritura de Dan Udey (y no puedo comentar al respecto), debería ser:
RewriteCond %{REQUEST_URI} ^/images/cached/
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule (.*) /images/generate.php?$1 [L]
Saludos.
Lo haría de una manera diferente.
Problemas: 1. Hacer que PHP saque los archivos es menos eficiente de lo que podría ser. 2. PHP tiene que verificar la existencia de archivos cada vez que se solicita una imagen. 3. Apache es mucho mejor en esto de lo que PHP alguna vez lo será.
Hay algunas soluciones aquí.
Puedes usar mod_rewrite
en Apache. Es posible usar mod_rewrite para probar para ver si existe un archivo, y si es así, servir ese archivo en su lugar. Esto evita el PHP por completo y hace que las cosas sean mucho más rápidas. La forma real de hacer esto, sin embargo, sería generar un esquema de URL específico que siempre debería existir, y luego redireccionar a PHP si no es así.
Por ejemplo:
RewriteCond %{REQUEST_URI} ^/images/cached/
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule (.*) /images/generate.php?$1 [L]
Entonces, si un cliente solicita /images/cached/<something>
y ese archivo ya no existe, Apache redirigirá la solicitud a /images/generate.php?/images/cached/<something>
. Este script puede generar la imagen, escribirla en el caché y luego enviarla al cliente. En el futuro, el script PHP nunca se llama, excepto para las nuevas imágenes.
Use el almacenamiento en caché. Como dijo otro cartel, use cosas como mod_expires
, Last-Modified headers, etc. para responder a las solicitudes GET condicionales. Si el cliente no tiene que volver a solicitar imágenes, la carga de la página se acelerará drásticamente y la carga en el servidor disminuirá.
Para los casos en los que tenga que enviar una imagen desde PHP, puede usar mod_xsendfile
para hacerlo con menos sobrecarga. Vea la excelente publicación del blog de Arnold Daniels sobre el tema, pero tenga en cuenta que su ejemplo es para descargas. Para mostrar imágenes en línea, saque el encabezado Content-Disposition (la tercera llamada a header ()).
Espero que esto ayude, más después de que desaparezca mi migraña.
En lugar de mantener la dirección de archivo en el archivo db, prefiero agregar un número al azar al nombre del archivo siempre que el usuario inicie sesión. Algo así para el usuario 1234: image / picture_1234.png? Rnd = 6534122341
Si el usuario envía una nueva imagen durante la sesión, solo actualizo el número aleatorio.
GUID aborda el problema de caché al 100%. Sin embargo, hace que sea más difícil hacer un seguimiento de los archivos de imagen. Con este método, existe la posibilidad de que el usuario vuelva a ver la misma imagen en un inicio de sesión futuro. Sin embargo, las probabilidades son bajas si genera su número aleatorio de mil millones de números.
phpThumb es un marco que genera imágenes / miniaturas redimensionadas sobre la marcha. También implementa el almacenamiento en caché y es muy fácil de implementar.
El código para cambiar el tamaño de una imagen es:
<img src="/phpThumb.php?src=/path/to/image.jpg&w=200&h=200" alt="thumbnail"/>
le dará una miniatura de 200 x 200;
También es compatible con marcas de agua.
Compruébelo en: http://phpthumb.sourceforge.net/