2009.01 14

在Wordpress中自动获取文章中的图片

在做Wordpress主题的时候,有一个问题一直没解决。那就是自动显示缩略图。当然,我知道你可能想利用wordpress中的自定义字段(custom field)功能,显然,这是可行的。但并不自动,这样的话,我们总需要手动添加custom field。很是麻烦。现在好了,在10 Killer WordPress Hacks这篇文章中,我看到最有用的一个hack将能解决这个问题,自动搜索文章图片,然后,显示。

<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<?php
$szPostContent = $post->post_content;
$szSearchPattern = '~<img [^\>]*\ />~'; // 搜索所有符合的图片
preg_match_all( $szSearchPattern, $szPostContent, $aPics );
$iNumberOfPics = count($aPics[0]); // 检查一下至少有一张图片
if ( $iNumberOfPics > 0 ) {
// 这里是你怎么处理图片的内容
for ( $i=0; $i < $iNumberOfPics ; $i++ ) {
echo $aPics[0][$i];
};
};
endwhile;
endif;
?>

但是,像你知道的,这样的话,如果一篇文章有多个图片的话,都统统会被显示出来。有时我们只需要显示一张,那这个代码就不符合我们的要求了,所以,让我们来小小地修改一下代码:

<?php
$soContent = $post->post_content;
$soImages = '~<img [^\>]*\ />~';
preg_match_all( $soImages, $soContent, $thePics );
$allPics = count($thePics[0]);
switch ( $allPics > 0 ) {
case $allPics = 1:
echo $thePics[0][0]; // 显示文章中的第一张图片
break; // 当图片数量有1个时,不再执行
default:
echo "这里应该显示图片,而不是sofish"; // 这里加入没图片时显示的默认图片
};
?>

像上面说明的,我们用switch语句,而不是if…else if…else这样,来获取我们的一张图片。当检查到一张的时候,代码不再运行。这样也省去了对服务器的请求。

UPDATE: 感谢来自herb同学的说法,用if…else语句

<?php
$soContent = $post->post_content;
$soImages = '~<img [^\>]*\ />~';
preg_match_all( $soImages, $soContent, $thePics );
$allPics = count($thePics[0]);
if( $allPics > 0 ){
echo $thePics[0][0];
}
else {
echo "这里应该显示图片,而不是sofish";
}
?>

这样的话,也OK,这里是不是说明会检测完所有的图片后,然后,再选择显示显示第一张/默认图片呢?如果是,这个代码的效率可能就没有上个好。但herb同学说:

你的那个switch有bug, 如果php的语法与C相同的话, 它应该只能显示仅有一张图片的缩略图。

不,这样的BUG没有出现,因为我自己测试过了。 估计是C与PHP有一些小不同。基于效率问题,我推荐你使用Switch语句的实现方法。你呢?如果测试出问题,可以用第二种方法。好吧,我只看了一点点的PHP,如果你有更好的方法,不妨提出来,让更多人知道。

74

  1. 2009.01.14 6:10 pm
    Shawn不是(visit): [回复]

    沙发,这个方法好!

  2. 2009.01.14 6:11 pm
    Yacca(visit): [回复]

    嗯…貌似解决了我未来皮里的一个问题.~~~继续加班,来顶顶~

  3. 2009.01.14 6:14 pm
    Shawn不是(visit): [回复]

    我觉得还有一个问题,如果图片过大,即使你规定了缩略图的尺寸,它的体积还是一如既往,这样会拖慢页面载入速度。

  4. 2009.01.14 6:33 pm
    sofish(visit): [回复]

    @Shawn不是: 但除此之外,并没有什么好方法,即使缓存,也需要第一次加载。

    @Yacca: 加班,囧。

  5. 2009.01.14 6:33 pm
    Leewings(visit): [回复]

    为什么有人是小朋友有人不是小朋友了?……
    and, 呵呵, 我 blog 暂时还不需要文章缩略图.. so, 没建议可以发啦~~

  6. 2009.01.14 6:41 pm
    herb(visit): [回复]

    hoho, 又见强大的正则表达式, 俺喜欢~

  7. 2009.01.14 6:52 pm
    sofish(visit): [回复]

    @Leewings: 遇到程序问题,哈哈。或许你有兴趣。

    @herb: 希望某天我也喜欢上。对正则表达式,现在还处于无语状态。以前看了一下PHP,看到正则表达式,无语,没再继续。

  8. 2009.01.14 6:59 pm
    Shawn不是(visit): [回复]

    其实,缩略图这一块我觉得还是手动 custom field 好点,flickr 和又拍都有那种生成大小图的功能,写文章的时候传图片顺便拷贝小图地址就好了。

  9. 2009.01.14 7:04 pm
    herb(visit): [回复]

    ..如果是只获取第一张图片的话,没有必要全部匹配,只需要用preg_match匹配首个就OK了…还有你的那个switch有bug, 如果php的语法与C相同的话, 它应该只能显示仅有一张图片的缩略图 .这样:
    if( $allPics > 0 )
    echo $thePics[0][0];
    else
    echo “这里应该显示图片,而不是sofish”;

  10. 2009.01.14 7:07 pm
    aunsen(visit): [回复]

    Shawn不是小朋友
    哈哈哈!

  11. 2009.01.14 7:24 pm
    laogao(visit): [回复]

    非常感谢了,在做主题的时候的确遇到了这个问题,而且一直用自定义字段来处理这个问题,现在好了,非常感谢了。转一下

  12. 2009.01.14 7:28 pm
    Jackycheung(visit): [回复]

    Sofish又有强大的动作了…

  13. 2009.01.14 7:34 pm
    辐射鱼(visit): [回复]

    上传的图片会自动创建缩略图,处理一下最大尺寸应该会更好。

  14. 2009.01.14 7:38 pm
    sofish(visit): [回复]

    @Shawn不是: 这样就不自动了。因为,这个世界上,“…” 很多。

    @herb: 哈哈。估计有一些不同吧。如果用preg_match的话,最终会显示“<”,而不是整个”"标签。

    if…else应该会检测所有图片,然后再显示第一张,或者显示默认图片。这个效率可能并没有switch高,因为break后就没有再进行了,要进行,也只是进行default了。

    BTW,总是感觉会编程真好。难道我是代码迷?

    @aunsen: 他假装不是小朋友而已。

    @laogao: 转,囧,我更欢迎链接。

    @Jackycheung: 没,在慢慢学习嘛。

    @辐射鱼: 嗯,这就看用的人怎么优化了,像btfish这么聪明的,当然没问题。

  15. 2009.01.14 7:41 pm
    fisio(visit): [回复]

    把首页列表搞得像鲜果热文一样。。。

  16. 2009.01.14 7:42 pm
    sofish(visit): [回复]

    @fisio: 嗯,有了这个,就完全可以了,哈哈。

  17. 2009.01.14 7:44 pm
    fisio(visit): [回复]

    @sofish: 神速啊

  18. 2009.01.14 7:53 pm
    leehow这个手还在痛的(visit): [回复]

    还是来打几个字…

  19. 2009.01.14 7:56 pm
    会律博客(visit): [回复]

    暂时用不到,先收藏着!

  20. 2009.01.14 8:04 pm
    herb(visit): [回复]

    @sofish: allpics并不是图片啊, 是匹配到的数目…如果匹配数目大于1, 则直接echo找到的内容.
    关于switch..和if…else, 后者效率更高, 因为switch..break和if…else其实全都是跳转.
    至于preg_match, 如果用这个函数, 后面要做相应的修改…有5个参数, 其中第三个可选参是返回匹配结果, 匹配一次的效率和匹配全部的效率那是没法比的.
    int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags [, int $offset ]]] )
    好吧, sofish的对象观念和形象思维太严重了, 有时候是好的, 有时候这不好

  21. 2009.01.14 8:05 pm
    laogao(visit): [回复]

    @sofish:原文链接和主站链接肯定有的,sofish回复的还挺快!

  22. 2009.01.14 8:42 pm
    welee(visit): [回复]

    1. 如果能检测若是没有图片就使用预设图片就更好了,毕竟可能有些文章没图片。
    2. if…else 和 switch…case 哪个有效率就不知道了,我是代码外行中的外行,貌似 sofish 那个比较有效率?
    3. Shawn 已经不是小朋友了,是大师,虽然他常谦虚地称自己为大湿,谦虚是好的,尤其是在这时期,呵呵!

  23. 2009.01.14 8:54 pm
    sofish(visit): [回复]

    @fisio: 这次慢点,hoho。

    @leehow这个手还在痛的: 我一直在等你多敲几个字,可以更新多一篇。

    @会律博客: 可能会生锈。

    @herb: 啊,看起来太复杂了。我等我慢慢学习,哈哈。太好了,我以为应该多注意你提到的这个。现在更多的是不懂,所以没得选择,所以,最优选择就更没法谈了。^,^…

    @laogao: 嘿嘿,我不是这个意思。

    @welee: 有的,switch中的default和if…else中的else就是。

  24. 2009.01.14 9:00 pm
    geuro(visit): [回复]

    太棒了,这正是我想要的,谢谢。

  25. 2009.01.14 9:23 pm
    会律博客(visit): [回复]

    看来问题是很严重的……

  26. 2009.01.14 9:54 pm
    adreaman(visit): [回复]

    呵呵,herb看到了问题,但是没看清楚其实sofish犯了三个错误。第一个就是herb说的那个switch语句。C和PHP在这种语句控制流的地方当然是一样的,按sofish的第一种写法的本意(如果他没有犯后两个错误),就是像herb说的那样将仅在只有一张图片的时候才会echo打印出语句来显示第一张图片。但是为什么问题没有发生呢?呵呵,因为sofish先把第一个case后的等于号写错了(其实就算等于号没写错这个逻辑也是不对的,case后面的数值应该和switch后的表达式的数值来匹配而不是在case后做判断),写成了赋值号,同时,switch语句后面的表达式又写成一个条件表达式(很明显按sofish的本意switch这里应该是$allPics而不是$allPics>0),这个表达式的结果是ture(也就是1),而case后的赋值运算结果也是其所赋的数值,也就是1,这样,不管有几张图片,只要大于0,这个case分之就肯定能走到,就能显示图片。就像herb写的那样直接判断完大于0之后直接echo $thePics[0][0] 就很正确。解释这个问题用了这么多的字,其实看一下语法就很容易理解问题在哪里了-http://www.w3school.com.cn/php/php_switch.asp。原来不懂PHP甚至基本的编程也能设计这样精美的主题。:)

  27. 2009.01.14 9:59 pm
    Dianso(visit): [回复]

    路过,只不过看不懂

  28. 2009.01.14 10:11 pm
    sofish(visit): [回复]

    @geuro: 随便拿去用。

    @adreaman: 哈哈,谢谢指出来。

    那switch那个会不会产生错误后果?

    BTW. 外观与程序在某种程度上是分开的。而wordpress提供了很多傻瓜式的函数。方便使用。只要CSS+xhtml+图片处理,完全可以把主题做好。

  29. 2009.01.14 10:31 pm
    左岸读书(visit): [回复]

    还得慢慢消化!

  30. 2009.01.14 10:42 pm
    herb(visit): [回复]

    @adreaman: 我发现了,呵呵~关系表达式不能用于switch,case表达式也只能是常数,但是这个并不是逻辑错误所以我没说
    @sofish: 这种分离而不耦合已经是目前系统设计的基本思想了, 比如软件换肤. 那个switch应该会给出一个error, 或许这个错误也会被php吞掉,嘿嘿,我不知道,php,不喜欢。
    然后如果照逻辑运行的话,它只能显示内容仅有一张图片的图片,囧,就是如此了。所以效率应该从内部实现来理解而不是字面意义,就比如学js,后期你可能更应该关注js的内部具体实现,学jquery,你可能更应该关注源码。学C++/C,你就要知道编译优化原理和微机原理,哈哈。good good study, day day up~

  31. 2009.01.14 11:00 pm
    sofish(visit): [回复]

    @左岸读书: 慢慢吃,哈哈。

    @herb: 太好了,好好学习,嘿嘿。多练习才知道。向herb学习。

    我要感慨,啊,世界上到处都是牛人。

  32. 2009.01.15 11:17 am
    林晨(visit): [回复]

    值得学习

  33. 2009.01.15 7:49 pm
    长河(visit): [回复]

    正在琢磨使用sofish的主题呢,太牛了都~

  34. 2009.01.15 10:17 pm
    花果山寨(visit): [回复]

    一直都想找这个功能,太好了!

  35. 2009.01.15 10:49 pm
    摩摩诘(visit): [回复]

    拿去升级DiggBox~

  36. 2009.01.16 12:27 pm
    BoBoSkY(visit): [回复]

    果然是有的小朋友有的不是小朋友有的是手还在疼小朋友。

  37. 2009.01.16 9:33 pm
    underone(visit): [回复]

    要是能直接写上yupoo规则就好了。。。就不但自动缩了图,还节省了带宽
    当然……这可能就是个插件了。。。

  38. 2009.01.16 10:11 pm
    underone(visit): [回复]

    $soImages = ‘~]*\ />~’;
    应该是
    $soImages = ‘~]*\ />~’;吧

  39. 2009.01.16 10:12 pm
    underone(visit): [回复]

    我刚才copy过来是中文引号好像》?

  40. 2009.01.16 10:27 pm
    underone(visit): [回复]

    恕我愚笨,自定义缩略图片的宽度或者高度,在哪里写?

  41. 2009.01.16 10:33 pm
    sofish(visit): [回复]

    @underone: copy好像有错误?

    你会加个套,定义图片的位置嘛。然后,可以,再定义这个套里面的图片的大小嘛。可以用overflow剪切,也可以用让他的宽度或者高度一定嘛。

    比较囧。

  42. 2009.01.16 11:22 pm
    胡戈戈(visit): [回复]

    php跟C的语法太相像,不过比C简单得多了

  43. 2009.01.16 11:33 pm
    sofish(visit): [回复]

    @胡戈戈: 你竟然都懂,强大!

  44. 2009.01.16 11:36 pm
    underone(visit): [回复]

    我个php白痴啊
    我还以为那个代码里有关于图片宽高的设定呢。。。
    我是可以加个套也可以写图大小。。。
    但是加了套以后岂不是不管有没有图都有这个套了么?怎么写这个判断呢?

  45. 2009.01.16 11:44 pm
    sofish(visit): [回复]

    @underone: 看到这一句没有?就是设计默认图片的:

    echo “这里应该显示图片,而不是sofish”; 改成 »

    echo’ <img class=”no_images” src=”" />’

    有图片和无图片,用CSS优先性就可以解决了,难道不是? 嘿嘿^,^…

  46. 2009.01.16 11:59 pm
    underone(visit): [回复]

    靠,我一下没转过弯来
    刚才我把 margin-right: 10px;的效果写在框在图片外边的div上了
    我就没想明白怎么在没有图片的情况下给这个效果取消了,所以没图的时候div是空的还是把字往右挤了10px
    效果都写图上就成了……笨死我

  47. 2009.01.17 12:04 am
    sofish(visit): [回复]

    @underone: 嘿嘿,可以理解是太晚了,精神不嘉。睡觉,晚安!

  48. 2009.01.17 12:06 am
    underone(visit): [回复]

    理论上还是。。。。不可理解,事实再次证明我是个新手……
    睡觉去

  49. 2009.01.17 6:53 am
    life97(visit): [回复]

    有没有办法随机获取自定义缩略图?

  50. 2009.01.19 2:10 pm
    Andor(visit): [回复]

    我的 php 比较菜,所以倾向于使用自定义字段来实现

  51. 2009.01.22 9:43 am
    老水兵(visit): [回复]

    很好,拿来主义,学习中

  52. 2009.02.03 10:23 am
    zhenfeng(visit): [回复]

    如果是个小图标,图片太小呢?

  53. 2009.02.03 10:25 am
    阵风(visit): [回复]

    最好加个判断,如果图片太小就继续搜索下一张图片而不是停止

  54. 2009.02.07 10:21 pm
    最喜欢美女的(visit): [回复]

    我想看看我叫什么小朋友,哈哈

  55. 2009.02.09 12:37 am
    Jinwen(visit): [回复]

    现在回过头来再看看这篇文章,研究下。

  56. 2009.02.14 12:25 pm
    橄榄皮(visit): [回复]

    很感谢可以解决部分的问题,但是我的文章中添加的图片是用nextgen,所以使用以上代码的时候不能出现图片,如果图片是用nextgen添加的,应该怎么办?

  57. 2009.02.20 6:28 pm
    店客(visit): [回复]

    不错。。。收藏了

  58. 2009.03.25 3:27 pm
    Yangtx(visit): [回复]

    好文收藏!
    BTW:评论美化的不错啊。

  59. 2009.03.29 11:31 pm
    RisingSun(visit): [回复]

    哈,我来了,关于你博客里面的文字+图片摘要是怎么实现的?有那些方法,初次接触这个博客程序,有点昏,呵呵

  60. 2009.04.09 6:40 pm
    adamghost(visit): [回复]

    不错 首收藏了哈:)

  61. 2009.04.18 11:48 am
    lnesuper(visit): [回复]

    太好了,我正需要解决这个问题,马上试试。 :D

  62. 2009.04.18 12:47 pm
    lnesuper(visit): [回复]

    那些代码在哪?

  63. 2009.05.08 6:19 pm
    狂舞网络(visit): [回复]

    呵呵,到此一游。

  64. 2009.05.10 10:39 pm
    布谷鸟(visit): [回复]

    既然是找第一张图片,就不要用preg_match_all,
    用preg_match就行了,找到就完事了。
    请看插件:http://niaolei.org.cn/posts/4012

  65. 2009.06.14 12:02 am
    bravo(visit): [回复]

    好多东西不懂的~

  66. 2009.06.17 5:25 pm
    girl(visit): [回复]

    我的留言没显示?

  67. 2009.06.28 12:33 am
    fantacyjcf(visit): [回复]

    如何控制缩略图的大小啊?我看了半天没看明白

  68. 2009.07.07 10:29 am
    girl(visit): [回复]

    加个css控制下酒可以了,我的就是这样!

  69. 2009.07.31 5:08 pm
    alex(visit): [回复]

    但这样的话如何设置图片显示的图片大小呢?否则文章中的图片有大有小,首页显示出来就不太整齐了。

  70. 2009.07.31 5:10 pm
    alex(visit): [回复]

    呵呵,写完就解决了,可以在CSS里面设置。

  71. 2009.09.16 9:23 pm
    guolicity(visit): [回复]

    有插件就好了,呵呵。

  72. 2009.10.07 5:27 pm
    帅哥(visit): [回复]

    不错不错

  73. 2009.10.15 11:48 am
    sukida(visit): [回复]

    这些 句子 写在哪个文件里面 ?

  74. 2009.12.08 4:44 pm
    AntiKorean(visit): [回复]

    一天访问这个页面几十次 :D

Additional comments powered by BackType