Maison  >  Article  >  développement back-end  >  Tutoriel de capture d'images distantes PHP (y compris les images sans suffixe)

Tutoriel de capture d'images distantes PHP (y compris les images sans suffixe)

藏色散人
藏色散人avant
2019-11-04 13:40:192886parcourir

Lorsque je développais la connexion WeChat auparavant, j'ai découvert que les images d'avatar WeChat n'avaient pas de nom de suffixe. La méthode traditionnelle de capture d'image ne fonctionnait pas et nécessitait un traitement de capture spécial. Par conséquent, diverses situations ont ensuite été combinées, regroupées dans une classe et partagées.

Créer un projet

A titre de démonstration, nous créons le projet grabimg dans le répertoire racine www, créons une classe GrabImage.php et un index.php.

Ecriture du code de classe

On définit une classe du même nom que le fichier : GrabImage

class GrabImage{
}

Attributs

Définissez ensuite plusieurs propriétés qui doivent être utilisées.

1. Définissez d'abord une adresse d'image qui doit être capturée : $img_url

2. Définissez ensuite un $file_name pour stocker le nom du fichier, mais ne portez pas le nom de l'extension, car cela peut impliquer Le nom de l'extension est modifié, nous décompressons donc ici la définition

3, suivie du nom de l'extension $extension

4 Ensuite, nous définissons un $file_dir La fonction de ceci. L'attribut est de capturer l'image distante. Le répertoire stocké localement est généralement relatif à l'emplacement du fichier d'entrée PHP comme point de départ. Cependant, ce chemin n'est généralement pas enregistré dans la base de données.

5. Enfin, nous définissons un $save_dir Comme son nom l'indique, ce chemin est le répertoire permettant de sauvegarder directement la base de données. Pour expliquer ici, nous ne stockons pas directement le chemin d'enregistrement du fichier dans la base de données. Il s'agit généralement de préparer la commodité de modifier le chemin si le système est migré ultérieurement. Notre $save_dir ici est généralement la date + le nom du fichier. Si vous avez besoin de l'utiliser, supprimez-le et épelez le chemin requis devant.

Méthode

Les attributs sont terminés, puis nous commençons officiellement le travail d'exploration.

Nous définissons d'abord une méthode ouverte getInstances pour obtenir certaines données, telles que l'adresse de l'image capturée et le chemin de sauvegarde local. Mettez-le également dans les propriétés.

public function getInstances($img_url , $base_dir)
{
    $this->img_url = $img_url;
    $this->save_dir = date("Ym").'/'.date("d").'/'; // 比如:201610/19/
    $this->file_dir = $base_dir.'/'.$this->save_dir.'/'; // 比如:./uploads/image/2016/10/19/
}

Le chemin de sauvegarde de l'image a été épissé. Nous devons maintenant prêter attention à la question de savoir si le répertoire existe. La date défile de jour en jour, mais le répertoire n'est pas créé automatiquement. Par conséquent, avant de sauvegarder l’image, vous devez d’abord la vérifier. Si le répertoire actuel n’existe pas, nous devons le créer immédiatement.

Nous créons la méthode set directory setDir. Nous définissons l'attribut sur privé, sûr

/**
 * 检查图片需要保持的目录是否存在
 * 如果不存在,则立即创建一个目录
 * @return bool
 */
private function setDir()
{
    if(!file_exists($this->file_dir))
    {
        mkdir($this->file_dir,0777,TRUE);
    }
    $this->file_name = uniqid().rand(10000,99999);// 文件名,这里只是演示,实际项目中请使用自己的唯一文件名生成方法
    return true;
}

L'étape suivante consiste à capturer le code principal

La première étape consiste à résoudre un problème. Les images que nous devons capturer peuvent ne pas avoir de suffixe. nom. Selon la méthode d'exploration traditionnelle, il n'est pas possible d'explorer d'abord l'image, puis d'intercepter le nom du suffixe.

