[PHP] Upload e successiva visualizzazione immagini in DB

MarcoGrazia

Utente Attivo
15 Dic 2009
852
20
28
63
Udine
www.stilisticamente.com
Bene, l'argomento è stra ritrito, oramai direi pure omogeneizzato, però certe cose rimangono in mente ed è sempre più difficile correggersi.
Il problema più grosso, al solito, è riconoscere l'errore la dove non sembrano essercene.
Fatta questa doverosa premessa vengo al dunque: dovendo rifare un sito, il quale tra l'altro presenta un migliaglio circa di immagini raccolte in una cartella del filesystem, tutte JPG tra l'altro; ho avuta la bella pensata di metterle tutte in un record.
Così, preso il record corrente, con tutte le belle didascalie, titoli e riferimenti alle immagini presenti nel filesystem, ci ho inserito un bel campo chiamato foto come MEDIUMBLOB ( le immagini solo dell'ordine dei 50Kb max. ) ed ho creata una routine che le carica dentro ogni record del database. Bene!
Poi mi creo il classico failetto :D che dato un certo ID carica l'immagine corrispondente... e no, manco pe gnente!
The image cannot displayed because it contains errors!
Allora controllo e modifico il programma di visualizzazione:
PHP:
ob_start();
session_start();
session_regenerate_id();
try
{
    function giveAPicture($id)
    {
        try
        {
            $conn = PDOConnetti();
            $handle = $conn->prepare('SELECT foto, attivo FROM immagini WHERE id=:id LIMIT 1;');
            $handle->bindValue(':id', (int)$id, PDO::PARAM_INT);
            $handle->execute();
            $giochi = $handle->fetch();
            unset( $conn, $handle );
        }
        catch (PDOException $e)
        {
            echo $e->getTraceAsString() . '<br><br>';
            echo $e->getCode() . '<br>' .
                    $e->getFile() . '<br>' .
                    $e->getLine() . '<br><br>' .
                    $e->getMessage();
        }
        return $giochi;
    }

    if (filter_has_var(INPUT_POST, 'id') && filter_has_var(INPUT_GET, 'id') > 0 )
    {
        $file = giveAPicture(filter_var($_GET['id'], FILTER_VALIDATE_INT));
        if ($file['attivo'] == 1)
        {
            if ($file['foto'] != null)
            {
                header('Content-Type: image/jpeg');
                //  echo $file['foto'];
                //  echo 'data:image/jpeg;base64,' . base64_decode($file['foto']);
                echo 'data:image/jpeg;base64,' . base64_encode($file['foto']);
            }
        }
    }
    else
    {
       
    }
}
catch (Exception $ex) {
    echo 'ERRORE GENERICO<br><br>';
    echo $ex->getTraceAsString() . '<br><br>' .
            $ex->getCode() . '<br>' .
            $ex->getFile() . '<br>' .
            $ex->getLine() . '<br>' .
            $ex->getMessage();
}
Che come si vede, porta i segni delle mie prove ( poche ) ma che non danno gli esiti sperati.
Allora mi viene il dubbio di aver sbagliato a caricare le immagini nel database!
Solo che non so come e dove, dato che nel database le immagini ci sono, ne ho pure scaricata una ( da phpMyAdmin ), una di quelle che mi davano errore, e l'ho visualizzata correttamente nella cartella di destinazione!
Comunque il semplice programma di caricamento è questo:
PHP:
try
{
    include_once __DIR__ . '/bin/genericFunction.inc.php';
   
    $conn = PDOConnetti();
    $sql = 'UPDATE immagini SET foto = :foto WHERE url_immagine = :url;';
    $handle = $conn->prepare($sql);
    echo '<h1>Immagini</h1><h2>Salvataggio foto nel DB</h2><hr>';
    foreach(glob('foto/*.jpg') as $name)
    {
        if (!is_dir($name))
        {
            if (is_readable($name))
            {
                $fp = fopen($name, 'rb');
                $content = fread( $fp, filesize($name));
                fclose($fp);
                if ( strlen($content) > 0 )
                {
                    $url = basename($name);
                    echo '<p>Sto salvando: <strong>' . $url . '</strong></p>';
                    $handle->bindValue( ':foto', $content, PDO::PARAM_LOB );
                    $handle->bindValue( ':url', $url, PDO::PARAM_STR );
                    $handle->execute();
                }
            }
        }
    }
    unset($conn, $handle );
   
}
catch (PDOException $e)
{
    echo 'ERRORE DATABASE:<br><br>';
    echo $e->getTraceAsString() . '<br><br>';
    echo $e->getCode() . '<br>' .
            $e->getFile() . '<br>' .
            $e->getLine() . '<br><br>' .
            $e->getMessage();
}
catch (Exception $e)
{
    echo 'ERRORE CODICE:<br><br>';
    echo $e->getTraceAsString() . '<br><br>';
    echo $e->getCode() . '<br>' .
            $e->getFile() . '<br>' .
            $e->getLine() . '<br><br>' .
            $e->getMessage();
}
Forse ho commesso l'errore di non codificare le immagini prima di caricarle nel database? E se sì come?
base64 o cosa? e perché?
 
Ho provato a migliorare addPhoto.php la dove caricava le immagini dal file system, usando una metodologia usata per caricare le immagini da $_FILE, ovvero utilizzare file_get_contents() ma non credo sia importante, l'ho fatto giusto per provare un'altra strada; ma soprattutto utilizzare addslashes() sul file letto.
PHP:
.....
$content = addslashes(file_get_content($name));
.....
Il risultato è sempre lo stesso, il file viene correttamente caricato sul database, ma poi in lettura da sempre lo stesso errore, cioè file con errori.
 
Hem.... e lo so devo comprare una tonnellata di Settimana enigmistica e compilare bene tutti i Aguzza la vista....
PHP:
if (filter_has_var(INPUT_POST, 'id') && filter_has_var(INPUT_GET, 'id') > 0 )
Chi ha visto l'errore? LA stringa è passata per URL.... :D :D :D
 
Ok, di cavolate ne avevo fatte pure troppe, ora le ho corrette e funziona.
Metto per chi interessa, la parte centrale del file loadImage.php
PHP:
//  Corretto, ora è giusto.
if (filter_has_var(INPUT_GET, 'id') && filter_has_var(INPUT_GET, 'id') > 0 )
    {
        //  Contiene tra l'altro la routine di connessione al database ( mancava )
        include_once __DIR__ . '/bin/genericFunction.inc.php';
        //  Contiene tra l'altro la routine che scarica l'immagine dal database. ( mancava )
        include_once __DIR__ . '/bin/loadGames.inc.php';
        $file = giveAPicture(filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT));
        if ($file['attivo'] == 1 )
        {
            if ($file['foto'] != null)
            {
                header('Content-Type: image/jpeg');
                header(" Content-Disposition: inline");
                echo $file['foto'];
            }
        }
    }
Uso: <img src="loadImage.php?id=4"> mancano ovviamente le routine per accedere al database e quella per prendere l'immagine dal record del database.
Vado a cena :(
 

Discussioni simili