用ChromePHP 探索 WordPress 佈景主題的運作機制


作者: | 2012/04/11 | 留言


chromePHP with WordPress

也許你用了一陣子 WordPress,也拿它來開發了許多專案,對於 WordPress 底層的運作有點概念,但一直沒有機會更清楚地理解TMD到底裡頭是發生了啥事,那麼這篇文章也許可為你的探險之路開啟一扇窗。因為專案需求,我用 ChromePHP 寫了一個 wordpress 的小plugin,主要是為了觀察WordPress佈景裡頭的每個頁面,到底暗中執行了哪些SQL,還有WP內建的那一堆常看到的global變數 (像是$wpdb, $post…) 又到底被放進了哪些東西。

ps.如果你只是拿WP來做一些小網站,未來也不太有機會拿 WordPress 做中大型的網站或開MU做深度應用,那就可以先別往下看了,因為內容我想應該不太適合你XD。

安裝後的效果是?

先來個看圖說故事好了,在安裝這個小plugin之前,必須先裝 chromePHP ,注意,這一切都只支援Google Chrome瀏覽器,裝完後你的Chrome右上角就會出現它的小圖示,記得開啟它:

chromePHP

安裝我自己寫的這個小plugin後 (或者把code寫在functions.php當然也行) ,開啟任何一頁 WordPress 網站頁面,打開 Chrome 的開發工具 (網頁上右鍵>檢查元素),點選”Console”頁籤,就可以發現這個頁面的底層做了啥事XD (一個普通的twenty-ten佈景首頁,就執行了38個大大小小的SQL queries,不過我的本機環境有開mu,所以應該會比較多一點):

chromePHP with WordPress

目前基本的就是查看有多少Loop,執行了多少次SQL,總時間及最耗時的SQL查詢也會列出。展開圖中的「SQL查詢詳情」,就可以看到所有在此頁面執行的SQL的明細:

wordpress sql list

再下一張是Loop裡的主角-WP_Query物件的內容,因為例子是在首頁,所以可見到 is_home 是 true:

wordpress loop sql

如果你看過twenty-ten佈景的原始碼,對WordPress Loop的運作也有基本的了解,你就會知道為啥這個頁面開出來會有兩個Loop,在此就不贅述。

然後,如果你進入的是單一頁面 (is_singular為true,就是像頁面(page),文章(post)等這種單一頁面),還可查看 $post 裡有啥鬼東西:

wordpress post variable

Plugin的實作方法

本想直接放下載連結,但目前還不夠滿意,所以先放上可呈現上述效果的code,有興趣的朋友可以慢慢tune成自己要的工具,或等我有空將plugin發佈出來。

首先你的 wp-config.php 需要加上:

[code lang=”php”]
// 讓WP將所有Queries存起來,請注意會影響效能,資料量愈多愈明顯,所以不建議用在正式環境。
define(‘SAVEQUERIES’, true);
[/code]

接著請去剛提到的 http://www.chromephp.com/,下載 ChromePHP.php,放進你目前所使用的佈景目錄裡的 lib目錄。(lib目錄自行建立即可)

再來就是要加入的code,以下預設為你將它加在 functions.php 先試玩:

[code lang=”php”]

// 把 ChromePHP.php 弄進來
add_action(‘init’, ‘__inc_chromephp’);
function __inc_chromephp(){
ob_start();
include ‘lib/ChromePhp.php’; //如果放在其他目錄記得自行修改~
}

// 每個loop開始時就印出log來瞧瞧
add_action(‘loop_start’, ‘__echo_loop_start’);
function __echo_loop_start($post){
ChromePhp::groupCollapsed(‘WP Loop 資訊’);
// 如果$post變數資料多,可能導致RESPONSE HEADER爆掉。
ChromePhp::log($post);
ChromePhp::groupEnd();
}

// 整頁的資料跑得差不多時,就輸出SQL記錄
add_action(‘wp_footer’, ‘__echo_SQL_queries_details’);
function __echo_SQL_queries_details()
{
global $wpdb, $post;

$query_table[] = array("SQL", "Execution Time", "Calling Function");
$expensive_query_time = 0;
$expensive_qnum = 0;
$expensive_query = "";
$total_time = 0;
$num = 1;

if (is_singular())
{
ChromePhp::groupCollapsed(‘$post 變數’);
ChromePhp::log($post);
ChromePhp::groupEnd();
}

ChromePhp::groupCollapsed(‘SQL 查詢詳情’);

foreach($wpdb->queries as $query)
{
$query_table[] = array($query[0], $query[1], $query[2]);

if($query[1] > $expensive_query_time)
{
$expensive_query_time = $query[1];
$expensive_query = $query[0];
$expensive_qnum = $num;
}
$total_time += $query[1];

ChromePhp::group(‘SQL查詢’.$num++);
ChromePhp::log($query[0]);
ChromePhp::log(‘(花費: ‘, round($query[1],5)." 秒)");
ChromePhp::groupEnd();
}
ChromePhp::groupEnd();
//ChromePhp::group($wpdb->queries); // 這個也很容易讓HEADER爆掉!

$total_queries = count($wpdb->queries);

ChromePhp::log(‘總共執行SQL查詢數目: ‘, $total_queries);
ChromePhp::log(‘總執行時間: ‘, round($total_time,5).’ 秒’);
ChromePhp::group(‘最耗時的查詢: (查詢’.$expensive_qnum.’)’);
ChromePhp::log($expensive_query);
ChromePhp::log(‘花費: ‘.round($expensive_query_time,5).’ 秒’);
ChromePhp::groupEnd();

ob_end_flush();
}

[/code]

就這樣,謝謝收看,記得按讚XD。


標籤:,

分類:,

本文作者是Audi Lu

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。

*

*

*

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料