标签: wordpress

让WordPress使用Redis缓存来进行加速

Redis是一个高级的key-value存储系统,类似memcached,所有内容都存在内存中,因此每秒钟可以超过10万次GET操作。

我下面提出的解决方案是在Redis中缓存所有输出的HTML 内容而无需再让WordPress重复执行页面脚本。这里使用Redis代替Varnish设置简单,而且可能更快。

安装 Redis

如果你使用的是 Debian 或者衍生的操作系统可使用如下命令安装 Redis:

apt-get install redis-server

或者阅读 安装指南

使用 Predis 作为 Redis 的 PHP 客户端

你需要一个客户端开发包以便 PHP 可以连接到 Redis 服务上。

这里我们推荐 Predis. 上传 predis.php 到 WordPress 的根目录。

前端缓存的PHP脚本

步骤1:在WordPress 的根目录创建新文件 index-with-redis.php ,内容如下:

<?php

// Change these two variables:

$seconds_of_caching = 60*60*24*7; // 7 days.

$ip_of_this_website = ‘204.62.14.112’;

/*

– This file is written by Jim Westergren, copyright all rights reserved.
– See more here: www.jimwestergren.com/wordpress-with-redis-as-a-frontend-cache/
– The code is free for everyone to use how they want but please mention my name and link to my article when writing about this.
– Change $ip_of_this_website to the IP of your website above.
– Add ?refresh=yes to the end of a URL to refresh it’s cache
– You can also enter the redis client via the command prompt with the command “redis-cli” and then remove all cache with the command “flushdb”.

*/

// Very necessary if you use Cloudfare:

if (isset($_SERVER[‘HTTP_CF_CONNECTING_IP’])) {
$_SERVER[‘REMOTE_ADDR’] = $_SERVER[‘HTTP_CF_CONNECTING_IP’];
}

// This is from WordPress:

define(‘WP_USE_THEMES’, true);

// Start the timer:

function getmicrotime($t) {
list($usec, $sec) = explode(” “,$t);
return ((float)$usec + (float)$sec);
}

$start = microtime();

// Initiate redis and the PHP client for redis:

include(“predis.php”);
$redis = new Predis\Client(”);

// few variables:

$current_page_url = “http://”.$_SERVER[‘HTTP_HOST’].$_SERVER[‘REQUEST_URI’];

$current_page_url = str_replace(‘?refresh=yes’, ”, $current_page_url);

$redis_key = md5($current_page_url);

// This first case is either manual refresh cache by adding ?refresh=yes after the URL or somebody posting a comment

if (isset($_GET[‘refresh’]) || substr($_SERVER[‘REQUEST_URI’], -12) == ‘?refresh=yes’ || ($_SERVER[‘HTTP_REFERER’] == $current_page_url && $_SERVER[‘REQUEST_URI’] != ‘/’ && $_SERVER[‘REMOTE_ADDR’] != $ip_of_this_website)) {
require(‘./wp-blog-header.php’);
$redis->del($redis_key);

// Second case: cache exist in redis, let’s display it

} else if ($redis->exists($redis_key)) {

$html_of_current_page = $redis->get($redis_key);

echo $html_of_current_page;

echo “<!– This is cache –>”;

// third: a normal visitor without cache. And do not cache a preview page from the wp-admin:

} else if ($_SERVER[‘REMOTE_ADDR’] != $ip_of_this_website && strstr($current_page_url, ‘preview=true’) == false) {
require(‘./wp-blog-header.php’);
$html_of_current_page = file_get_contents($current_page_url);
$redis->setex($redis_key, $seconds_of_caching, $html_of_current_page);
echo “<!– Cache has been set –>”;

// last case: the normal WordPress. Should only be called with file_get_contents:

} else {
require(‘./wp-blog-header.php’);
}

// Let’s display some page generation time (note: CloudFlare may strip out comments):

$end = microtime();
$t2 = (getmicrotime($end) – getmicrotime($start));
if ($_SERVER[‘REMOTE_ADDR’] != $ip_of_this_website) {
echo “<!– Cache system by Jim Westergren. Page generated in “.round($t2,5).” seconds. –>”;
}
?>

或者直接下载 index-with-redis.php

步骤2:将上述代码中的 IP 地址替换成你网站的 IP 地址

步骤3:在.htaccess 中将所有出现 index.php 的地方改为 index-with-redis.php ,如果你使用的是 Nginx 则修改 nginx.conf 中的 index.php 为 index-with-redis.php(并重载 Nginx : killall -s HUP nginx)。

性能测试

1.没有Redis 的情况下,平均首页执行1.614 秒,文章页0.174 秒(无任何缓存插件)

2.使用Redis 的情况下,平均页面执行时间0.00256秒

我已经在我的博客中使用了如上的方法进行加速很长时间了,一切运行良好。

其他建议

我的环境是Nginx + PHP-FPM + APC + Cloudflare + Redis. 安装在一个 nano VPS 中,无缓存插件。

请确认使用了gzip压缩,可加快访问速度。

访问 wp-admin

要访问 wp-admin 必须使用 /wp-admin/index.php 代替原来的 /wp-admin/.

原文:jimwestergren 编译:oschina

最近博客变慢的原因

我哩个擦,太郁闷了,不经意间发现博客的query到了1500-1600,这是什么概念,一个页面就要这么多的查询,随便一个cc估计就挂完了吧。怪不得有童鞋说我的博客速度太慢了,然后最近的当机提示邮件也比较多。打开一个页面要7-8秒。首先,先停掉了插件,不管用!又换了主题,还是依旧。可以判断wordpress没有问题。打开探针发现服务器才上线27天,肯定是中间挂了。最后只能看看是不是面板问题。最后找到原因,发现Memcached没有开。罪魁祸首啊,vps重启后,Memcached没有随机启动,导致博客变慢。不深究了,直接开启,速度恢复。开了之后一个页面只需零点几秒了,减少到60左右的query,汗!

wordpress评论邮件回复博客名带特殊符号修正

如果你的博客名称有特殊符号,就像我一样,有一个撇,那么就在回信的时候必须修正一下,不然会被转义,其实代码可以写的更好。
方法主要是添加htmlspecialchars()函数来防止转义,如果你看到回信中有转义的部分,可以给那一句直接加一个htmlspecialchars来处理。

比如我的会在标题出现错误,改动如下。

$subject = ‘您在 [' . get_option("blogname") . '] 的留言有了回复’;

改成

$subject = '您在['.html_entity_decode(get_option("blogname"), ENT_QUOTES).']的留言有了回复';

如果觉得麻烦,可以直接贴下面的评论邮件通知代码。

//评论回应邮件通知
function comment_mail_notify($comment_id) {
  $admin_notify = '1'; // admin 要不要收回复通知 ( '1'=要 ; '0'=不要 )
  $admin_email = get_bloginfo ('admin_email'); // $admin_email 可改为你指定的 e-mail.
  $comment = get_comment($comment_id);
  $comment_author_email = trim($comment->comment_author_email);
  $parent_id = $comment->comment_parent ? $comment->comment_parent : '';
  global $wpdb;
  if ($wpdb->query("Describe {$wpdb->comments} comment_mail_notify") == '')
    $wpdb->query("ALTER TABLE {$wpdb->comments} ADD COLUMN comment_mail_notify TINYINT NOT NULL DEFAULT 0;");
  if (($comment_author_email != $admin_email && isset($_POST['comment_mail_notify'])) || ($comment_author_email == $admin_email && $admin_notify == '1'))
    $wpdb->query("UPDATE {$wpdb->comments} SET comment_mail_notify='1' WHERE comment_ID='$comment_id'");
  $notify = $parent_id ? get_comment($parent_id)->comment_mail_notify : '0';
  $spam_confirmed = $comment->comment_approved;
  if ($parent_id != '' && $spam_confirmed != 'spam' && $notify == '1') {
    $wp_email = 'no-reply@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])); // e-mail 发出点, no-reply 可改为可用的 e-mail.
    $to = trim(get_comment($parent_id)->comment_author_email);
    $subject = '您在['.html_entity_decode(get_option("blogname"), ENT_QUOTES).']的留言有了回复';
    $message = '
    

' . trim(get_comment($parent_id)->comment_author) . ', 您好!

您曾在《' . get_the_title($comment->comment_post_ID) . '》的留言:
' . trim(get_comment($parent_id)->comment_content) . '

' . trim($comment->comment_author) . ' 给您的回应:
' . trim($comment->comment_content) . '

您可以点击 查看回应完整內容

欢迎您再度光临 ' . get_option('blogname') . '

(此邮件由系统自动发出,请勿回复.)

'; $from = "From: \"" . get_option('blogname') . "\" <$wp_email>"; $headers = "$from\nContent-Type: text/html; charset=" . get_option('blog_charset') . "\n"; wp_mail( $to, $subject, $message, $headers ); //echo 'mail to ', $to, '
' , $subject, $message; // for testing } }

给wordpress评论头像添加alt属性

一般评论是调用wp_list_comments()这个函数的,而它在调用get_avatar()列出评论者头像的时,并没有传递头像的alt属性参数。

开启方法如下

找到wp-include/comment-template.php文件打开,查找get_avatar,找到下面这行代码:


将其就改为:

comment_author" ); ?>

注意:修改的是wp核心文件,升级后会覆盖,需要重新再改。只适合于评论通过wp_list_comments()来显示的主题。

为wordpress添加谷歌百度ping

ping的作用是通知谷歌和百度有新的文章,马上来收录,比蜘蛛爬行要来的快。

默认的wordpress是没有ping百度和ping谷歌的,添加方法是

wp后台-设置-撰写-更新服务,添加如下两行:

http://ping.baidu.com/ping/RPC2

http://blogsearch.google.com/ping/RPC2

CommentToMail代码分析与调试

CommentToMail 是typecho的一个基于 PHPMailer 的评论通知插件, 本文讨论基于1.2.3

===========================
一. 使用PHPMailer 发送邮件:

PHPMailer 包含3个文件:

class.smtp.php 发送邮件用的,php socket 实现smtp协议
class.pop3.php 接受邮件用的
class.phpmailer.php PHPMailer类

有3种邮件发送模式: smtp, mail, sendmail.

从 class.phpmailer.php 文件中

359
/**
360
 * Sets Mailer to send message using SMTP.
361
 * @return void
362
 */
363
public function IsSMTP() {
364
  $this->Mailer = 'smtp';
365
}
366
 
367
/**
368
 * Sets Mailer to send message using PHP mail() function.
369
 * @return void
370
 */
371
public function IsMail() {
372
  $this->Mailer = 'mail';
373
}
374
 
375
/**
376
 * Sets Mailer to send message using the $Sendmail program.
377
 * @return void
378
 */
379
public function IsSendmail() {
380
  if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
381
    $this->Sendmail = '/var/qmail/bin/sendmail';
382
  }
383
  $this->Mailer = 'sendmail';
384
}
385
 
386
/**
387
 * Sets Mailer to send message using the qmail MTA.
388
 * @return void
389
 */
390
public function IsQmail() {
391
  if (stristr(ini_get('sendmail_path'), 'qmail')) {
392
    $this->Sendmail = '/var/qmail/bin/sendmail';
393
  }
394
  $this->Mailer = 'sendmail';
395
}

可知:

smtp 模式最为常用,直接配置好smtp服务器相关参数,就可以发送邮件了

mail 模式调用php自带mail函数来发送邮件,需要运行环境有邮件服务器.

sendmail 模式调用外部二进制程序(sendmail 或 qmail 或php.ini 中 sendmail_path指定)来发送邮件,据
/var/qmail/bin/sendmail 和 /var/qmail/bin/sendmail 可以推测,这个功能一般是在linux服务器上用的,
win服务器就不瞎琢磨了.

windows服务器,又不带邮件服务,综上,只有 smtp模式最靠谱了.

常用smtp邮件服务器:

website ssl host port user pass
mail.yeah.net false smtp.yeah.net 25 user=xxx@yeah.net(或xxx) ***
mail.163.com false smtp.163.com 25 user=xxx@163.com(或xxx) ***
exmail.qq.com false smtp.exmail.qq.com 25 user=xxx@yourdomain ***
(ssl的我没写,因为我测试没成功- -!!)

首先直接写一段代码调用PHPMailer发送邮件,以确定参数配置正确、”最小系统”正常工作.

本地测试正常,拿到服务器发现

1. PHP Warning: set_time_limit() has been disabled for security reasons,

这句意义不是很大,直接@或去掉.

2. SMTP Error: Could not connect to SMTP host.

发现是服务器禁用 fsockopen 所致, 将 class.smtp.php 中 @fsockopen 替换为 @pfscokopen (还好服务器没有禁用这个),发现可以正常发邮件了.

注: CommentToMail 1.2.3 附带的 class.smtp.php 里面就是@fsockopen,遇到此错误可以尝试此法.
还有 Plugin.php 中 SendMail() 中也用到了 fsockopen.

===========================
二. CommentToMail 代码分析:

①何时发送邮件

CommentToMail 插件 添加 finishComment 回调函数, CommentToMail_Plugin::toMail()
即 评论完成时 调用 toMail() 这个函数.

②如何发送邮件

toMail() 这个函数实现的功能就是 根据本条评论的信息 生成邮件信息(发送给谁,内容是什么,等)
并调用 SendMail() 来发送邮件, 之间数据通过临时文件(明白了cache目录的用处了)(gzdeflate,serialize) 和get来传递.

③SendMail() 做了什么?

它通过fsockopen GET 方式把包含邮件内容的临时文件的名字 传递给 /CommentToMail/send_mail.php

④send_mail.php 文件做了什么?

它通过替换 邮件模板 中关键词,产生邮件内容, 并创建 PHPMailer 实例,调用其 Send() 方法把邮件发送出去.

⑤PHPMailer

通过 socket 构造stmp协议,发出邮件.

===========================
三. CommentToMail 调试

因为评论完成时通过get方式调用 send_mail.php 执行, 所以客户端看不到 send_mail.php 的执行结果,不便调试,了解了其原理,可以 注释掉 send_mail.php 中 @unlink($file) 来保存临时文件以供分析和调试.

在typecho中完成一条评论,然后查看cache 目录内临时文件名称,

在 $smtp= unserialize(gzinflate(file_get_contents($file))); 后添加 print_r($smtp) 以查看临时文件内容
浏览器 访问 usr/plugins/CommentToMail/send_mail.php?mail=XXXX (其中XXXX=base64_encode($filename))

又发现服务器gzinflate被禁用- -!!.

于是干脆去掉gzdeflate,即

把 Plugin.php 中

    file_put_contents('./usr/plugins/CommentToMail/cache/'.$filename, gzdeflate(serialize($smtp))); 改为
    file_put_contents('./usr/plugins/CommentToMail/cache/'.$filename, serialize($smtp));

把 send_mail.php 中

    $smtp= unserialize(gzinflate(file_get_contents($file))); 改为
    $smtp= unserialize(file_get_contents($file));

再次在typecho中评论,产生新的临时文件,并在浏览器中访问 send_mail.php?mail=XXXX

发现可以正常读到 临时文件内容了,检查参数配置无误,邮件也发送成功了.

然后又发现当同时发送给被评论者和文章作者时, 邮件发送又不灵了, 先发的邮件总是能够成功,后法的一个总是失败.

调换 send_mail.php 中 向博主发信,向访客发信 的先后次序,仍是后一个失败.

开始想是不是因为服务器禁用 set_time_limit, 后面那个邮件发送超时了?

在send_mail.php 中各处添加时间检查,输出结果如下:

————————–

0.000: 将要载入phpmailer.
0.007: 载入phpmailer完毕.

0.009: 将要向访客发信
2012-04-04 18:51:02 向 yyyyy@163.com 发送邮件成功!
0.715: 向访客发信完毕

0.716: 将要向博主发信
SMTP Error: Could not authenticate.
2012-04-04 18:52:02 向 aaaaa@yurenchen.com 发送邮件错误: SMTP Error: Could not authenticate.
60.887: 向博主发信完毕

————————–

可以看到第一封邮件基本是秒发出去的,第二封消耗了60秒时间,并最终发送失败.

于是看了下PHPMailer 自带的smtp发送示例 test_db_smtp_basic.php , 大致流程是

new PHPMailer();

设置smtp 参数;

while(){
设置邮件参数;
Send();
ClearAddresses();
ClearAttachments();
}

再对比 send_mail.php, 发现

每次在send函数中创建 PHPMailer 实例, 并用$mail=NULL;销毁实例(插件作者大概也是用惯了JavaScript – -!!),

于是找找 PHPMailer 类的析构方法,发现没有.

于是把 $mail = new PHPMailer(); 拿到 send 函数外面,

并在 send 函数结尾添加

$mail->ClearAddresses();
$mail->ClearAttachments();

以清除接收邮箱地址 和 附件.

再次在浏览器访问 send_mail.php?mail=XXXX

输出结果:

——————————

0.000: 将要载入phpmailer.
0.008: 载入phpmailer完毕.

0.009: 将要向访客发信
2012-04-04 19:14:24 向 yyyyy@163.com 发送邮件成功!
0.588: 向访客发信完毕

0.588: 将要向博主发信
2012-04-04 19:14:24 向 aaaaa@yurenchen.com 发送邮件成功!
0.944: 向博主发信完毕

——————————-

直接秒发了,内牛满面啊 (T_T)

原来 send_mail.php 中这句 set_time_limit(0); 是这么悲剧来的啊

===========================
四. 关于CommentToMail 1.2.4

相对于1.2.3 的改动主要有以下几点,不过似乎引入的问题比解决的问题还多,但依然感谢带给我们CommentToMail插件的DEFE.

① 在 class.smtp.php 和 Plugin.php 中添加了 fsockopen 容错,

fsockopen 失败则尝试 pfsockopen,

再失败则尝试 stream_socket_client,

再失败 就要报错了:Failed to connect to server

② class.phpmailer.php中 IsSMTP 函数中 ‘smtp’ 修改成了 ‘SMTP’, 这一招似乎是江湖传言,

查看 class.phpmailer.php 代码:

571
// Choose the mailer and send through it
572
switch($this->Mailer) {
573
  case 'sendmail':
574
    return $this->SendmailSend($header, $body);
575
  case 'smtp':
576
    return $this->SmtpSend($header, $body);
577
  default:
578
    return $this->MailSend($header, $body);
579
}

产生的影响就是switch分支总是default,

就是PHPMailer总是用 mail 模式发信,这个在大部分服务器上应该都不能用.

③ send_mail.php 中 引入 class.phpmailer.php 的操作放到了 send 函数中,

不是一上来就载入class.phpmailer.php 文件,而是等到需要时才载入,来提高执行效率.

但是用的是 require 包含文件,当同时发送邮件给博主和被评论者时,两次调用send函数必然报错:

PHP Fatal error: Cannot redeclare class phpmailerException

④ 临时文件动态加密解密函数 mcode 疑似有问题, 没有仔细看加密算法,

直接去掉加密解密过程就可以用,加上则解密时失败.

仍然延续的问题:

① PHPMailer 实例化仍在 send 函数中进行, 导致发送第二封邮件时失败.

好吧,上传了调试后的代码: CommentToMail.rar

转载须注明出处: http://www.yurenchen.com/14.htm

wordpress高负载加速利器Varnish

由于有用wordpress做站的冲动,就看了一下wordpress对大数据高负载时候的解决方法,看起来wordpress对高负载唯一的办法,只能是上Varnish了,特此记录一下。
Varnish要配合使用WordPress Varnish插件,还要优化配置才能够达到最好的效果,由于没有相应的站测试,只能贴一些测试。

WordPress 缓存插件性能对比

虽然原生态的 WordPress 效率实在底下,但是 WordPress 提供了很多插件,国外服务器领域里也有很多开源的缓存软件,这几天在 Jerry的帮忙下,萝卜网的服务器用上了 Varnish 缓存加速,现在每天轻松应付流量,系统的负载也不再升高,呵呵。这里贴一篇国外高手的文章,一些主流的 WordPress 缓存插件,以及和用上 Varnish 的 WordPress 性能的对比。

原文:《WordPress Cache Plugin Benchmarks》
http://cd34.com/blog/scalability/wordpress-cache-plugin-benchmarks/

译文:《WordPress 缓存插件性能对比》,译文网址已经失效。

1、作者使用的插件下载以及版本号:
DB Cache (version 0.6)
DB Cache Reloaded (version 2.0.2)
W3 Total Cache (version 0.8.5.1)
WP Cache (version 2.1.2)
WP Super Cache (version 0.9.9)
WP Widget Cache (version 0.25.2)
WP File Cache(version 1.2.5)
WP Varnish (in beta)
WP Varnish ESI Widget (in beta)

2、生产环境:
Debian 3.1/Squeeze VPS
Linux Kernel 2.6.33
Single core of a Xen Virtualized Xeon X3220 (2.40ghz)
2gb RAM
CoW file is written on a Raid-10 System using 4x1tb 7200RPM Drives
Apache 2.2.14 mpm-prefork
PHP 5.3.1
WordPress 官方主题测试数据
Tests are performed from a Quadcore Xeon machine connected via 1000 Base T on the same switch and /24 as the VPS machine

3、测试使用的Bash代码:

#!/bin/shFETCHES=1000
PARALLEL=10/usr/sbin/apache2ctl stop
/etc/init.d/mysql restart
apache2ctl start
echo Sleeping
sleep 30
time ( \
echo First Run; \
ab -n $FETCHES -c $PARALLEL http://example.com/; \
echo Second Run; \
ab -n $FETCHES -c $PARALLEL http://example.com/; \
\
echo First Run; \
./http_load -parallel $PARALLEL -fetches $FETCHES wordpresstest; \
echo Second Run; \
./http_load -parallel $PARALLEL -fetches $FETCHES wordpresstest; \
)

4、测试以下 URL 的 http_load:
http://example.com/
http://example.com/2010/03/hello-world/
http://example.com/2008/09/layout-test/
http://example.com/2008/04/simple-gallery-test/
http://example.com/2007/12/category-name-clash/
http://example.com/2007/12/test-with-enclosures/
http://example.com/2007/11/block-quotes/
http://example.com/2007/11/many-categories/
http://example.com/2007/11/many-tags/
http://example.com/2007/11/tags-a-and-c/
http://example.com/2007/11/tags-b-and-c/
http://example.com/2007/11/tags-a-and-b/
http://example.com/2007/11/tag-c/
http://example.com/2007/11/tag-b/
http://example.com/2007/11/tag-a/
http://example.com/2007/09/tags-a-b-c/
http://example.com/2007/09/raw-html-code/
http://example.com/2007/09/simple-markup-test/
http://example.com/2007/09/embedded-video/
http://example.com/2007/09/contributor-post-approved/
http://example.com/2007/09/one-comment/
http://example.com/2007/09/no-comments/
http://example.com/2007/09/many-trackbacks/
http://example.com/2007/09/one-trackback/
http://example.com/2007/09/comment-test/
http://example.com/2007/09/a-post-with-multiple-pages/
http://example.com/2007/09/lorem-ipsum/
http://example.com/2007/09/cat-c/
http://example.com/2007/09/cat-b/
http://example.com/2007/09/cat-a/
http://example.com/2007/09/cats-a-and-c/

5、最终性能对比:
Sorted in Ascending order in terms of higher overall performance

Addon Apachebench Cold Start
Warm Start http_load Cold Start
Warm Start
Req/Second Time/Request 50% within x ms Fetches/Second Min First Response Avg First Response
Baseline 4.97 201.006 2004 15.1021 335.708 583.363
5.00 200.089 2000 15.1712 304.446 583.684
DB Cache 4.80 208.436 2087 15.1021 335.708 583.363
Cached all SQL queries 4.81 207.776 2091 15.1712 304.446 583.684
DB Cache 4.87 205.250 2035 14.1992 302.335 621.092
Out of Box config 4.94 202.624 2026 14.432 114.983 618.434
WP File Cache 4.95 201.890 2009 15.8869 158.597 549.176
4.99 200.211 2004 16.1758 99.728 544.107
DB Cache Reloaded 5.02 199.387 1983 15.0167 187.343 589.196
All SQL Queries Cached 5.03 200.089 1985 14.9233 150.145 586.443
DB Cache Reloaded 5.06 197.636 1968 14.9697 174.857 589.161
Out of Box config 5.08 196.980 1968 15.181 257.533 587.737
Widgetcache 6.667 149.903 1492 15.0264 245.332 602.039
6.72 148.734 1487 15.1887 299.65 598.017
W3 Total Cache 153.45 65.167 60 133.1898 8.916 85.7177
DB Cache off, Page Caching with Memcached 169.46 59.011 57 188.4 9.107 50.142
W3 Total Cache 173.49 57.639 52 108.898 7.668 86.4077
DB Cache off, Minify Cache with Memcached 189.76 52.698 48 203.522 8.122 43.8795
W3 Total Cache 171.34 58.364 50 203.718 8.097 44.1234
DB Cache using Memcached 190.01 52.269 48 206.187 8.186 42.4438
W3 Total Cache 175.29 57.048 48 87.423 7.515 107.973
Out of Box config 191.15 52.314 47 204.387 8.288 43.217
W3 Total Cache 175.29 57.047 51 204.557 8.199 42.9365
Database Cache using APC 191.19 52.304 48 200.612 8.11 44.6691
W3 Total Cache 114.02 87.703 49 114.393 8.206 82.0678
Database Cache Disabled 191.76 52.150 49 203.781 8.095 42.558
W3 Total Cache 175.80 56.884 51 107.842 7.281 87.2761
Database Cache Disabled, Minify Cache using APC 192.01 52.082 50 205.66 8.244 43.1231
W3 Total Cache 104.90 95.325 51 123.041 7.868 74.5887
Database Cache Disabled, Page Caching using APC 197.55 50.620 46 210.445 7.907 41.4102
WP Super Cache 336.88 2.968 16 15.1021 335.708 583.363
Out of Box config, Half On 391.59 2.554 16 15.1712 304.446 583.684
WP Cache 161.63 6.187 12 15.1021 335.708 583.363
482.29 20.735 11 15.1712 304.446 583.684
WP Super Cache 919.11 1.088 3 190.117 1.473 47.9367
Full on, Lockdown mode 965.69 1.036 3 975.979 1.455 9.67185
WP Super Cache 928.45 1.077 3 210.106 1.468 43.8167
Full on 970.45 1.030 3 969.256 1.488 9.78753
W3 Total Cache 1143.94 8.742 2 165.547 0.958 56.7702
Page Cache using Disk Enhanced 1222.16 8.182 3 1290.43 0.961 7.15632
W3 Total Cache 1153.50 8.669 3 165.725 0.916 56.5004
Page Caching – Disk Enhanced, Minify/Database using APC 1211.22 8.256 2 1305.94 0.948 6.97114
Varnish ESI 2304.18 0.434 4 349.351 0.221 28.1079
2243.33 0.44689 4 4312.78 0.152 2.09931
WP Varnish 1683.89 0.594 3 369.543 0.155 26.8906
3028.41 0.330 3 4318.48 0.148 2.15063
6、总结:
Varnish 用来做缓存,因为是内存级别的,读取速度相当之快,所有其他的缓存插件都是浮云,唯一能媲美的是启用了Page Caching – Disk (Enhanced), Minify Caching – Alternative PHP Cache (APC), Database Caching – Alternative PHP Cache (APC)的 W3 Total Cache 插件。

萝卜网目前使用的方案是 Nginx (82端口) + Varnish (反向监听81)+ Nginx (再反向监听80),当然也可以尝试 Apache (82)+ Varnish(81) + Nginx (80),具体怎么配置就不是本文的讨论范围了。

至于为什么不用 Apache (81) + Nginx (80),因为 Nginx 用来做反向代理+缓存加速的话,是在硬盘读取的,而Varnish直接读取内存,速度明显加快,唯一头疼的就是太损耗内存,服务器8G的内存瞬间跑满,看来得花钱加大内存了 T_T

英文版转载

WordPress Cache Plugin Benchmarks
A lot of time and effort goes into keeping a WordPress site alive when it starts to accumulate traffic. While not every site has the same goals, keeping a site responsive and online is the number one priority. When a surfer requests the page, it should load quickly and be responsive. Each addon handles caching a little differently and should be used in different cases.

For many sites, page caching will provide decent performance. Once your sites starts receiving comments, or people log in, many cache solutions cache too heavily or not enough. As many solutions as there are, it is obvious that WordPress underperforms in higher traffic situations.

The list of caching addons that we’re testing:

* DB Cache (version 0.6)
* DB Cache Reloaded (version 2.0.2)
* W3 Total Cache (version 0.8.5.1)
* WP Cache (version 2.1.2)
* WP Super Cache (version 0.9.9)
* WP Widget Cache (version 0.25.2)
* WP File Cache(version 1.2.5)
* WP Varnish (in beta)
* WP Varnish ESI Widget (in beta)

What are we testing?
* Frontpage hits
* httpload through a series of urls

We take two measurements. The cold start measurement is taken after any plugin cache has been cleared and Apache2 and MySQL have been restarted. A 30 second pause is inserted prior to starting the tests. We perform a frontpage hit 1000 times with 10 parallel connections. We then repeat that test after Apache2 and the caching solution have had time to cache that page. Afterwards, http_load requests a series of 30 URLs to simulate people surfing other pages. Between those two measurements, we should have a pretty good indicator of how well a site is going to perform in real life.

What does the Test Environment look like?
* Debian 3.1/Squeeze VPS
* Linux Kernel 2.6.33
* Single core of a Xen Virtualized Xeon X3220 (2.40ghz)
* 2gb RAM
* CoW file is written on a Raid-10 System using 4x1tb 7200RPM Drives
* Apache 2.2.14 mpm-prefork
* PHP 5.3.1
* WordPress Theme Test Data
* Tests are performed from a Quadcore Xeon machine connected via 1000 Base T on the same switch and /24 as the VPS machine

This setup is designed to replicate what most people might choose to host a reasonably popular wordpress site.

tl;dr Results
If you aren’t using Varnish in front of your web site, the clear winner is W3 Total Cache using Page Caching – Disk (Enhanced), Minify Caching – Alternative PHP Cache (APC), Database Caching – Alternative PHP Cache (APC).

If you can use Varnish, WP Varnish would be a very simple way to gain quite a bit of performance while maintaining interactivity. WP Varnish purges the cache when posts are made, allowing the site to be more dynamic and not suffer from the long cache delay before a page is updated.

W3 Total Cache has a number of options and sometimes settings can be quite detrimental to site performance. If you can’t use APC caching or Memcached for caching Database queries or Minification, turn both off. W3 Total Cache’s interface is overwhelming but the plugin author has indicated that he’ll be making a new ‘Wizard’ configuration menu in the next version along with Fragment Caching.

WP Super Cache isn’t too far behind and is also a reasonable alternative.

Either way, if you want your site to survive, you need to use a cache addon. Going from 2.5 requests per second to 800+ requests per second makes a considerable difference in the usability of your site for visitors. Logged in users and search engine bots still see uncached/live results, so, you don’t need to worry that your site won’t be indexed properly.

Results
Sorted in Ascending order in terms of higher overall performance

Addon Apachebench Cold Start
Warm Start http_load Cold Start
Warm Start
Req/Second Time/Request 50% within x ms Fetches/Second Min First Response Avg First Response
Baseline 4.97 201.006 2004 15.1021 335.708 583.363
5.00 200.089 2000 15.1712 304.446 583.684
DB Cache 4.80 208.436 2087 15.1021 335.708 583.363
Cached all SQL queries 4.81 207.776 2091 15.1712 304.446 583.684
DB Cache 4.87 205.250 2035 14.1992 302.335 621.092
Out of Box config 4.94 202.624 2026 14.432 114.983 618.434
WP File Cache 4.95 201.890 2009 15.8869 158.597 549.176
4.99 200.211 2004 16.1758 99.728 544.107
DB Cache Reloaded 5.02 199.387 1983 15.0167 187.343 589.196
All SQL Queries Cached 5.03 200.089 1985 14.9233 150.145 586.443
DB Cache Reloaded 5.06 197.636 1968 14.9697 174.857 589.161
Out of Box config 5.08 196.980 1968 15.181 257.533 587.737
Widgetcache 6.667 149.903 1492 15.0264 245.332 602.039
6.72 148.734 1487 15.1887 299.65 598.017
W3 Total Cache 153.45 65.167 60 133.1898 8.916 85.7177
DB Cache off, Page Caching with Memcached 169.46 59.011 57 188.4 9.107 50.142
W3 Total Cache 173.49 57.639 52 108.898 7.668 86.4077
DB Cache off, Minify Cache with Memcached 189.76 52.698 48 203.522 8.122 43.8795
W3 Total Cache 171.34 58.364 50 203.718 8.097 44.1234
DB Cache using Memcached 190.01 52.269 48 206.187 8.186 42.4438
W3 Total Cache 175.29 57.048 48 87.423 7.515 107.973
Out of Box config 191.15 52.314 47 204.387 8.288 43.217
W3 Total Cache 175.29 57.047 51 204.557 8.199 42.9365
Database Cache using APC 191.19 52.304 48 200.612 8.11 44.6691
W3 Total Cache 114.02 87.703 49 114.393 8.206 82.0678
Database Cache Disabled 191.76 52.150 49 203.781 8.095 42.558
W3 Total Cache 175.80 56.884 51 107.842 7.281 87.2761
Database Cache Disabled, Minify Cache using APC 192.01 52.082 50 205.66 8.244 43.1231
W3 Total Cache 104.90 95.325 51 123.041 7.868 74.5887
Database Cache Disabled, Page Caching using APC 197.55 50.620 46 210.445 7.907 41.4102
WP Super Cache 336.88 2.968 16 15.1021 335.708 583.363
Out of Box config, Half On 391.59 2.554 16 15.1712 304.446 583.684
WP Cache 161.63 6.187 12 15.1021 335.708 583.363
482.29 20.735 11 15.1712 304.446 583.684
WP Super Cache 919.11 1.088 3 190.117 1.473 47.9367
Full on, Lockdown mode 965.69 1.036 3 975.979 1.455 9.67185
WP Super Cache 928.45 1.077 3 210.106 1.468 43.8167
Full on 970.45 1.030 3 969.256 1.488 9.78753
W3 Total Cache 1143.94 8.742 2 165.547 0.958 56.7702
Page Cache using Disk Enhanced 1222.16 8.182 3 1290.43 0.961 7.15632
W3 Total Cache 1153.50 8.669 3 165.725 0.916 56.5004
Page Caching – Disk Enhanced, Minify/Database using APC 1211.22 8.256 2 1305.94 0.948 6.97114
Varnish ESI 2304.18 0.434 4 349.351 0.221 28.1079
2243.33 0.44689 4 4312.78 0.152 2.09931
WP Varnish 1683.89 0.594 3 369.543 0.155 26.8906
3028.41 0.330 3 4318.48 0.148 2.15063
Test Script

#!/bin/sh

FETCHES=1000
PARALLEL=10

/usr/sbin/apache2ctl stop
/etc/init.d/mysql restart
apache2ctl start
echo Sleeping
sleep 30
time ( \
echo First Run; \
ab -n $FETCHES -c $PARALLEL http://example.com/; \
echo Second Run; \
ab -n $FETCHES -c $PARALLEL http://example.com/; \
\
echo First Run; \
./http_load -parallel $PARALLEL -fetches $FETCHES wordpresstest; \
echo Second Run; \
./http_load -parallel $PARALLEL -fetches $FETCHES wordpresstest; \
)

URL File for http_load

http://example.com/
http://example.com/2010/03/hello-world/
http://example.com/2008/09/layout-test/
http://example.com/2008/04/simple-gallery-test/
http://example.com/2007/12/category-name-clash/
http://example.com/2007/12/test-with-enclosures/
http://example.com/2007/11/block-quotes/
http://example.com/2007/11/many-categories/
http://example.com/2007/11/many-tags/
http://example.com/2007/11/tags-a-and-c/
http://example.com/2007/11/tags-b-and-c/
http://example.com/2007/11/tags-a-and-b/
http://example.com/2007/11/tag-c/
http://example.com/2007/11/tag-b/
http://example.com/2007/11/tag-a/
http://example.com/2007/09/tags-a-b-c/
http://example.com/2007/09/raw-html-code/
http://example.com/2007/09/simple-markup-test/
http://example.com/2007/09/embedded-video/
http://example.com/2007/09/contributor-post-approved/
http://example.com/2007/09/one-comment/
http://example.com/2007/09/no-comments/
http://example.com/2007/09/many-trackbacks/
http://example.com/2007/09/one-trackback/
http://example.com/2007/09/comment-test/
http://example.com/2007/09/a-post-with-multiple-pages/
http://example.com/2007/09/lorem-ipsum/
http://example.com/2007/09/cat-c/
http://example.com/2007/09/cat-b/
http://example.com/2007/09/cat-a/
http://example.com/2007/09/cats-a-and-c/

大前端D4主题moper修改版

下载地址:https://moper.me/d4-moper.zip

更新记录
2012年10月18日 加入redirect_comment_link函数中的HTTP响应拆分漏洞修复。

使用方法:
1、修改function-opt.php文件里,面包屑导航中调用的feed地址,可在该文件中直接搜索http://t.moper.me/rss.xml并修改。
2、在网站根目录下建立avatar
3、上传大前端D4主题moper修改版到主题文件夹下
4、启用后修改D4主题设置,页面设置,菜单设置等。请自行建立单页的读者墙、留言板、随机文章、网站导航等。

本博启用的插件:
Configure SMTP
Google XML Sitemaps
My Visitors
无觅相关文章插件

注意:
1、Google XML Sitemaps插件已在底部增加了sitemap的链接
2、My Visitors主要是用于备份数据库,同时附带了文章计数的功能,由于和wp-posts的技术函数不一样,故修改了function-opt.php文件中如下部分:

//访问量
function dtheme_views(){
	if(function_exists('the_views')) the_views();
}

修改为

//访问量
function dtheme_views(){
	if(function_exists('post_views')) post_views('','');
}

如果你没有用My Visitors,请自行改回。

修改内容:
1、侧栏读者墙和下方文章列表显示错位
2、有可能在页面添加友情链接单页的时候,在第一行出现错误
3、增加首页翻页功能
4、分类页右侧侧边栏不显示
5、侧边栏搜索在内页失效
6、不显示搜索的关键词
7、防止内容里的代码跑出
8、搜索按钮错位
9、滚动公告栏功能,并修改为读取feed形式
10、关于加入微博图标等,移植自万戈(css已经加入,需要在你想要显示的页面插入文章时加入一段代码)

我的微博

11、导航栏下拉菜单
12、网站导航归档页

详细修改内容请查看《大前端D4主题bug及优化集锦

大前端D4主题bug及优化集锦

切换到了大前端D4主题,没想到还有这么多要折腾的,呵呵,都记录下来了,也形成了自己现在所用的版本,如果大家只想用我现在使用的版本,那就不必看下面的了,可以直接拿去使用,链接为大前端D4主题moper修改版下载

1、在根目录下建立avatar
使用大前端D4的时候会出现类似于如下的错误,原因是没有在根目录建立avatar文件夹。

Warning: copy(/avatar/b5bce33239d69ae1dd920fa5fb6c7b3b) [function.copy]: failed to open stream: No such file or directory in wp-content/themes/d4/inc/function-opt.php on line 526
Warning: filesize() [function.filesize]: stat failed for avatar/b5bce33239d69ae1dd920fa5fb6c7b3b in wp-content/themes/d4/inc/function-opt.php on line 528
Warning: copy(avatar/b5bce33239d69ae1dd920fa5fb6c7b3b) [function.copy]: failed to open stream: No such file or directory in wp-content/themes/d4/inc/function-opt.php on line 528
Warning: copy(avatar/b5bce33239d69ae1dd920fa5fb6c7b3b) [function.copy]: failed to open stream: No such file or directory in wp-content/themes/d4/inc/function-opt.php on line 526
Warning: filesize() [function.filesize]: stat failed for avatar/b5bce33239d69ae1dd920fa5fb6c7b3b in wp-content/themes/d4/inc/function-opt.php on line 528
Warning: copy(avatar/b5bce33239d69ae1dd920fa5fb6c7b3b) [function.copy]: failed to open stream: No such file or directory in wp-content/themes/d4/inc/function-opt.php on line 528

2、侧栏读者墙和下方文章列表显示错位

common.css中查找.sub-greater,增加overflow:hidden属性;查找.post-list,增加clear:both属性。

可能出现的问题:读者墙说明不显示,缩小的时候,侧边栏的热门标签悬挂出现

可能是因为,添加了overflow:hidden。
把common.css中的overflow:hidden属性去掉

3、有可能在页面添加友情链接单页的时候,在第一行出现错误。
修改links.php文件中的空格错误,用notepad2等工具修改文件空格模式为LF即可。

4、Math Comment Spam Protection把布局搞乱
想添加数字验证码插件,暂时未和D4主题融合,可考虑拖动插件。

5、增加首页翻页功能

修改主题的home.php文件,找到下面这段代码:



将第二行修改为下面的代码:


然后在home.php里面想要放翻页的地方加入


6、分类页右侧侧边栏不显示

网上流传的版本少了class定义,造成风格不对,以下是修正过的。
修改inc/function-opt.php文件中的分页函数,改成如下所示代码:

//分页功能
function dtheme_pagenav( $p = 4 ) {
global $wp_query, $paged;
if ( is_singular() ) return;
$max_page = $wp_query->max_num_pages;
if($max_page == 1 )echo '
'; //最新更新判断,更新2011-12-22 echo ''; } function p_link( $i, $title = '' ) { if ( $title == '' ) $title = "第 {$i} 页"; echo "{$i} "; }

7、侧边栏搜索在内页失效。

sidebar.php里面的搜索前的form改成如下。

8、不显示搜索的关键词

首先修改inc/function-opt.php文件中的面包屑导航,function dtheme_crumbs($s)带上参数,如果要加粗和红色,把

echo $tag_a.$s.' 的搜索结果';

改成:

echo $tag_a.''.$s.' 的搜索结果';

接下来修改,header.php里的

dtheme_crumbs();
改为
dtheme_crumbs($s);

9、防止内容里的代码跑出

在css/article.css中26行左右加上

.entry pre{overflow:auto;}

10、搜索按钮错位

在common.css文件里找到.btn样式,把里面的min-width宽度改成min-width:48px; 或者加上clear:both; 可解决按钮错位。
不能同时使用,本博使用了min-width:48px;

11、公告栏功能

第一步,打开主题文件common.css,找到“.crumbs-tip”将其替换为:

.crumbs-tip{overflow:hidden;position:absolute;width:400px; height:18px;top:5px;right:20px;border:#febe8f 1px solid;background-color:#fff8d9;border-radius:2px;color:#f60;padding:5px 12px}
.crumbs-tip ul{position:absolute;height:50px;}
.crumbs-tip ul li{overflow:hidden;list-style:none;float:left;width:450px;height:25px;margin-left:-5px;border-right:1px solid #ddd;}

第二步,打开主题文件function-opt.php,找到“//面包屑导航”

将如下代码:

if (get_option('d_onlytip_b') == 'Open') {
echo '
'.stripslashes(get_option('d_onlytip')).'
'; };

替换为:

if (get_option('d_onlytip_b') == 'Open') {
		echo '
  • 欢迎各位同学在本博客留言,提建议,有访必回!
  • 博客遭受评论机器人攻击,后台太卡了,只好用数据库删了所有待审评论,导致有些同学的待审评论也被删除了,在
  • 公告内容
'; };

代码中的中文即为公告内容,为了防止文章标题太长后和公告栏打架,所以公告栏宽度有所限制,公告内容最多可写45个字,编辑的时候注意要把握好字数,另外,以后公告内容就在functions-opt.php这个文件中手动输入吧,懒得集成到后台主题选项处输入了,麻烦!

第三步,也是最重要的一步了,把如下代码添加到common.js文件中:

	// 文字滚动
    (function($){
    $.fn.extend({
    Scroll:function(opt,callback){
    if(!opt) var opt={};
    var _this=this.eq(0).find("ul:first");
    var        lineH=_this.find("li:first").height(),
    line=opt.line?parseInt(opt.line,10):parseInt(this.height()/lineH,10),
    speed=opt.speed?parseInt(opt.speed,10):7000, //卷动速度,数值越大,速度越慢(毫秒)
    timer=opt.timer?parseInt(opt.timer,10):7000; //滚动的时间间隔(毫秒)
    if(line==0) line=1;
    var upHeight=0-line*lineH;
    scrollUp=function(){
    _this.animate({
    marginTop:upHeight
    },speed,function(){
    for(i=1;i<=line;i++){
    _this.find("li:first").appendTo(_this);
    }
    _this.css({marginTop:0});
    });
    }
    _this.hover(function(){
    clearInterval(timerID);
    },function(){
    timerID=setInterval("scrollUp()",timer);
    }).mouseout();
    }
    })
    })(jQuery);
    $(document).ready(function(){
    $(".crumbs-tip").Scroll({line:1,speed:1000,timer:5000});//修改此数字调整滚动时间
    });

moper修改:
调用了一个微博的feed,采用的是万戈工具条的代码。
即在第二步的时候,在主题文件function-opt.php,找到“//面包屑导航”改变如下代码。

	if (get_option('d_onlytip_b') == 'Open') {
    function wgToolBar_notice( $num = 5){
        date_default_timezone_set('PRC');
        require_once (ABSPATH . WPINC . '/class-feed.php');
        $feed = new SimplePie();
        $feed->set_feed_url( 'http://t.moper.me/rss.xml' );    //RSS 地址
        $feed->set_file_class('WP_SimplePie_File');
        $feed->set_cache_duration( 6000 );    //缓存时间,600秒
        $feed->init();
        $feed->handle_content_type();
        $items = $feed->get_items( 0, $num );
        echo '
'; echo ''; echo '
'; } wgToolBar_notice( 5 ); //输出数量 };

12、关于加入微博图标等,移植自万戈
css如下:

#wgSNS li{list-style-type:none;}
#wgSNS li a{background:url(../img/sns_icon.png) no-repeat;display:block;text-indent:28px;}
#wgSNS #tb_fav{background-position:0 0;}
#wgSNS #tb_mail{background-position:0 -25px;}
#wgSNS #tb_rss{background-position:0 -50px;}
#wgSNS #tb_sohu{background-position:0 -75px;}
#wgSNS #tb_twitter{background-position:0 -100px;}
#wgSNS #tb_sina{background-position:0 -125px;}
#wgSNS #tb_net163{background-position:0 -150px;}
#wgSNS #tb_baidu{background-position:0 -175px;}
#wgSNS #tb_douban{background-position:0 -200px;}
#wgSNS #tb_facebook{background-position:0 -225px;}
#wgSNS #tb_tencent{background-position:0 -250px;}
#wgSNS #tb_digu{background-position:0 -275px;}

编辑关于页面,加入如下html

我的微博

13、大前端D4主题导航栏下拉菜单实现方法

第一步:打开后台—外观—菜单—在右侧新建菜单—首页(名字随便起),然后将左侧的页面和分类目录选中之后添加至菜单,并进行拖动
第二步只需在主题文件/css/common.css中添加如下css代码即可:

.nav li li {height:30px;float:left;}   
.nav li li a {line-height:30px !important;}   
.nav li ul {position: absolute;left: -999em;width: 150px;margin: 0;border-width: 1px 1px 0px;z-index: 999;}   
.nav  li ul li {border-top: 1px solid #484848;border-bottom: 1px solid #0C0C0C;border-right: none;border-left: none;}   
.nav  li ul li a {background: #484848;width: 100px;height:30px;color: #fff !important;  font-weight: normal;opacity: .80;filter: alpha(opacity=80); text-shadow: 0px 1px 0px #000 !important;}   
.nav li ul li a:hover {text-shadow: 0px 1px 0px #fff !important;}   
.nav  li ul li a:hover {background: #333333;color: #fff !important;text-shadow: 0px 1px 0px #000 !important;text-decoration: none;}   
.nav  li ul ul {margin: -31px 0px 0px 150px;}   
.nav  li ul ul li a {}   
.nav  li ul li ul li a {}   
.nav  li:hover,.nav  li.hover {position: static;}   
.nav  li:hover ul ul,.nav  li:hover ul ul ul,.nav  li:hover ul ul ul ul {left: -999em;}   
.nav  li:hover ul, .nav  li li:hover ul,.nav  li li li:hover ul,.nav  li li li li:hover ul {left: auto;}  

14、网站导航归档页
在网站导航里面加入了归档页,参照的是zww.me的代码。

特点:
1. 这个存档函数会在数据库生成一个表 SHe_archives_25216,用来保存在文章新发表/删除文章时生成的 html,这主要是加快访问速度,不用每次都要查询数据库生成归档。
2. 显示每月文章数
3. 显示每篇文章的评论数

说明:我另外加了jQuery滑动效果,jQ代码来自上面提到的 hzlzh,稍微修改。

下面是详细步骤

1. 把下面的 archives_list_SHe 函数代码扔进主题的 functions.php 里面 (2010.7.23 edit)

function archives_list_SHe() {
     global $wpdb,$month;
     $lastpost = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE post_date <'" . current_time('mysql') . "' AND post_status='publish' AND post_type='post' AND post_password='' ORDER BY post_date DESC LIMIT 1");
     $output = get_option('SHe_archives_'.$lastpost);
     if(empty($output)){
         $output = '';
         $wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE 'SHe_archives_%'");
         $q = "SELECT DISTINCT YEAR(post_date) AS year, MONTH(post_date) AS month, count(ID) as posts FROM $wpdb->posts p WHERE post_date <'" . current_time('mysql') . "' AND post_status='publish' AND post_type='post' AND post_password='' GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC";
         $monthresults = $wpdb->get_results($q);
         if ($monthresults) {
             foreach ($monthresults as $monthresult) {
             $thismonth    = zeroise($monthresult->month, 2);
             $thisyear    = $monthresult->year;
             $q = "SELECT ID, post_date, post_title, comment_count FROM $wpdb->posts p WHERE post_date LIKE '$thisyear-$thismonth-%' AND post_date AND post_status='publish' AND post_type='post' AND post_password='' ORDER BY post_date DESC";
             $postresults = $wpdb->get_results($q);
             if ($postresults) {
                 $text = sprintf('%s %d', $month[zeroise($monthresult->month,2)], $monthresult->year);
                 $postcount = count($postresults);
                 $output .= '' . "\n";
             }
         update_option('SHe_archives_'.$lastpost,$output);
         }else{
             $output = '
Sorry, no posts matched your criteria.
' . "\n"; } } echo $output; }

2. 复制一份主题的 page.php 更名为 archives.php,然后在最顶端加入:


再然后找到类似 ,在其下面加入如下代码(2010.7.21 edit)

全部展开/收缩

进wp后台添加一新页面,在右侧栏模板选择 archives

3. 如果你的主题本身加载了 jQuery 库,那么继续把下面的 jQ 代码加上去,就会有滑动伸缩效果了(2010.7.23 edit)

/* 存档页面 jQ伸缩 */
 $('#expand_collapse,.archives-yearmonth').css({cursor:"s-resize"});
 $('#archives ul li ul.archives-monthlisting').hide();
 $('#archives ul li ul.archives-monthlisting:first').show();
 $('#archives ul li span.archives-yearmonth').click(function(){$(this).next().slideToggle('fast');return false;});
 //以下下是全局的操作
 $('#expand_collapse').toggle(
 function(){
 $('#archives ul li ul.archives-monthlisting').slideDown('fast');
 },
 function(){
 $('#archives ul li ul.archives-monthlisting').slideUp('fast');
 });

css 样式可以通过 #archive 来定义

moper修改,当时实现时好像jquery代码无法生效,后经直接查看zww的代码复制过来后生效,不知道是什么情况,大家如果出现这样的错误,可以直接查看本博的jquery代码。

以下是在网上找出的各种bug修正和优化方法,没有在moper修改版中实现。

1、ipad下css错位
没有ipad,无法测试,网上的那位朋友也没有直接给出方法,不过大家可以去看他的css。

2、主页上顶端的两个大的推荐栏,话说我一篇文章只有一个按钮怎么办?
这个代码需要修改文件inc/home-header.php.也就是在原来的按钮外面加一个判断,如果第二个按钮显示的标签设置为“non”的时候,按钮将不显示。






3、列表用ul

确的列表应该是这样的


大前端用成了


经查看,发现只有带缩略图的那些是上面的这种情况。修改后会造成css错误,暂未修改。

4、风格函数包重复

这个一般来说是没什么影响的,我那天遇到的问题是我评论了一个评论,然后就调用风格中发送邮件的函数。但是这个函数被定义了两次,所以出错。这个就只需要在函数外面加一个条件判断function_exists就行了,就能够防止重复定义了。

5、d4友情链接消失

首先进入 链接分类目录 然后将鼠标放在 你的分类目录名称上,在浏览器的左下方就会出现一个链接地址如:

https://moper.me/wp-admin/edit-tags.php?action=edit&taxonomy=link_category&tag_ID=10&post_type=post

我们看这个链接中的 tag_ID=10 我们记住这个ID号,然后在D4主题的根目录下找到Sidebar.php这个文件并打开,找到下面的代码(63行处)


将上面代码中的

category=2
改成tag_ID=10中的ID代表数字10

category=10
改好后保存,在去看看我们的友情链接是不是已经显示出来了!!!

6、大前端D4主题加图文幻灯

wordpress主题中知更鸟的HotNews pro主题很多朋友都用过,这个主题是一个非常经典的主题,其中有很多值得我们学习i的东西,Maxling.com今天把HotNews pro主题首页的图文幻灯提取出来加入到了我现在用的大前端D4主题中,顺便分享出来记录一下调用方法,说不定以后修改主题的时候用得上。

这个图文幻灯的效果大家可以在本站或去知更鸟的网站去看,幻灯是自动调用后台的5篇最新置顶文章(含文章中的第一张图片)。

注意!大家在参照本文修改之前记得先备份一下主题。(我这是以大前端D4主题为例,其他主题大同小异)

1) 下载幻灯所需的JS文件,图片和slider.php 并将下载的所需文件放到你想加幻灯的主题目录里【 slider of hotnews

2) 在主题的footer.php中添加js的调用代码

找到


在其下面加入


3) 在functions.php文件的最后一个 ?> 标志前添加如下代码

/*Catch first image (post-thumbnail fallback) */
 function catch_first_image() {
  global $post, $posts;
  $first_img = '';
  ob_start();
  ob_end_clean();
  $output = preg_match_all('//i', $post->post_content, $matches);
  $first_img = $matches [1] [0];

  if(empty($first_img)){ //Defines a default image
		$random = mt_rand(1, 22);
		echo get_bloginfo ( 'stylesheet_directory' );
		echo '/img/default-image.jpg';
  }
  return $first_img;
 }
 ;

//标题文字截断
function cut_str($src_str,$cut_length)
{
    $return_str='';
    $i=0;
    $n=0;
    $str_length=strlen($src_str);
    while (($n<$cut_length) && ($i<=$str_length))
    {
        $tmp_str=substr($src_str,$i,1);
        $ascnum=ord($tmp_str);
        if ($ascnum>=224)
        {
            $return_str=$return_str.substr($src_str,$i,3);
            $i=$i+3;
            $n=$n+2;
        }
        elseif ($ascnum>=192)
        {
            $return_str=$return_str.substr($src_str,$i,2);
            $i=$i+2;
            $n=$n+2;
        }
        elseif ($ascnum>=65 && $ascnum<=90)
        {
            $return_str=$return_str.substr($src_str,$i,1);
            $i=$i+1;
            $n=$n+2;
        }
        else
        {
            $return_str=$return_str.substr($src_str,$i,1);
            $i=$i+1;
            $n=$n+1;
        }
    }
    if ($i<$str_length)
    {
        $return_str = $return_str . '';
    }
    if (get_post_status() == 'private')
    {
        $return_str = $return_str . '(private)';
    }
    return $return_str;
}
;

小贴士:以上代码的13行中有一句 /img/default-image.jpg ,在文章没有图片时调用的默认图片,请自己制作一张名为default-image.jpg ,放置到主题下的img目录里。

4) 在common.css中添加如下CSS样式代码

/** slideshow **/
#slideshow {position:relative; background:#fff; width:672px; height:248px; padding:10px; border:1px solid #ccc;}
.slideshow {width:672px;height:248px;overflow:hidden;}
.featured_post{line-height:24px; width:670px;height:248px;overflow:hidden;}
.slider_image,.slider_image img {float: left;width:360px;height:248px;}
.slider_post {float:right;width:280px;padding-right:10px;}
.slider_post p{font-size:13px;text-indent:2em;margin-top:5px;}
#slider_nav  {position:absolute;display:block;width:200px;height:34px;z-index:999;margin:210px 0 0 210px;}
#slider_nav a {background:url(img/slider_nav.png);display:block;float:left;font-size:12px;font-weight:bold;
                  margin-right:5px;padding:0 8px 0 8px;color:#ebebeb;}
div#slider_nav a.activeSlide { color:#f99356;}
#featured_tag {background:url(img/featured.png);width:21px;height:79px;left:0px;position:absolute;top:20px;z-index:999;}
#tag_c {background:url(img/tag_c.png);width:21px;height:79px;right:0px;position:absolute;top:170px;z-index:10;}
.news {background:url(img/news.png);position:absolute;width:51px;height:51px;right:-3px;top:-3px;z-index:10;}

注:请根据你存放背景小图片的位置来修改代码中的图片路径

5) 在需要调用的地方(一般为首页index.php)添加以下代码即可


在实际调用中,你可能要修改css代码中的宽高参数,以及 slider.php文件中 标题和内容的截取字数,请自行调整。


7、加入标签云页
有这个想法,大家也可以用插件或者代码来实现,由于本博还没有那么迫切的需要,So……暂时搁置了。

8、为文章中的图片加上alt
发现读者墙头像和文章内页的图片没有alt信息。暂时没有解决。

如大家还发现了什么错误,或者有什么好的建议,可以留言一起探讨哦。

参照了以下很多人的总结,如果有未加上链接的,请留言告知,多谢大家哈~

大前端D4主题分类目录页相关问题总结
http://www.dreamxyt.net/518.html
WordPress大前端D4主题实现动态公告栏的方法
http://www.dreamxyt.net/526.html
为大前端的D4主题增加首页翻页功能
http://www.letuknowit.com/archives/daqianduan-d4-wordpress
大前端D4主题加图文幻灯
http://maxling.net/da-qian-duan-d4-zhu-ti-jia-tu-wen-huan-deng.html
大前端D4主题导航栏下拉菜单实现方法
http://www.dreamxyt.net/478.html
D4主题优化版正式放出下载
http://www.dreamxyt.net/571.html
代码实现WordPress归档页面模板
http://zww.me/archives/25209
D4主题Bug处理
http://www.hicoogle.com/bug-handling-d4-topic.html
大前端D4主题的一些bug修复
http://www.zoudongyan.com/blog/181/large-number-of-front-end-bug-fixes-d4-theme

wordpress站点自动给图片添加alt属性代码

经过百度的SEO检测发现,图片建议加入alt属性。万能的wordpress额,一搜索就有相应的答案了,记录如下。

function photo_alt($c) {
global $post;//全局量
$title = $post->post_title;//文章标题
$s = array('/src="(.+?.(jpg|bmp|png|jepg|gif))"/i' => 'src="$1" alt="'.$title.'"');
foreach($s as $p => $r){
$c = preg_replace($p,$r,$c);
}
return $c;
}
add_filter( 'the_content', 'photo_alt' );