File_exists solution in php check

Asked

Viewed 332 times

-2

Alternative function for the file_exists function()

define('BASE', 'http://localhost/seusite'); 

public static function checkImageExists($urlImage) {
    $filename = BASE . "/uploads/{$urlImage}";
    $ExtFile = mb_strtolower(strrchr($filename, "."));
    $Extension = ['.jpg', '.jpeg', '.png'];
    if (in_array($ExtFile, $Extension) && (@fopen($filename, "r") == true)):
        if (getimagesize($filename)):
            return true;
        else:
            return false;
        endif;
    else:
        return false;
    endif;
}

using the function:

checkImageExists(portfolio/2018/02/1-novo-1518485054.jpg);
  • Have you checked with the Xhprof to see if it’s worth it?

  • 1

    Are you just publicizing the function? If so, it’s best to use Github. With at least 20 reputation you can join [chat] and publicize it there. If you have any questions about the code, your question was unclear and needs editing. Do the [tour] and read the [Ask] guide for more details.

  • Just to share it, I don’t know how to move it yet!

  • It is not necessary FOPEN to use GETIMAGESIZE, in fact FOPEN will keep the file open until the script is finished, which is really a big problem, it would be better to use only is_file

  • Dear Romulo, I know it has been a long time, but I would like to know if you have ever tested my answer. See you soon.

1 answer

1

It’s not necessary fopen to use getimagesize, in fact the fopen will keep the file open until the script is finished, which is really a huge problem, for example if you are going to do delete or edit operations or change the position pointer.

Another unnecessary check that can lead to error is the checking of file extension, really it is somewhat unnecessary if it is to take into account that a server can customize the extensions to yet the internal content of the document is an image.

It would be better to use alone is_file combined with getimagesize, since it itself will only recognize images, so:

function is_image($path)
{
    return is_file($path) && getimagesize($path) !== false;
}

The is_file checks whether it is a file and whether it exists, whether it is a folder or not it returns false.

The getimagesize always returns array, except when the file is not an image, so in the case !== false can be a little better at micro-optimization, for example you will check several files at once a folder, where it can contain thousands of files.

If you want to check specifics instead of using getimagesize may be more efficient to use finfo, that uses MAGIC to check the file mime-type, for example:

class Image
{
    const JPEG = 1;
    const GIF = 2;
    const PNG = 3;
    const WEBP = 4;
    const SVG = 5;

    public static function isImage($path, $type)
    {
        if (is_file($path) === false) {
            return false;
        }

        $mime = self::mime($path);

        switch ($type) {
            case self::JPEG:
                return $mime === 'jpeg';

            case self::GIF:
                return $mime === 'gif';

            case self::PNG:
                return $mime === 'png';

            case self::WEBP:
                return $mime === 'webp';

            case self::SVG:
                return $mime === 'svg+xml';

            default:
                throw new InvalidArgumentException("Argumento precisa ser uma das constantes definidas na class Image");
        }
    }

    private static function mime($path)
    {
        $mime = '';

        if (function_exists('finfo_open')) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mime  = finfo_file($finfo, $path);
            finfo_close($finfo);
        } elseif (function_exists('mime_content_type')) {
            $mime = mime_content_type($path);
        }

        return strpos($mime, 'image/') === 0 ? substr($mime, 6) : false;
    }
}

The use would be very simple, like this:

Image::isImage('image/foto.jpg', Image::JPEG); //Retorna TRUE
Image::isImage('image/foto.jpg', Image::GIF);  //Retorna FALSE
Image::isImage('image/foto.jpg', Image::PNG);  //Retorna FALSE

In a procedural style could do so:

define('IMAGE_JPEG', 1);
define('IMAGE_GIF', 2);
define('IMAGE_PNG', 3);
define('IMAGE_WEBP', 4);
define('IMAGE_SVG', 5);

function is_image($path, $type)
{
    if (is_file($path) === false) {
        return false;
    }

    $mime = image_mime($path);

    switch ($type) {
        case IMAGE_JPEG:
            return $mime === 'jpeg';

        case IMAGE_GIF:
            return $mime === 'gif';

        case IMAGE_PNG:
            return $mime === 'png';

        case IMAGE_WEBP:
            return $mime === 'webp';

        case IMAGE_SVG:
            return $mime === 'svg+xml';

        default:
             throw new InvalidArgumentException("Argumento precisa ser uma das constantes definidas na class Image");
    }
}

function image_mime($path)
{
    $mime = '';

    if (function_exists('finfo_open')) {
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mime  = finfo_file($finfo, $path);
        finfo_close($finfo);
    } elseif (function_exists('mime_content_type')) {
        $mime = mime_content_type($path);
    }

    return strpos($mime, 'image/') === 0 ? substr($mime, 6) : false;
}

The use would be like this:

is_image('image/foto.png', IMAGE_JPEG); //Retorna FALSE
is_image('image/foto.png', IMAGE_GIF);  //Retorna FALSE
is_image('image/foto.png', IMAGE_PNG);  //Retorna TRUE

Browser other questions tagged

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