Multiple registration of image

Asked

Viewed 328 times

2

Here I come to ask for your help again! I created a function to register images in the database being one of them the cover and the rest of album images.

The script up to register the cover image and the album, but the album is only registered in the database 1 (an) image, the most curious thing is that the files are moved to the folder uploads/ but are not registered in the bank.

THE HTML:

<?php //Chama a função inserir caso tenha algum dado em POST (includes/conexao)
   if (isset($_POST['salvar'])) {
   criar_album('albumImagens', 'capa', $_POST);
}  
?>

<form class="form-horizontal" method="POST" action="" enctype="multipart/form-data" runat="server" />
<fieldset>

 <legend>Nova imagem</legend>
  <div class="form-group">
   <label class="col-md-3 control-label" for="nome">Nome</label>  
   <div class="col-md-6">
  <input name="nome" type="text" placeholder class="form-control input-md" required />
   </div>
  </div>

  <!-- Text input --> 
  <div class="form-group">   
    <div id="thumbnail">
   </div>
   <label class="col-md-3 control-label" for="capa">Capa:</label>  
   <div class="col-md-4">
  <input type="file" name="capa" id="capa" class="form-control" required>
</div>
   </div>

   <!-- Text input-->
   <div class="form-group">
   <label class="col-md-3 control-label" for="imagem">Album:</label>  
   <div class="col-md-4">
  <input type="file" name="imagem[]" id="imagem" class="form-control" required multiple />
   </div>
   </div>

   <!-- Button -->
   <div class="form-group">
   <label class="col-md-3 control-label" for="salvar"></label>
   <div class="col-md-5">
  <button type="submit" id="salvar" name="salvar" class="btn btn-primary btn-lg">Salvar</button>
   </div>
   </div>

   </fieldset>
   </form>

A Function:

function criar_album($album, $destaque, $dados){
$con = conectar();
$caminho = 'uploads/';
$nome = $_POST['nome'];
$qtd = count($_FILES["imagem"]["name"]);

if ($qtd > 0){
   $nomeArquivoCapa = $_FILES["capa"]["name"];
   $nomeTemporarioCapa = $_FILES["capa"]["tmp_name"];
   $tamanhoArquivoCapa = $_FILES["capa"]["size"];

for ($i=0; $i <= $qtd; $i++) { 
    $nomeArquivo = $_FILES["imagem"]["name"][$i];
    $nomeTemporario = $_FILES["imagem"]["tmp_name"][$i];
    $tamanhoArquivo = $_FILES["imagem"]["size"][$i];


    if (!empty($nomeArquivoCapa)) {
        $arquivoArrayCapa = explode(".", $nomeArquivoCapa);
        $extensaoCapa = end($arquivoArrayCapa);
        $arquivoCapa = $caminho.md5(time().rand(3212, 15452)).'.'.$extensaoCapa;

        if (move_uploaded_file($nomeTemporarioCapa, $arquivoCapa)) {
            $inserir = $con->prepare("INSERT INTO $destaque(nome, imagem) VALUES('$nome', '$arquivoCapa')");
            $inseri = $inserir->execute(); // Execute a inserção
            $last = $con->lastInsertId();
        }

        if (!empty($nomeArquivo)) {
        $arquivoArray = explode(".", $nomeArquivo);
        $extensao = end($arquivoArray);
        $arquivo = $caminho.md5(time().rand(3212, 15452)).'.'.$extensao;

        if (move_uploaded_file($nomeTemporario, $arquivo)) {
        $inserir = $con->prepare("INSERT INTO $album(idCapa, imagem) VALUES('$last', '$arquivo')");
        $inseri = $inserir->execute(); // Execute a inserção    
        }

    else {
        echo '<div class="alert alert-danger" role="alert">Erro, tente novamente mais tarde!</div>';
        }
    }   
}

    }
echo '<div class="alert alert-success" role="alert">Salvo com sucesso!</div>';
  }
}

SQL structure:

Table capa: ID, Name and Image

Table albumImagens: idCapa, image

What seems to happen is that the is not working, because it only makes a passage and nothing else. The excerpt if (move_uploaded_file($nomeTemporario, $arquivo)) This moving all images at once to my view...

I executed a var_dump($inserir) to see if the querys are being generated and noticed that SIM are being generated but run only happens UMA VEZ inserting only 1 image in the database.

object(PDOStatement)#3 (1) { ["queryString"]=> string(101) "INSERT INTO albumImagens(idCapa, imagem) VALUES('59', 'uploads/16487b1c9236bca1231deafb2e711d15.png')" } object(PDOStatement)#1 (1) { ["queryString"]=> string(101) "INSERT INTO albumImagens(idCapa, imagem) VALUES('59', 'uploads/7cb40a35907252ef2e0c401bc0561b1c.png')" }

Only image 1 with ending 11d15.jpg this being inserted...

