-3

I can't show an image that is on a mysql server, in a blob field. Saving images to mysql works, I can retrieve data, but when I want to display it I can't. Try to implement the example given on this website: [baulphp] 1

Basically what it does is call a PHP file that retrieves the image and returns it by rewriting the header with the header function and then an echo of the content. But the issue is that I am trying this in an MVC and POO project, and the url is friendly and the urls are rewritten through .htaccess. So, I can't directly call a PHP file like the example from that web ...

I tried doing that from the example in a controller action, and calling it inside the IMG tag but it didn't work either.

this is my code, this is the view form:

<form method="POST" action="<?= BASE_URL ?>productos/<?= $metodo ?>" enctype="multipart/form-data">
    <h2><?= $texbut ?> Producto</h2>
    <p><label for="p_nombre">Nombre del Producto:<span class="asterisco">&nbsp;*</span></label></p>
    <p><input type="text" name="p_nombre" <?= $_SESSION['abm_prod'] == 3 ? 'disabled="disabled"' : '' ?> 
              value="<?= $_SESSION['abm_prod'] > 1 ? $prod2edit->p_nombre : ''; ?>" id="p_nombre" maxlength="100" 
              required="required" autofocus="autofocus" placeholder="Ingrese nombre del producto..."> </p>
    
    <p><label for="p_descrip">Descripcion del Producto:</label></p>
    <p><textarea name="p_descrip" <?= $_SESSION['abm_prod'] == 3 ? 'disabled="disabled"' : '' ?> 
              id="p_descripcion" autofocus="autofocus" 
              placeholder="Ingrese descripción del producto..."><?= $_SESSION['abm_prod'] > 1 ? $prod2edit->p_descripcion : ''; ?></textarea></p>
    
    <p><label for="p_red">Nombre reducido:</label></p>
    <p><input type="text" name="p_red" <?= $_SESSION['abm_prod'] == 3 ? 'disabled="disabled"' : '' ?> 
              value="<?= $_SESSION['abm_prod'] > 1 ? $prod2edit->p_red : ''; ?>"
              id="p_red" maxlength="20" autofocus="autofocus" placeholder="Ingrese nombre reducido/corto..."> </p>
    
    <p><label for="p_imagen">Cargar foto del producto</label></p>
    <div class="abmformcontent2 clearfix">
        <div class="abmformleft">
            <input class="botonfoto" type="file" name="p_imagen" />
            <?php if(isset($_SESSION['errorimg'])): ?>
                    <p class="errores"><?= $_SESSION['errorimg'] ?></p>
            <?php endif; ?>

            <p><label for="p_precio">Precio:<span class="asterisco">&nbsp;*</span></label></p>
            <p><input class="inputval" type="text" name="p_precio" <?= $_SESSION['abm_prod'] == 3 ? 'disabled="disabled"' : '' ?> 
                      value="<?= $_SESSION['abm_prod'] > 1 ? $prod2edit->p_precio : ''; ?>"
                      id="p_precio" required="required" autofocus="autofocus" placeholder="Ingrese precio del producto ..."> </p>

            <p><label for="p_stock">Stock:</label></p>
            <p><input class="inputval" type="number" name="p_stock" <?= $_SESSION['abm_prod'] == 3 ? 'disabled="disabled"' : '' ?> 
                      value="<?= $_SESSION['abm_prod'] > 1 ? $prod2edit->p_stock : ''; ?>"
                      id="p_stock" autofocus="autofocus" placeholder="Stock actual..."> </p>

            <?php $categorias = Utilidades::Cat_for_menu(); ?>
            <p><label for="p_catid">Seleccione Categoría:</label></p>
            <select class="selectorcat" name="p_catid" <?= $_SESSION['abm_prod'] == 3 ? 'disabled="disabled"' : '' ?>>
                <?php while ($cat = $categorias->fetch_object()): ?>
                <option value="<?= $cat->c_id ?>" <?= $_SESSION['abm_prod'] > 1 && $cat->c_id==$prod2edit->p_categoria_id ? 'selected' : ''; ?> >
                    <?= $cat->c_nombre ?>
                </option>
                <?php endwhile; ?>
            </select>
        </div>
        <div class="abmformright">
            <img src='<?= BASE_URL ?>productos/viewimg&p_id=<?= $prod2edit->p_id ?>' alt='Imagen producto'   />
        </div>
    </div>

    <p><input type="number" hidden="hidden" name="p_id" value="<?= isset($prod2edit->p_id) ? $prod2edit->p_id : ''; ?>" ></p>
    
    <div class="boton3">
        <input type="submit" class="boton" value="Confirmar">
        <a href="<?=BASE_URL?>productos/gestion"><input type="button" class="boton" value="Cancelar"></a>
    </div>
</form>

And here is part of the controller and the action:

require_once 'models/mproductos.php';
require_once 'models/mimages.php';

Class ProductosController{
    
    public function viewimg() {
        
        $id = filter_input(INPUT_GET, 'p_id', FILTER_SANITIZE_NUMBER_INT);

        if($id>0){
            //Credenciales de conexion
            $Host = 'localhost';
            $Username = 'prueba';
            $Password = '123456';
            $dbName = 'macrotienda';

            //Crear conexion mysql
            $db = new mysqli($Host, $Username, $Password, $dbName);

            //revisar conexion
            if($db->connect_error){
               die("Connection failed: " . $db->connect_error);
            }

            //Extraer imagen de la BD mediante GET
            $result = $db->query("SELECT * FROM images WHERE i_producto = $id");

            if($result->num_rows > 0){
                $imgDatos = $result->fetch_assoc();
                
                //Mostrar Imagen
                header("Content-type: ".$imgDatos['i_mimetype']); 
                echo $imgDatos['i_content']; 
            }else{
                echo 'Imagen no existe...';
            }
        }
        
    }
    
    // *************************************************************************
    
    public function gestion() {

        $productos = new mProductos();
        $allproductos = $productos->Traer_Todos();
        require_once 'views/products/gestion.php';
        
    }

Clarification: As seen there in the action "viewimg" is all of the connection, that is only in test mode, because in reality that class inherits the connection parameters, test both ways and both receive the object of the database...

Here it is when you record the image:

public function create() {
    $insert = "insert into macrotienda.images values(null,".
              " '$this->filename', ".
              " '$this->mimetype', ".
              "  $this->height,    ".
              "  $this->width,     ".
              " '$this->hwtext',   ".
              "  $this->size,      ".
              " '$this->content',  ".
              "  now(),            ".
              "  $this->producto_id ) ";

    $result = $this->conn->query($insert);
    return $result;

here when you assign those data:

$imagen  = $_FILES['p_imagen'];

$ftype = $imagen['type'];
$fsize = $imagen['size'];

$ftmp   = $imagen['tmp_name'];

$ftamaño = getimagesize($ftmp);

$image = new mimages();
$image->setFilename($imagen['name']);
$image->setHeight($ftamaño[0]);
$image->setWidth($ftamaño[1]);
$image->setHwtext($ftamaño[3]);
$image->setMimetype($ftype);
$image->setSize($fsize);
$image->setContent(addslashes(file_get_contents($ftmp)));

I'm still a novice in PHP programming ... how could I show the image?

THANK YOU

tereško
  • 58,060
  • 25
  • 98
  • 150
Pedro
  • 1
  • 1
  • what is _$imgDatos['i_content'];_? – Sfili_81 Jul 13 '20 at 12:58
  • $imgDatos['i_content'] contains the contents of the database blob field. – Pedro Jul 13 '20 at 13:14
  • you save the entire image in the db? in my opinion it's better to upload the image into a folder and then save the reference to the db – Sfili_81 Jul 13 '20 at 13:24
  • yes, I am saving the complete images in the database ... they are limited to 500 Kbytes ... in that case, I need to save them in the db ... I recognize that it is not ideal ... This is part of a learning course, but at the same time I am also adding functionalities that were not requested, because I came up with a project to apply it on a real page. So, I would like to solve this too to know how to do it if I really need it. Thanks! – Pedro Jul 13 '20 at 13:35
  • look at [this](https://stackoverflow.com/questions/7793009/how-to-retrieve-images-from-mysql-database-and-display-in-an-html-tag) – Sfili_81 Jul 13 '20 at 14:01
  • Thanks!!! I found a way that works for me. I base on this example: echo ''; I had to remove the stripslashes function -which I don't know what it does- and it showed the image well. With that function, it showed me everything wrong. If you can clarify the use of that function and base64_encode, very grateful ... Thx! – Pedro Jul 14 '20 at 01:05
  • on [php manual](https://www.php.net/manual/en/function.stripslashes.php) you can find all the explanation ;) Please post a complete answer so if someone has the same problem he can find a solution – Sfili_81 Jul 14 '20 at 06:30

1 Answers1

0

Here is the solution:

In the view form it should go like this:

 <div class="abmformright">
     <?php if(isset($_SESSION['img_prod'])): ?>
          <?php echo '<img src="data:image/jpeg;base64,'.base64_encode($_SESSION['img_prod']->i_content ).'"  />'; ?>
     <?php endif; ?>
</div>

Thanks!!!

Pedro
  • 1
  • 1