Jump to content
  • 0
Omar~

[Resolvido] Como apagar arquivo já existente com PHP sem saber a extensão

Question

Bem criei essa classe de upload de imagem para os avateres de usuários de um site que estou fazendo.

Está aqui a classe:

Spoiler

<?php

class avatarUpload {

    // Atributos do Arquivo enviado
    private $file;
    private $name;
    private $size;
    // Atributos para a imagem convertida
    private $image;
    private $finalName;
    private $newImage;
    // Atributo da pasta de armazenamento
    private $folder;
    // Atributos dos Resultados obtidos
    private $result;

    /** ***************************************************************
     * @Method: Construtor da classe
     * Se não informar um diretório ou se não existir cria um 
     * por padrão.
     ** ***************************************************************/
    function __construct($uploadDir = null) {
        $this->folder = ((string) $uploadDir ? $uploadDir : './upload/');
        if (!file_exists($this->folder) && !is_dir($this->folder)) {
            mkdir($this->folder, 0777);
        }
    }

    /** ***************************************************************
     * @Method: Obtem os dados pelos parâmetros
     * * Informe uma arquivo por Global $_FILE e o nome para o arquivo
     ** ***************************************************************/
    public function sendImage(array $file, $filename) {
        $this->file = $file;
        $this->name = (string) $filename;
        $this->size = 250;
        $this->getImageType();
    }

    /** ***************************************************************
     * @Method: Retorna o resultado verdadeiro caso tenha sucesso
     * no upload do arquivo.
     ** ***************************************************************/
    public function setResult() {
        return $this->result;
    }

    /** ***************************************************************
     * @Method: Obtem o tipo de imagem.
     * @return (bool) Se não for imagem jpg.. ou png... restorna falso
     * se true executa o próximo método.
     ** ***************************************************************/
    private function getImageType() {
        switch ($this->file['type']) {
            case 'image/jpg':
            case 'image/jpeg':
            case 'image/pjpeg':
                $this->image = imagecreatefromjpeg($this->file['tmp_name']);
                break;
            case 'image/png':
            case 'image/x-png':
                $this->image = imagecreatefrompng($this->file['tmp_name']);
                break;
        }
        if (!$this->image) {
            @imagedestroy($this->image);
            $this->result = false;
        } else {
            $this->setImageResize();
        }
    }

    /** ***************************************************************
     * @Method: Redimenciona a imagem caso ela seja maior que o 
     * permitido.
     ** ***************************************************************/
    private function setImageResize() {
        $x = imagesx($this->image);
        $y = imagesy($this->image);
        $imageX = ( $this->size < $x ? $this->size : $x );
        $imageY = ($imageX * $y) / $x;

        $this->newImage = imagecreatetruecolor($imageX, $imageY);
        imagealphablending($this->newImage, false);
        imagesavealpha($this->newImage, true);
        imagecopyresampled($this->newImage, $this->image, 0, 0, 0, 0, $imageX, $imageY, $x, $y);

        $this->finalName = strtolower($this->name . strrchr($this->file['name'], '.'));
        $this->createNewImage();
    }

    /** ***************************************************************
     * @Method: Cria a nova imagem já tratada na pasta de envio
     * permitido.
     * @return (bool) Se houver problemas durante o processo de
     * armazenamento remoto, retorna um resultado falso e não salva a
     * imagem.
     ** ***************************************************************/
    private function createNewImage() {
        switch ($this->file['type']) {
            case 'image/jpg':
            case 'image/jpeg':
            case 'image/pjpeg':
                imagejpeg($this->newImage, $this->folder . $this->finalName);
                break;
            case 'image/png':
            case 'image/x-png':
                imagepng($this->newImage, $this->folder . $this->finalName);
                break;
        }
        imagedestroy($this->image);
        imagedestroy($this->newImage);

        if (!$this->newImage) {
            $this->result = false;
        } else {
            $this->result = true;
        }
    }

}

 

 

Até aí tudo bem, acontece o seguinte com o passar do tempo muitas imagens estarão hospedadas no diretório, a intenção é, toda vez que um usuário upar uma nova imagem a anterior é deletada, justamente porque tratei de colocar o nome da imagem passando por parâmetro o id da conta que estiver cadastrada, assim sendo somente terei 1 imagem com o número do ID da conta.

No que até aqui tudo bem 100% funcional como queria, mas acontece que na classe permito o upload de imagem do tipo PNG e JPG assim sendo se um usuário upar uma imagem em um formato e depois em outra terei 2 imagens com o mesmo nome, mas com a extensão diferente.

 