Nous devons obtenir le type d'image par d'autres méthodes. La méthode consiste à obtenir les informations d'en-tête de fichier à partir des informations de flux de fichier, jugeant ainsi les informations MIME du fichier, puis vous pouvez connaître le nom du suffixe du fichier.

Pour plus de commodité, définissez d'abord un mappage MIME et extension de fichier.

$mimes=array(
    'image/bmp'=>'bmp',
    'image/gif'=>'gif',
    'image/jpeg'=>'jpg',
    'image/png'=>'png',
    'image/x-icon'=>'ico'
);

De cette façon, lorsque j'obtiens le type d'image/gif, je peux savoir qu'il s'agit d'une image .gif.

Utilisez la fonction php get_headers pour obtenir les informations d'en-tête du flux de fichiers. Lorsque sa valeur n'est pas fausse, on l'affecte à la variable $headers

et on retire la valeur de Content-Type qui est la valeur de mime.

if(($headers=get_headers($this->img_url, 1))!==false){
    // 获取响应的类型
    $type=$headers['Content-Type'];
}

En utilisant la table de mappage que nous avons définie ci-dessus, nous pouvons facilement obtenir le nom du suffixe.

$this->extension=$mimes[$type];

Bien sûr, le $type obtenu ci-dessus peut ne pas exister dans notre table de mappage, ce qui signifie que ce type de fichier n'est pas ce que nous voulons. Jetez-le simplement et ignorez-le.

Les étapes suivantes sont les mêmes que pour les fichiers de saisie traditionnels.

$file_path = $this->file_dir.$this->file_name.".".$this->extension;
// 获取数据并保存
$contents=file_get_contents($this->img_url);
if(file_put_contents($file_path , $contents))
{
    // 这里返回出去的值是直接保存到数据库的路径 + 文件名,形如:201610/19/57feefd7e2a7aY5p7LsPqaI-lY1BF.jpg
    return $this->save_dir.$this->file_name.".".$this->extension;
}

Obtenez d'abord le chemin complet de l'image enregistrée locale $file_path, puis utilisez file_get_contents pour récupérer les données, puis utilisez file_put_contents pour enregistrer dans le chemin du fichier tout à l'heure.

Enfin, nous renvoyons un chemin qui peut être enregistré directement dans la base de données au lieu d'un chemin de stockage de fichiers.

La version complète de cette méthode d'exploration est :

private function getRemoteImg()
{
    // mime 和 扩展名 的映射
    $mimes=array(
        'image/bmp'=>'bmp',
        'image/gif'=>'gif',
        'image/jpeg'=>'jpg',
        'image/png'=>'png',
        'image/x-icon'=>'ico'
    );
    // 获取响应头
    if(($headers=get_headers($this->img_url, 1))!==false)
    {
        // 获取响应的类型
        $type=$headers['Content-Type'];
        // 如果符合我们要的类型
        if(isset($mimes[$type]))
        {
            $this->extension=$mimes[$type];
            $file_path = $this->file_dir.$this->file_name.".".$this->extension;
            // 获取数据并保存
            $contents=file_get_contents($this->img_url);
            if(file_put_contents($file_path , $contents))
            {
                // 这里返回出去的值是直接保存到数据库的路径 + 文件名,形如:201610/19/57feefd7e2a7aY5p7LsPqaI-lY1BF.jpg
                return $this->save_dir.$this->file_name.".".$this->extension;
            }
        }
    }
    return false;
}

Enfin, par souci de simplicité, nous souhaitons simplement appeler l'une des méthodes ailleurs pour terminer l'exploration. Par conséquent, nous plaçons l'action d'exploration directement dans getInstances, et après avoir configuré le chemin, explorons directement. Par conséquent, ajoutons du code dans la méthode de configuration d'initialisation getInstances.

if($this->setDir())
{
    return $this->getRemoteImg();
}
else
{
    return false;
}

Test

Essayons-le dans le fichier index.php que nous venons de créer.

<?php
require_once &#39;GrabImage.php&#39;;
$object = new GrabImage();
$img_url = "http://www.bidianer.com/img/icon_mugs.jpg"; // 需要抓取的远程图片
$base_dir = "./uploads/image"; // 本地保存的路径
echo $object->getInstances($img_url , $base_dir);
?>

