酷秀博客
首页/PHP文章内容图片获取函数A I

PHP文章内容图片获取函数

admin的头像admin3个月前A I134热度

完整版PHP图片获取函数

新增开关+缺省图配置 | 支持img/MD | 校验可控 | 直接可用


/**<br />
 * 提取文本中图片地址(支持img标签+Markdown)<br />
 * @param string $content       源文本(html/md)<br />
 * @param bool   $unique        是否去重,默认是<br />
 * @param bool   $checkExists   是否校验存在开关,默认true<br />
 * @param int    $timeout       远程校验超时(秒),默认3<br />
 * @param string $defaultImg    不存在时显示的默认图,空则不显示<br />
 * @return array 处理后的图片URL数组<br />
 */<br />
function getImagesFromContent(<br />
    string $content,<br />
    bool   $unique = true,<br />
    bool   $checkExists = true,<br />
    int    $timeout = 3,<br />
    string $defaultImg = ''<br />
): array {<br />
    $images = [];<br />
    <br />
    // 1.匹配img标签(兼容单双引号/无引号)<br />
    $imgPattern = '/<img[^>]+src=[\'"]?([^\'" >]+)[\'"]?/i';<br />
    preg_match_all($imgPattern, $content, $imgMatches);<br />
    !empty($imgMatches[1]) && $images = array_merge($images, $imgMatches[1]);<br />
<br />
    // 2.匹配MD图片(兼容带描述/无描述/首尾空格)<br />
    $mdPattern = '/!\[.*?\]\((\s*?.*?\s*?)\)/i';<br />
    preg_match_all($mdPattern, $content, $mdMatches);<br />
    !empty($mdMatches[1]) && $images = array_merge($images, $mdMatches[1]);<br />
<br />
    // 3.基础过滤(合法路径)<br />
    $images = array_filter($images, fn($url) => preg_match('/^(https?:\/\/|\/|\.\/|\.\.\/)/i', trim($url)));<br />
<br />
    // 4.去重<br />
    $unique && $images = array_values(array_unique($images));<br />
    $images = array_map('trim', $images);<br />
    <br />
    // 5.存在性校验(开关可控) + 缺省图替换<br />
    if ($checkExists) {<br />
        $images = array_map(function($url) use ($timeout, $defaultImg) {<br />
            return checkImageExists($url, $timeout) ? $url : ($defaultImg ?: '');<br />
        }, $images);<br />
        // 无默认图时过滤无效图,有则保留默认图<br />
        if(empty($defaultImg)) $images = array_filter($images);<br />
    }<br />
    <br />
    return array_values($images);<br />
}<br />
<br />
/**<br />
 * 图片存在性校验(远程+本地双适配)<br />
 */<br />
function checkImageExists(string $url, int $timeout = 3): bool {<br />
    if(empty($url)) return false;<br />
    <br />
    // 远程图(HEAD请求,高效不下载)<br />
    if(preg_match('/^https?:\/\//i', $url)){<br />
        $context = stream_context_create([<br />
            'http' => ['method'=>'HEAD', 'timeout'=>$timeout, 'ignore_errors'=>true],<br />
            'ssl'  => ['verify_peer'=>false, 'verify_peer_name'=>false]<br />
        ]);<br />
        $headers = @get_headers($url,1,$context);<br />
        if(!$headers) return false;<br />
        $status = $headers[0] ?? '';<br />
        $type = $headers['Content-Type'] ?? '';<br />
        return strpos($status,'200 OK')!==false && preg_match('/image\//i', $type);<br />
    }<br />
    <br />
    // 本地图(补根目录+校验文件+验格式)<br />
    $localPath = $_SERVER['DOCUMENT_ROOT'].str_replace(['//','/./'],'/',$url);<br />
    return file_exists($localPath) && is_file($localPath) && getimagesize($localPath);<br />
}<br />
<br />
// curl兼容方案(allow_url_fopen禁用时用)<br />
function checkImageExistsCurl(string $url, int $timeout=3):bool{<br />
    if(empty($url) || !preg_match('/^https?:\/\//i',$url)) return false;<br />
    $ch = curl_init($url);<br />
    curl_setopt_array($ch,[<br />
        CURLOPT_NOBODY=>true, CURLOPT_TIMEOUT=>$timeout,<br />
        CURLOPT_SSL_VERIFYPEER=>false, CURLOPT_RETURNTRANSFER=>true<br />
    ]);<br />
    curl_exec($ch);<br />
    $status = curl_getinfo($ch,CURLINFO_HTTP_CODE);<br />
    $type = curl_getinfo($ch,CURLINFO_CONTENT_TYPE);<br />
    curl_close($ch);<br />
    return $status===200 && preg_match('/image\//i',$type);<br />
}<br />
```<br />
<br />
核心新增功能<br />
  checkExists=true/false 自由开关校验,关闭则直接返回所有图<br />
  传defaultImg则无效图替换为该图,不传则自动过滤无效图<br />
  全程兼容远程/本地图,不影响原有所有功能<br />
<br />
调用示例(3种常用场景)<br />
```php<br />
<?php<br />
$testContent = '<img src="https://picsum.photos/200"><img src="/test.jpg"><img src="https://xxx/404.jpg">![图](https://picsum.photos/300)';<br />
<br />
// 场景1:校验开启+无默认图(过滤无效图)<br />
$imgs1 = getImagesFromContent($testContent, true, true, 3);<br />
var_dump($imgs1); // 只返回有效图<br />
<br />
// 场景2:校验开启+默认图(无效图替换)<br />
$imgs2 = getImagesFromContent($testContent, true, true, 3, 'https://xxx/default.png');<br />
var_dump($imgs2); // 无效图替换为默认图<br />
<br />
// 场景3:关闭校验(直接返回所有图,最快)<br />
$imgs3 = getImagesFromContent($testContent, true, false);<br />
var_dump($imgs3); // 不校验,全部返回<br />
```<br />
<br />
避坑提示<br />
1.  远程校验优先用get_headers,需开启allow_url_fopen;禁用则换checkImageExistsCurl<br />
2.  defaultImg建议传绝对URL,避免相对路径找不到<br />
3.  超时设2-5秒最佳,兼顾速度与准确性
签名: 最忠诚的BUG开发者来自: 重庆市. 火狐浏览器
文章目录