Enfim alguma sugestão de como prever que isso aconteça, sendo somente ser possível ter 1 única imagem no diretório independente da extensão.

Obs.: Fiz alguns testes usando "unlink", mas não obtive sucesso.

No mais acho que o procedimento seria apagar a anterior, porém não sei como proceder.

Share this post


Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Bom dia. No ato do upload da imagem pelo usuário, faça a consulta na tabela para pegar o nome da imagem com sua extensão, obtendo sucesso basta apagar atualizar o registro e apagar a imagem atual, sem problema algum.

Share this post


Link to post
Share on other sites
  • 0

Primeiramente obrigado ao @Alaerte Gabriel por responder. 

Sim é uma boa sugestão mas resolvi o caso, bastou eu criar um array com as extensões de imagens, daí percorrer esse array buscando as extensões e apagar assim então. 

 

Citar

$extension = ['.jpg', '.jpeg', '.pjpeg', '.png', '.x-png'];
foreach ($extension as $value) {
      if (file_exists($this->folder . $this->name . $value)) {
          unlink($this->folder . $this->name . $value);
      }
}

 

Então tópico resolvido.

 

Aproveitei e modifiquei a class para upload de imagens em geral e vou compartilhar aqui:

imageUpload.php

Spoiler

class imageUpload {

    // Atributos do Arquivo enviado
    private $file;
    private $name;
    private $size;
    // Atributos da imagem convertida para a pasta
    private $image;
    private $finalName;
    private $newImage;
    private $imageX;
    private $imageY;
    private $sizeX;
    private $sizeY;
    // Atributo da pasta de armazenamento
    private $folder;
    // Atributos dos Resultados obtidos
    private $result;

    /** *****************************************************************
     * @Method: Construtor da classe
     * Se não informar um diretório ou se não existir cria um 
     * por padrão.
     /** ****************************************************************/
    function __construct($uploadDir = null) {
        $this->folder = ((string) $uploadDir ? $uploadDir : './upload/');
        if (!file_exists($this->folder) && !is_dir($this->folder)) {
            mkdir($this->folder, 0777);
        }
    }

    /** *****************************************************************
     * @Method: Obtem os dados pelos parâmetros
     * @param ($file) Informe uma arquivo por Global $_FILE
     * @param ($filename) Informe nome para o arquivo
     * @param ($width) Informe o tamanho da imagem "opcional"
     /** ****************************************************************/
    public function sendImage(array $file, $filename, $width = null) {
        $this->file = $file;
        $this->name = (string) $filename;
        $this->size = ((int) $width ? $width : 250);
        $this->getImageType();
    }

    /** *****************************************************************
     * @Method: Retorna o resultado verdadeiro caso tenha sucesso
     * no upload do arquivo.
     /** ****************************************************************/
    public function setResult() {
        return $this->result;
    }

    /** *****************************************************************
     * @Method: Obtem o tipo de imagem.
     * @return (bool) Se não for imagem jpg.. ou png... retorna falso
     *                se true executa o próximo método.
     /** ****************************************************************/
    private function getImageType() {
        switch ($this->file['type']) {
            case 'image/jpg':
            case 'image/jpeg':
            case 'image/pjpeg':
                $this->image = imagecreatefromjpeg($this->file['tmp_name']);
                break;
            case 'image/png':
            case 'image/x-png':
                $this->image = imagecreatefrompng($this->file['tmp_name']);
                break;
        }
        if (!$this->image) {
            @imagedestroy($this->image);
            $this->result = false;
        } else {
            $this->setImageResize();
        }
    }

    /** *****************************************************************
     * @Method: Redimenciona a imagem caso ela seja maior que o 
     * permitido.
     /** ****************************************************************/
    private function setImageResize() {
        $this->sizeX = imagesx($this->image);
        $this->sizeY = imagesy($this->image);
        $this->imageX = ($this->size < $this->sizeX ? $this->size : $this->sizeX);
        $this->imageY = ($this->imageX * $this->sizeY) / $this->sizeX;
        $this->newImage = imagecreatetruecolor($this->imageX, $this->imageY);
        imagealphablending($this->newImage, false);
        imagesavealpha($this->newImage, true);
        $this->copyImage();
    }

