使用织梦自带的 GetFirstImg 函数(最推荐)
这是织梦官方提供或社区公认的函数,专门用于这个目的,兼容性最好,也最稳定。

(图片来源网络,侵删)
函数代码
您需要确保这个函数存在,如果您的系统中没有,请将它添加到您的核心函数文件中。
打开文件:/include/helpers/extend.helper.php
在文件末尾的 ?> 之前,添加以下代码:
/**
* 获取文档中的第一张图片地址
*
* @param string $body 文档内容
* @param string $prefix 图片地址前缀
* @return string
*/
if ( ! function_exists('GetFirstImg'))
{
function GetFirstImg($body, $prefix = '')
{
if (empty($body)) return '';
$preg = "/<img.*?src=[\'|\"](.*?)[\'|\"].*?[\/]?>/i";
preg_match_all($preg, $body, $match);
if (!empty($match[1][0])) {
// 如果设置了前缀(如网站域名),则拼接
if (!empty($prefix)) {
return $prefix . $match[1][0];
}
return $match[1][0];
}
return '';
}
}
注意:
extend.helper.php文件是专门用来存放扩展函数的,修改它不会影响核心程序升级,所以是最佳选择。(图片来源网络,侵删)
如何使用
添加完函数后,您就可以在任何需要的地方调用它了,比如在列表页、内容页等。
示例1:在列表页(list_article.htm)中使用
假设您想在列表页的循环中,为每篇文章获取一张缩略图。
{dede:list pagesize='10'}
<li>
<!-- 调用GetFirstImg函数获取第一张图,并加上网站域名前缀 -->
[field:body function='GetFirstImg(@me, "{dede:global.cfg_basehost/}")'/]
<!-- 如果获取到图片,则显示,否则显示默认图片 -->
<a href="[field:arcurl/]">
<img src="[field:body function='GetFirstImg(@me, "{dede:global.cfg_basehost/}")'/]"
onerror="this.src='/images/default.jpg'" <!-- 设置一个默认图片 -->
alt="[field:title function='html2text(@me)'/]" />
</a>
<h2><a href="[field:arcurl/]">[field:title/]</a></h2>
<p>[field:description function='cn_substr(@me, 100)'/]...</p>
</li>
{/dede:list}
代码解释:

(图片来源网络,侵删)
{dede:global.cfg_basehost/}:这是织梦的全局变量,代表您网站的域名,如http://www.yoursite.com,用它作为前缀可以确保图片路径是完整的。function='GetFirstImg(@me, "{dede:global.cfg_basehost/}")':这是核心调用。@me:代表当前字段的值,这里就是field:body的文章内容。GetFirstImg(...):是我们刚刚添加的函数。onerror="this.src='/images/default.jpg'":这是一个很好的实践,如果文章中没有图片,GetFirstImg会返回空,img标签的src会无效,onerror就会触发,显示一张您指定的默认图片,避免页面布局错乱。
使用自定义SQL查询(适用于列表页)
如果您不想修改文件,或者希望在列表页直接从数据库获取,可以通过修改列表的SQL查询来实现。
修改列表模板
打开您的列表模板文件,list_article.htm。
找到列表的起始标签 {dede:list},并将其替换为自定义的SQL标签。
原始代码:
{dede:list pagesize='10'}
<!-- 循环内容 -->
{/dede:list}
修改后的代码:
{dede:sql sql='
SELECT
a.id,
a.title,
a.description,
a.pubdate,
a.body,
SUBSTRING_INDEX(SUBSTRING_INDEX(a.body, "src='", -1), "'", 1) AS first_img
FROM
dede_archives a
LEFT JOIN
dede_addonarticle b ON a.id = b.aid
WHERE
a.channel = 1
AND a.arcrank > -1
ORDER BY
a.sortrank DESC
limit 0, 10;
'}
<li>
<a href="[field:arcurl/]">
<!-- 判断是否获取到图片 -->
[field:first_img runphp='yes']
if(@me != '') {
@me = '<img src="' . @me . '" alt="' . addslashes('[field:title/]') . '" />';
} else {
@me = '<img src="/images/default.jpg" alt="' . addslashes('[field:title/]') . '" />';
}
[/field:first_img]
</a>
<h2><a href="[field:arcurl/]">[field:title/]</a></h2>
<p>[field:description function='cn_substr(@me, 100)'/]...</p>
</li>
{/dede:sql}
代码解释
- SQL语句:
SUBSTRING_INDEX(SUBSTRING_INDEX(a.body, "src='", -1), "'", 1):这是这个方法的核心,这是一个MySQL字符串函数,用于从文章内容a.body中提取src属性的值。- 它的工作原理是:先找到最后一个
src=',然后从这个位置开始取到后面的内容,再从这个结果中找到第一个 并取它之前的内容,这样就精确地提取了图片地址。 WHERE a.channel = 1:1代表文章模型,请根据您的实际情况修改。limit 0, 10:代表获取10条记录,pagesize属性在这里无效,需要手动修改数字来控制条数。
runphp='yes':在{dede:sql}中,默认情况下字段值不会被PHP处理,使用runphp='yes'可以让field:first_img中的PHP代码生效,从而实现判断和输出HTML标签。
手动编写PHP代码(适用于内容页或其他PHP文件)
如果您需要在PHP文件(如 index.php 或自定义页面)中获取,可以直接使用PHP代码。
<?php
// 假设 $articleBody 是从数据库获取的文章内容
$articleBody = '<p>这是一段文字,<img src="/uploads/2025/10/01/pic1.jpg" alt="图片1" />这里有一张图。</p><p>后面还有另一张<img src="http://www.example.com/pic2.jpg" alt="图片2" />。</p>';
// 使用正则表达式匹配
$pattern = "/<img.*?src=[\'|\"](.*?)[\'|\"].*?[\/]?>/i";
preg_match_all($pattern, $articleBody, $matches);
// 检查是否匹配到图片
if (!empty($matches[1]) && !empty($matches[1][0])) {
$firstImageUrl = $matches[1][0];
// 如果是相对路径,可以加上网站域名
if (strpos($firstImageUrl, 'http') !== 0) {
$firstImageUrl = 'http://www.yoursite.com' . $firstImageUrl;
}
echo "获取到的第一张图片地址是:" . $firstImageUrl;
} else {
echo "文章中没有找到图片。}
?>
总结与建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
GetFirstImg 函数 |
最推荐,代码整洁,可复用,不依赖特定模板,符合织梦规范。 | 需要修改 extend.helper.php 文件(一次即可,非常安全)。 |
几乎所有场景,尤其是列表页和内容页的模板调用。 |
| 自定义SQL | 无需修改PHP文件,直接在模板中完成。 | SQL语句复杂,不易读;pagesize 失效,需手动控制条数;灵活性稍差。 |
不方便修改核心文件,且只需要在列表页使用的场景。 |
| 原生PHP代码 | 灵活性最高,可以在任何PHP文件中使用。 | 代码冗长,不适用于模板文件,不符合织梦的标签化思想。 | 在PHP控制器、API接口或非模板页面中获取图片。 |
对于绝大多数开发者来说,强烈推荐使用方法一,因为它是最规范、最稳定、最易于维护的解决方案。