2 answers

1

The problem I noticed is the following, as you approach, your intention is to register an album with a cover image and the others being extras. However in your current role you have the upload and record the cover inside the loop for. So you are registering the album in the same amount of times as the image occurrences.

To resolve this, it’s simple to remove the album’s registration code snippet from within the for.

<?php
function criar_album($album, $destaque, $dados){
    $con = conectar();
    $caminho = 'uploads/';
    $nome = $_POST['nome'];
    $qtd = count($_FILES["imagem"]["name"]);

    if ($qtd > 0){
        $nomeArquivoCapa = $_FILES["capa"]["name"];
        $nomeTemporarioCapa = $_FILES["capa"]["tmp_name"];
        $tamanhoArquivoCapa = $_FILES["capa"]["size"];

        if(empty($nomeArquivoCapa)){
            echo '<div class="alert alert-danger" role="alert">Erro, capa nao inserida!</div>';
            return;
        }

        $arquivoArrayCapa = explode(".", $nomeArquivoCapa);
        $extensaoCapa = end($arquivoArrayCapa);
        $arquivoCapa = $caminho.md5(time().rand(3212, 15452)).'.'.$extensaoCapa;

        if (move_uploaded_file($nomeTemporarioCapa, $arquivoCapa)) {
            $inserir = $con->prepare("INSERT INTO $destaque(nome, imagem) VALUES('$nome', '$arquivoCapa')");
            $inseri = $inserir->execute(); // Execute a inserção
            $last = $con->lastInsertId();
        }else{
            echo '<div class="alert alert-danger" role="alert">Erro, tente novamente mais tarde!</div>';
        }

        for ($i=0; $i <= $qtd; $i++) { 
            $nomeArquivo = $_FILES["imagem"]["name"][$i];
            $nomeTemporario = $_FILES["imagem"]["tmp_name"][$i];
            $tamanhoArquivo = $_FILES["imagem"]["size"][$i];

            if (!empty($nomeArquivo)) {
                $arquivoArray = explode(".", $nomeArquivo);
                $extensao = end($arquivoArray);
                $arquivo = $caminho.md5(time().rand(3212, 15452)).'.'.$extensao;

                if (move_uploaded_file($nomeTemporario, $arquivo)) {
                    $inserir = $con->prepare("INSERT INTO $album(idCapa, imagem) VALUES('$last', '$arquivo')");
                    $inseri = $inserir->execute(); // Execute a inserção    
                }else{
                    echo '<div class="alert alert-danger" role="alert">Erro, tente novamente mais tarde!</div>';
                }
            }

        }
        echo '<div class="alert alert-success" role="alert">Salvo com sucesso!</div>';
    }
}
  • Unfortunately still the same problem, only uma imagem é cadastrada at the bank.

  • @Rafaelacioly try to perform a debug to see the SQL being made, and after checking if it is saving with idCapa correspondent.

  • yes William, I put the code to force error display and what returned was Notice: Undefined offset: 2 this error correlates the line just below the for, concerning the insertion of the idCapa the same usually happens.

  • 1

    The reason for the undefined is that, I didn’t notice either, as if using count it returns in the total number of records. and the array starts at 0, so the error is in for which should be $i < $qtd.

  • not yet solved, the problem is at the time of inserting the image in the database because the script is moving all at once and so does not return to the for

  • William, I made a var_dump($inserir) (after the query) and the return I had was 2 querys para inserção ie, querys are created but when executing it only executes a...

  • These two query are in the same string? if yes, check if they are separated by ;, because one must be independent of the other.

  • Guilherme, I put the result of the query in the post, see what appears! it seems that there is no ;

  • 1

    @Rafaelacioly it is performing a two separate moments, in this way no need of the ;, but I can’t think of anything else that might be the problem. A tip, comment each part of the code, explaining, who knows how you find the error.

Show 4 more comments

1


When developing a project, or creating an auxiliary script, it is essential to be calm above all because writing code with more than 100 lines already begins to be a bit tricky at the time of finding }, or ; among so many functions, variables and arguments, in your code, I confess that it was no different, above all I had no notas which is usually good sometimes even for the author of the code himself.

The following are some possible improvements I’ve made to your script, to make it more objective/efficient.

Function

<?php

$pdo = new PDO("mysql: hostname=localhost; dbname=example;", "root", "");

// Nesta função trabalhamos uma vez mais a array, de modo a obtermos a mesma ID
function array_final($array, $id){
    if(is_array($array)){
        foreach($array as $im){
            $f[] =  array("imagem"=>$im, "id"=>$id);
        }   
        $valores = array();
        foreach($f as $p){
            $valores = array_merge($valores, array_values($p));
        }
        return $valores;
    } else {
        return false;   
    }
}