    /** *****************************************************************
     * @Method: Copia a imagem do diretório temporário 
     *          Define as dimensões da imagem
     *          Verifica se já existe uma imagem com o mesmo nome e a
     *          remove.
     /** ****************************************************************/
    private function copyImage() {
        $extension = ['.jpg', '.jpeg', '.pjpeg', '.png', '.x-png'];
        foreach ($extension as $value) {
            if (file_exists($this->folder . $this->name . $value)) {
                unlink($this->folder . $this->name . $value);
            }
        }
        imagecopyresampled($this->newImage, $this->image, 0, 0, 0, 0, $this->imageX, $this->imageY, $this->sizeX, $this->sizeY);
        $this->finalName = strtolower($this->name . strrchr($this->file['name'], '.'));
        $this->createNewImage();
    }

    /** *****************************************************************
     * @Method: Cria a nova imagem já tratada na pasta de envio.
     * @return (bool) Se houver problemas durante o processo de
     * armazenamento remoto, retorna um resultado falso e não salva a
     * imagem.
     /** ****************************************************************/
    private function createNewImage() {
        switch ($this->file['type']) {
            case 'image/jpg':
            case 'image/jpeg':
            case 'image/pjpeg':
                imagejpeg($this->newImage, $this->folder . $this->finalName);
                $this->result = true;
                break;
            case 'image/png':
            case 'image/x-png':
                imagepng($this->newImage, $this->folder . $this->finalName);
                $this->result = true;
                break;
        }
        imagedestroy($this->image);
        imagedestroy($this->newImage);
    }

}

 

 

Aqui é o exemplo como executar:

Existem algumas maneiras de proceder essa primeira. Apenas envia a imagem e deixa a classe se responsabilizar pelo resto.

Spoiler

<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <?php
        require 'imageUpload.php';
        $filter = filter_input_array(INPUT_POST, FILTER_DEFAULT);
        if ($filter && $filter['sendfile']) {
            $Upload = new imageUpload();
            $Upload->sendImage($_FILES['image'], 'nomeparaimagem');
            if ($Upload->setResult()) {
                echo "Enviou<hr>";
            } else {
                echo "Qualquer documentação para erro no envio<hr>";
            }
        }
        ?>
        <form action="" method="post" enctype="multipart/form-data">
            <input type="file" name="image">
            <br>
            <input type="submit" name="sendfile" value="Enviar Arquivo">
        </form>
    </body>
</html>

 

 

 

Aqui já seria caso quisesse permitir várias imagens sem apagar a anterior então crio um maneira de colocar um nome aleatório na imagem, sendo impossível que chegue a ter 2 nomes iguais.

Citar

* Preferir tratar eu mesmo do nome da imagem, assim sendo não é necessário manipulação de strings pela classe

 

Spoiler

<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <?php
        require 'imageUpload.php';
        $filter = filter_input_array(INPUT_POST, FILTER_DEFAULT);

        // Isso vai gerar um código de 5 caracteres:
        $codigo = "";
        $lengths = str_split("1234567890abcdefghijklmnopqrstuvxywz1234567890");
        for ($i = 0; $i < 5; $i++) {
            $codigo .= $lengths[array_rand($lengths)];
        }
        
        // Então pego o código gerado, contateno com o comando time para gerar um nome aleatório
        $nome = $codigo . '-' . time();

        if ($filter && $filter['sendfile']) {
            $Upload = new imageUpload();
            $Upload->sendImage($_FILES['image'], $nome);
            if ($Upload->setResult()) {
                echo "Enviou<hr>";
            } else {
                echo "Qualquer documentação para erro no envio<hr>";
            }
        }
        ?>
        <form action="" method="post" enctype="multipart/form-data">
            <input type="file" name="image">
            <br>
            <input type="submit" name="sendfile" value="Enviar Arquivo">
        </form>

    </body>
</html>

 

 

Também adicionei a classe a possibilidade de manipular o tamanho da imagem, é só passar o tamanho por parâmetro: 

Spoiler

$Upload = new imageUpload();
// $_FILES['image'] = Arquivo enviado pelo input "image"
// 'nomequalquer' = É o nome que terá a imagem
// 500 : É o tamanho da imagem no caso 500 de largura
// Nota: A classe sempre vai redimensionar a imagem e propoção real mantendo seus aspéctos reais
$Upload->sendImage($_FILES['image'], 'nomequalquer', 500); 

 

 

  • +1 1

Share this post


Link to post
Share on other sites
  • 0

Muito boa, e eu usando uma classe gigante pra fazer a mesma coisa, carregar uma imagem do icone do usuário e apagar a anterior, só adaptei o formato pois no meu caso é um icone mesmo e funcionou 100%, coloca no github, da pra ir dando umas atualizadas nela conforme formos colocando mais funcionalidades.

 

+1

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.