entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Hola, tengo una aplicación web en la cual muestro unas imágenes dependiendo del nombre de archivo que le envíe, para que esta imágenes no puedan ser vistas por cualquiera, las protejo mediante una archivo .htaccess alojado en la misma carpeta.
En el archivo .htaccess solo tengo puesto esto: Deny from all,
y para mostrar las imágenes uso esta linea de html:

<img src="includes/showimg.php?wimg=00000003.jpg" />

Y este es código del archivo showimg.php:

<? $image_folder = '../doc/docs/';  if (isset($_GET['wimg']) && basename($_GET['wimg']) == $_GET['wimg']) {
$pic = $image_folder.$_GET['wimg'];
if (file_exists($pic) && is_readable($pic)) {
    $ext = substr($pic, -3);
    switch ($ext) {
        case 'jpg':
            $mime = 'image/jpeg';
            break;
        case 'gif':
            $mime = 'image/gif';
            break;
        case 'png':
            $mime = 'image/png';
            break;
        default:
            $mime = false;
    }
    // if a valid MIME type exists, display the image
    // by sending appropriate headers and streaming the file
    if ($mime) {
        header('Content-type: '.$mime);
        header('Content-length: '.filesize($pic));
        $file = @ fopen($pic, 'rb');
        if ($file) {
            header('Location: '.$image_folder.$_GET['wimg']);
            exit;
        }
    }
}}?>

El problema es que cuando pongo el archivo .htaccess no se ven las imágenes, pero si lo borro si. Pero se supone que al llamar a la imagen a través de php si debería mostrármela, ¿no es así?

Muchas gracias.

2 Respuestas

2votos

Leonardo-Tadei Puntos227320

Hola @fersan,

cuando decís " se supone que al llamar a la imagen a través de php si debería mostrármela", es cierto, pero solo si PHP es el que se encarga de la visualización.

Lo que tu código hace es recibir la ruta a la imagen, enviar una cabecera con el tipo mime y el tamaño, y luego con otra cabecera invocar a una redirección con "Location", pero esta redirección hará que el navegador se redirija haciendo una petición nueva a la imagen real (descartando las cabeceras previas) con lo cual tu script es solo una forma sofisticada de escribir el URL de la imagen a la que no querés dar acceso en el navegador.

Para que sea PHP el que lee y envía la imagen luego abrir el archivo en el IF final deberías hacer:

$file = @ fopen($pic, 'rb');
        if ($file) {
            fpassthru($file);
            fclose($file)
        }

Lo que hace fpassthru() es leer todo el archivo y enviarlo a la salida estándar. Ahora tu script generaría las cabeceras correctas de la imagen, y luego mandaría el contenido del archivo imagen leído del disco para que lo visualice el navegador.

0voto

fersan comentado

Gracias Leonardo, pero sigue sin funcionarme, pero tengo una duda:
¿Estas dos lineas las debo dejar (justo antes del $file)?:

        header('Content-type: '.$mime);
        header('Content-length: '.filesize($pic));

0voto

Leonardo-Tadei comentado

Hola @fersan,

sí, esas líneas van. De hecho, si no las tuvieras, el navegador no sabría que debe interpretar un archivo de extensión PHP como una imagen.

Te dejo un ejemplo tomado del manual de PHP para que uses de modelo:

<?php
// open the file in a binary mode
$name = './img/ok.png';
$fp = fopen($name, 'rb');

// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));

// dump the picture and stop the script
fpassthru($fp);
exit;
?>

http://php.net/manual/en/function.fpassthru.php

En el ejemplo no se llama a fclose() porque al terminar el script, los recursos se liberan solos, pero es una buena práctica acostumprarse a liberar los recursos asignados.

Verificá además no tener algún problema con las rutas. También podrías tener alguna condición de salida con un mensaje de error en el caso de que el archivo no exista, para descubrir mejor qué está pasando.

1voto

fersan comentado

Muchas gracias, funciona perfectamente.

2votos

alv-c Puntos1200

Estás haciendo una redirección a la imagen

header('Location: '.$image_folder.$_GET['wimg']);

Probá cambiando todo esto:

$file = @ fopen($pic, 'rb');
    if ($file) {
        header('Location: '.$image_folder.$_GET['wimg']);
        exit;
    }

Por esto

 readfile($pic);

0voto

fersan comentado

Muchas gracias por tu respuesta alv-c, pero ya lo probé y tampoco me funciona así.

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta