エロジンインデックス静的HTML化アップデートに

000010

WordPressを通さずに静的HTML化に向けて何度か試行錯誤を繰り返しここ半ヶ月でようやく形にできました。対象は個別記事ページ以外の全ての領域です。プラグインやAnalytics、セキュリティなどはワードプレスの規約上利用しなければならないので、記事ページはワードプレスを使うハイブリッド形式です。MySQLから独自のデータベースにアクセスし、用意したテンプレートHTMLから独自タグを用いてindex.htmlを生成しています。よってデータベースのアクセスが省かれ莫大なコスト削減と超高速化を実現しました、記事更新ごとにphpで更新(アクセスするだけ)を行う手間が増えましたが、大したことはありません。

これらの作業は全てPHPで施しましたが、Pythonだとその一連の作業(テンプレートからインデックス生成)に特化したDjungoというスクリプトが用意されていることに驚きました。将来的にはPythonでエロジン構成していきたいと思っている見通しです。

WordPressの重い理由

さくらサーバなどから初めてワードプレスをインストールして管理画面に入った方々が、まず最初に感じるのが他のブログサービス管理画面と比べて重いということです。月額500円程度のスペックではワードプレスを動かしているPHP、をWEBサーバ(Apache)と連携させているPHP-FPM(FastCGI)のメモリがまったく足りません。

重い理由は様々ですが、なんといっても一番の原因はデータベースを常時更新していることです。ワードプレスのテーマ編集からsingle.phpを覗くと

<?php if (have_posts()) :
    while (have_posts()) :
        the_post();
        <article>
        <h2>single_post_title();</h2>
    endwhile;/ 繰り返し処理終了
else :?>

こう記述されています。while()文は投稿した全ての記事分、繰り返し処理を行いますので、何万PVもあるサイトは何万回も繰り返し処理をしているハメになり、記事が多ければ多いほどガチガチに重くなります。よってWEBページごとにこういった動的プログラミングが記載されたサイトはカチ重です。PHPだけならまだしも、その繰り返しの中にある関数はデータベースにアクセスして取得しています。

それだけならまだしも、まだまだ重い理由は続きます。そもそもWEBサイトというのは.htmlで作られたテキストファイルをサーバのフォルダにポツンと置くだけで、表示されます。

index.html
1/5
0

このindex.htmlというファイル一つにアクセスすればそのままindex.htmlが表示されます、これが理想の形ですが、WordPressの場合はこうなっています。

index.html
2/5
0

このindex.phpにアクセスすればワードプレスで作成されたウェブサイトが表示されますが、その裏では色々なファイルにアクセスしています。

index.phpを覗くと、
WP index

3/5
0

require( dirname( __FILE__ ) . "/wp-blog-header.php");
と記載されています。requireとはファイルを呼び出すという意味で、別のPHPファイルwp-blog-header.phpにアクセスされます。

ではその、wp-blog-header.phpを覗くと今度は
require_once( dirname(__FILE__) . "/wp-load.php");
require_once( ABSPATH . WPINC . "/template-loader.php");
とまた別のPHPファイルを呼び出しています。

wp-load.phpはエラーなどの対策処理で、template-loader.phpは各テンプレートファイルにアクセスさせるための分岐処理を行っています。

と、このように何十個ものPHPファイルにアクセスしてようやく辿り着くのが、デザイン変更できるthemes/style/index.phpです。たった1回サイトにアクセスしただけで、この一連の流れを全て行いますので、ワードプレスは重いんです。

ぎゃぷっぎゃぷっクソワロタ ネット依存症のデブ
4/5
0

今回実装したこと

形式にもよりますが、ブログシステムは簡単なものでトップページに10~30個ほどの新着記事を降順で表示すればいいだけです。データベースには記事タイトル,記事URL,記事本文,カテゴリ,投稿日時などと列に一つの各行でまとめられているので、それを投稿日時順に取得すれば良いだけです。問題はセキュリティ対策の難しい管理画面です。なのでワードプレスの管理画面はそのまま流用して、html生成だけMySQLからPDOで独自に取得します。

$st = $pdo->prepare("
    SELECT * FROM wp_posts
    WHERE post_type='post'
    AND post_status='publish'
    ORDER BY post_date DESC
");

これで$stにはワードプレスの投稿記事全てが配列で入っています。これをHTML形式に修飾します。

$html = '';
foreach($st as $key=>$val) {
$html[] = "<article>"
<h2>{$val['post_title']}</h2>
"</article>"
}

これで$html[]には配列ごとに<article>タグが全記事分ぶち込まれました。当然このままではトップページが長くなってしまうので、表示する記事数分に分割します。この際とっても便利なPHP関数array_chunkを使用します。

$html_page = array_chunk($html, 30);

array_chunkの引数1番目に配列、2番めに何個に分割するかの数値を入れます。仮に$html配列に300個分のHTMLタグがある場合、それを30個に分割するので$html_pageには$html_page[9][29]となっています。よって

/ ページ分だけ繰り返す
foreach($html_page as $page=>$htmls) {

/ 予め用意したテンプレートファイルを文字列で読み込む
$temp = file_get_contents('template.html');

/ テンプレートファイルの記事ループ箇所に<$ARTICLE$>と入れておく
/ よってその独自タグにimplode(配列を全て文字列に結合)したタグをぶち込む
$temp = str_replace('<$ARTICLE$>', implode('', $htmls), $temp);

/ 現時点で$tempには1ページ分のHTMLタグが入っており、
/ それを文字列でファイルに書き込む
file_put_contents("page-{$page}.html", $temp);
}

これでpage-0.htmlからpage-29.htmlまでのHTMLが生成されました。記事を更新するごとに、上記で作ったPHPファイルを実行するだけで一気にすべて作成されます。こうしておくことで、いちいちデータベースにアクセスしなくても、静的ファイルを読み込み快適なWEBサーフィンができるようになります。

当然上記のようなトップページをページ別に分けるだけでなく、それをカテゴリやタグ、月別などもたくさん作っていかなければなりません。

PHP FILE_GET_CONTENTS
5/5
0
5/0
0

関連記事