Hé, je l'ai capturé

Tutoriel de capture dimages distantes PHP (y compris les images sans suffixe)

Code complet


 * @link bidianer.com
 */
class GrabImage{
    /**
     * @var string 需要抓取的远程图片的地址
     * 例如:http://www.bidianer.com/img/icon_mugs.jpg
     * 有一些远程文件路径可能不带拓展名
     * 形如:http://www.xxx.com/img/icon_mugs/q/0
     */
    private $img_url;
    /**
     * @var string 需要保存的文件名称
     * 抓取到本地的文件名会重新生成名称
     * 但是,不带拓展名
     * 例如:57feefd7e2a7aY5p7LsPqaI-lY1BF
     */
    private $file_name;
    /**
     * @var string 文件的拓展名
     * 这里直接使用远程图片拓展名
     * 对于没有拓展名的远程图片,会从文件流中获取
     * 例如:.jpg
     */
    private $extension;
    /**
     * @var string 文件保存在本地的目录
     * 这里的路径是PHP保存文件的路径
     * 一般相对于入口文件保存的路径
     * 比如:./uploads/image/201610/19/
     * 但是该路径一般不直接存储到数据库
     */
    private $file_dir;
    /**
     * @var string 数据库保存的文件目录
     * 这个路径是直接保存到数据库的图片路径
     * 一般直接保存日期 + 文件名,需要使用的时候拼上前面路径
     * 这样做的目的是为了迁移系统时候方便更换路径
     * 例如:201610/19/
     */
    private $save_dir;
    /**
     * @param string $img_url 需要抓取的图片地址
     * @param string $base_dir 本地保存的路径,比如:./uploads/image,最后不带斜杠"/"
     * @return bool|int
     */
    public function getInstances($img_url , $base_dir)
    {
        $this->img_url = $img_url;
        $this->save_dir = date("Ym").'/'.date("d").'/'; // 比如:201610/19/
        $this->file_dir = $base_dir.'/'.$this->save_dir.'/'; // 比如:./uploads/image/2016/10/19/
        return $this->start();
    }
    /**
     * 开始抓取图片
     */
    private function start()
    {
        if($this->setDir())
        {
            return $this->getRemoteImg();
        }
        else
        {
            return false;
        }
    }
    /**
     * 检查图片需要保持的目录是否存在
     * 如果不存在,则立即创建一个目录
     * @return bool
     */
    private function setDir()
    {
        if(!file_exists($this->file_dir))
        {
            mkdir($this->file_dir,0777,TRUE);
        }
        $this->file_name = uniqid().rand(10000,99999);// 文件名,这里只是演示,实际项目中请使用自己的唯一文件名生成方法
        return true;
    }
    /**
     * 抓取远程图片核心方法,可以同时抓取有后缀名的图片和没有后缀名的图片
     *
     * @return bool|int
     */
    private function getRemoteImg()
    {
        // mime 和 扩展名 的映射
        $mimes=array(
            'image/bmp'=>'bmp',
            'image/gif'=>'gif',
            'image/jpeg'=>'jpg',
            'image/png'=>'png',
            'image/x-icon'=>'ico'
        );
        // 获取响应头
        if(($headers=get_headers($this->img_url, 1))!==false)
        {
            // 获取响应的类型
            $type=$headers['Content-Type'];
            // 如果符合我们要的类型
            if(isset($mimes[$type]))
            {
                $this->extension=$mimes[$type];
                $file_path = $this->file_dir.$this->file_name.".".$this->extension;
                // 获取数据并保存
                $contents=file_get_contents($this->img_url);
                if(file_put_contents($file_path , $contents))
                {
                    // 这里返回出去的值是直接保存到数据库的路径 + 文件名,形如:201610/19/57feefd7e2a7aY5p7LsPqaI-lY1BF.jpg
                    return $this->save_dir.$this->file_name.".".$this->extension;
                }
            }
        }
        return false;
    }
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer