Home  >  Article  >  Backend Development  >  How to use php to capture images without suffix

How to use php to capture images without suffix

王林
王林forward
2020-01-23 18:47:202858browse

How to use php to capture images without suffix

The specific implementation steps are as follows:

Create project

As a demonstration, we create the project grabimg in the www root directory, create A class GrabImage.php and an index.php.

Writing class code

We define a class with the same name as the file: GrabImage

class GrabImage{
}

Attributes

The next few definitions attributes that need to be used.

1. First define an image address that needs to be captured: $img_url

2. Then define a $file_name to store the name of the file, but do not carry the extension name because it may involve The extension name is changed, so here we unpack the definition

3, followed by the extension name $extension

4, and then we define a $file_dir. The function of this attribute is to capture the remote image. The directory stored locally is generally relative to the location of the PHP entry file as the starting point. However, this path is generally not saved to the database.

5. Finally, we define a $save_dir. As the name suggests, this path is the directory for directly saving the database. To explain here, we do not directly store the file saving path in the database. This is usually to prepare for the convenience of changing the path if the system is migrated later. Our $save_dir here is generally the date file name. If you need to use it, take it out and spell the required path in front.

(Free learning video tutorial sharing: php video tutorial)

Method

The attributes are finished, let’s officially Start scraping.

First we define an open method getInstances to obtain some data, such as the address of the captured image and the local save path. Also put it in properties.

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/
}

The image saving path has been spliced. Now we have to pay attention to a question, whether the directory exists. The date goes by day by day, but the directory is not automatically created. Therefore, before saving the image, you need to check it first. If the current directory does not exist, we need to create it immediately.

We create the set directory method setDir. We set the attribute to private, safe

How to use php to capture images without suffix

The next step is to capture the core code

The first step is to solve a problem, the image we need to capture may No suffix. According to the traditional crawling method, it is not feasible to crawl the image first and then intercept the suffix name.

We must obtain the image type through other methods. The method is to obtain the file header information from the file stream information, thereby judging the file mime information, and then you can know the file suffix name.

For convenience, first define a mime and file extension mapping.

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

In this way, when I get the type of image/gif, I can know that it is a .gif picture.

Use the php function get_headers to obtain file stream header information. When its value is not false, we assign it to the variable $headers

and take out the value of Content-Type which is the value of mime.

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

Using the mapping table we defined above, we can easily obtain the suffix name.

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

Of course, the $type obtained above may not exist in our mapping table, which means that this type of file is not what we want. Just discard it and ignore it.

The following steps are the same as traditional grabbing files.

$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;
}

First get the full path of the local saved image $file_path, then use file_get_contents to grab the data, and then use file_put_contents to save to the file path just now.

Finally we return a path that can be saved directly to the database instead of a file storage path.

The complete crawling method is as follows:

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;
}

Finally, for the sake of simplicity, we want to complete the crawling by just calling one of the methods elsewhere. Therefore, we put the crawling action directly into getInstances, and after configuring the path, we crawl directly. Therefore, we add code in the initialization configuration method getInstances.

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

Test

Let’s try it in the index.php file we just created.

<?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);
?>

The complete code is as follows:


 * @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;
    }
}

Recommended related articles and tutorials: php tutorial

The above is the detailed content of How to use php to capture images without suffix. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:cnblogs.com. If there is any infringement, please contact admin@php.cn delete