function imagens($array, $nome=null){
    if(!empty($array) && isset($array)){
        // Esta linha imprime o nome dos ficheiros em maiusculo, para o caso de $nome for diferente de vazio    
        if(isset($nome)){
            // Para multiplos ficheiros (album) 
            if(is_array($array["name"])){
                foreach($array["name"] as $id=>$item){
                    $imagem[] = $item;  
                }   
            // Para o caso de o ficheiro selecionado  ser apenas 1 (CAPA)   
            } else {
                $explode = explode(".", $array["name"]);    
                return strtoupper($explode[0]); 
            }
            if(isset($imagem)){
                foreach($imagem as $id=>$img){
                    $explode[] = explode(".", $img);
                }   
                for($i=0; $i<count($explode);$i++){
                    $explodes[] = strtoupper(array_shift($explode[$i]));    
                }
                // Retorna uma array contento o nome e a extensao dos arquivos  
                return $explodes;   
            }   
        // Para o caso de $nome for igual a  0, ou vazio    
        } else {
            // Para multiplos ficheiros (album)     
            if(is_array($array["name"])){
                foreach($array["name"] as $id=>$item){
                    $imagem[] = $item;  
                }
            // Para o caso de o ficheiro selecionado  ser apenas 1 (CAPA)       
            } else {
                return $array["name"];  
            }
            if(isset($imagem)){
                // Retorna uma array contento o nome e a extensao dos arquivos  
                return $imagem; 
            }   
        }
    } else {
        return false;   
    }   
}

function enviar($ficheiro, $caminho){
    // Arquivo existe ? 
    if(count($ficheiro) <= 0){
        return false;   
    } else {
        // Para multiplos ficheiros (album)         
        if(is_array($ficheiro["name"])){
            foreach($ficheiro["name"] as $id=>$imagem){
                $upload = $caminho . basename($imagem);
                $estado = move_uploaded_file($ficheiro["tmp_name"][$id], $upload) ? true : false;   
            }   
        // Para o caso de o ficheiro selecionado  ser apenas 1 (CAPA)       
        } else {
            $upload = $caminho . basename($ficheiro["name"]);
            $estado = move_uploaded_file($ficheiro["tmp_name"], $upload) ? true : false;    
        }
        // se o ficheiro for movido com sucesso, retorna true como ultima declaracao
        if($estado == true){
            return true;    
        }   
    }   
}

function criar_album($album, $capa){
// chamar a váriavel pdo atravez do escopo global       
global $pdo;
// Caminho/diretorio para onde vao os ficheiros
$caminho = 'up/';
$qtd = count($_FILES["imagem"]["name"]);

if ($qtd > 0){
       $nomeArquivoCapa = $_FILES["capa"]["name"];
       $upload = $caminho . basename($nomeArquivoCapa);
       // Se o ficheiro de capa e o(s) ficheiro(s) forem movidos com sucesso
       if(enviar($_FILES["capa"], $caminho, "capa") && enviar($_FILES["imagem"], $caminho, "imagem")){
            // Prepara a primeira consulta SQL 
           $inserir = $pdo->prepare("INSERT INTO {$capa} (nome, imagem) VALUES (:nome, :imagem)");
           // Passando multiplos parametros atravez do metodo execute do PDO
           // inserir->execute(array(":bind1"=>valor1, "bind2"=>valor2, ...));
           $inserir->execute(array(":nome"=>imagens($_FILES["capa"], 1), ":imagem"=>imagens($_FILES["capa"])));
           // Captar a ultima ID inseriida
           $id = $pdo->lastInsertId();
            // Aqui iniciamos uma transação para maior fluidez  
           $pdo->beginTransaction();
           // calcular o numero de placeholders para a query em questao
           foreach(imagens($_FILES["imagem"]) as $p){
               $interr[] = '(?,?)';
           }
            // Aqui concatenamos os valores anteriormente trabalhados, incluindo os placeholders
           $sql = "INSERT INTO {$album} (imagem, idCapa) VALUES ". implode(",", $interr);   
           echo $sql;
           // Preparar a consulta SQL
           $inserir = $pdo->prepare($sql);
           try{
           // Executar a consulta, com multiplos parametros
           // INSERT INTO tabela (campo1, campo2) VALUES (?,?),(?,?)...
                $inserir->execute(array_final(imagens($_FILES["imagem"]), $id));
           // Capturar a exceção        
           } catch (PDOException $e){
           // Imprimir a exceção, se existir        
                $e->getMessage();
           }
           // Confirmar inclusao 
           $pdo->commit();
      } 
    }
}

?>

For this case, what was wanted was to register in the database, a set of values at once. However it was necessary to build a query of that kind:

INSERT INTO table (field 1, field 2) VALUES (?, ?), (?, ?)...

Once we worked with placeholders then set up the pontos de interrogação in the place where the values would be replaced.

Since the result set for the query was something like this:

Array ( [0] => usr1.jpg [1] => 55 [2] => usr2.jpg [3] => 55 ) 

               (imagem)       (id)       (imagem)       (id)

According to the website perform consultation using this process may even be faster than usual.

Most of all, I just hope I haven’t complicated your life with those new functions that I have added, I will shortly edit my reply and add a few more details explaining what was going on with your original code, or how to solve the problem in it.

Script Original

<?php

$pdo = new PDO("mysql: hostname=localhost; dbname=example;", "root", "");

function criar_album($album, $capa){
global $pdo;
$caminho = 'up/';
$nome = $_POST['nome'];
$qtd = count($_FILES["imagem"]["name"]);

if ($qtd > 0){
   $nomeArquivoCapa = $_FILES["capa"]["name"];
   $nomeTemporarioCapa = $_FILES["capa"]["tmp_name"];
   $tamanhoArquivoCapa = $_FILES["capa"]["size"];

for ($i=0; $i < $qtd; $i++) { 
    $nomeArquivo = $_FILES["imagem"]["name"][$i];
    $nomeTemporario = $_FILES["imagem"]["tmp_name"][$i];
    $tamanhoArquivo = $_FILES["imagem"]["size"][$i];


    if (!empty($nomeArquivoCapa)) {
        $arquivoArrayCapa = explode(".", $nomeArquivoCapa);
        $extensaoCapa = end($arquivoArrayCapa);
        $arquivoCapa = $caminho.md5(time().rand(3212, 15452)).'.'.$extensaoCapa;
        // Descomente a linha para guardar a imagem com o nome original no banco de dados
        //$arquivo = $nomeArquivoCapa;

        if (move_uploaded_file($nomeTemporarioCapa, $arquivoCapa)) {
            $inserir = $pdo->prepare("INSERT INTO $capa(nome, imagem) VALUES('$nome', '$arquivoCapa')");
            $inseri = $inserir->execute(); // Execute a inserção
            $last = $pdo->lastInsertId();
        }

        if (!empty($nomeArquivo)) {
        $arquivoArray = explode(".", $nomeArquivo);
        $extensao = end($arquivoArray);
        $arquivo = $caminho.md5(time().rand(3212, 15452)).'.'.$extensao;
        // Descomente a linha para guardar a imagem com o nome original no banco de dados
        //$arquivo = $nomeArquivo;
        if (move_uploaded_file($nomeTemporario, $arquivo)) {
        $inserir = $pdo->prepare("INSERT INTO $album(idCapa, imagem) VALUES('$last', '$arquivo')");
        $inseri = $inserir->execute(); // Execute a inserção    
        }

    else {
        echo '<div class="alert alert-danger" role="alert">Erro, tente novamente mais tarde!</div>';
        }
    }   
}

    }
echo '<div class="alert alert-success" role="alert">Salvo com sucesso!</div>';
  }
}

?>

If you read the lines carefully, you’ll notice I’ve changed practically nothing, just 1 sinal was removed, what was in the looping for.

Of:

for ($i=0; $i <= $qtd; $i++) { 
    ...

To:

for ($i=0; $i < $qtd; $i++) { 
    ...

I also changed the name value of the path variable, which was uploads, for up, the rest is the same. I confess that I still have to try to understand your code.

Yet here you are performing upload and cadastro successfully, leaving only to cite the error.

The most likely error is in the structure of your table. This is how my table(s) table(s) is (to) structured:

--
-- Estrutura da tabela `albumimagens`
--

CREATE TABLE IF NOT EXISTS `albumimagens` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `idCapa` int(11) NOT NULL,
  `imagem` varchar(36) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idCapa` (`idCapa`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;


CREATE TABLE IF NOT EXISTS `capa` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(36) NOT NULL,
  `imagem` varchar(36) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=77 ;

Despite the values in the fields varchar are insufficient for the hash generated for the image name, the images were being saved in half.

Another thing is, if you look at my two tables, they both have a field ID independent primary key and with auto_increment, which in this case is mandatory and in others is simply recommended. So if possible, delete and re-create the table albumimagens and try again.

See you later and good luck.

Other sources:

PDO Prepared Insert with mult. Rows...

  • Edilson, I confess that it became much more complicated than my own code, Oce had to create 3 functions to do something I did with one, I was very confused with some lines...

  • Sometimes to make the code more portable, and tidy, it’s necessary to do this -, then edit and put a resolution/explanation in order to your code.

  • There it is, I hope it works with you this time, because here it’s working normally, but I still recommend organizing loopings as this, or overly extensive statements in office, tends to help a lot.

  • Edilson, I was able to find the error! I was not creating a default id for the table albumimagens, was just using the idCapa, when I changed worked normally, thank you!

  • 2

    Glad you made it, it’s always good to work slow and pay attention to everything, buddy. Good luck.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.