こんにちは。
キャスレーコンサルティング TS(テクニカルサービス)部の松永です。

弊社では、業務の一部でWordPress(以下WP)を使っています。
WPは、中小企業のウェブページの管理でもっとも使われている
CMS(content management system)です。

世界中で8700万サイト、日本国内で500万サイトが稼働しています。
もともとブログ管理ツールとして誕生したWPですが、
近年はウェブサイト、ウェブアプリの制作にも使われています。

近年弊社では、ウェブアプリケーションを併用した、
規模がやや大きなサイト作成のご依頼も多くなっています。
そのような中で、WPのシステムファイルの構成を調査する機会があります。

今回は、このWPのファイル構成の調査の方法についてです。
そして、標準的なWPのページの読み込み動作でどのようなファイルが読み込まれ、
読み込まれた内容を出力されるか
を見てみたいと思います。

 

どのように出力するか?

PHPには、読み込みを標準入出力に記録する”echo”があります。
このechoを、WPのすべてのファイルの最初と最後につけることができれば、
読み込んだファイルを、視覚的に確認することができます。

画面は汚せないので、ブラウザコンソールに出力します。
最初と最後に出力することによって、入れ子の構造がわかります。

また、出力時の日時をUNIXタイムで記録すれば、読み込みの遅い箇所の特定が可能になります。

ではさっそくはじめましょう。

注意事項

・変更ファイル数が多いため、一部を人力で復旧するのは不可能です。
 ご自分のWPフォルダで作業される場合は自己責任でお願いし、必ずバックアップを取ってください。

・バージョンアップ時に、書き換えられる可能性があります。更新に注意してください。

・1900本のファイルを書き換えるスクリプトを作成し、
 そのファイルへのアクセスを持って、書き換えを始めます。

・ファイルアクセスを1度行うだけで、出力されます。
 2回押すと出力が2倍になるので、必ず1回だけ押してください。

環境

Ver4.9.7

themeは標準的デフォルトテンプレート

ファイル数は1900本

実行コード

以下のPHPファイルを作成し、WPのトップフォルダと同階層に配置します。
config.php、wp-contentフォルダなどがあるところです。
権限によっては、WPの構成ファイル全体へのアクセス権の変更が必要です。
そして、ここに一度だけアクセスを行います。以下の例では、test.phpです。

<?php
$dir = dirname(__FILE__)."/";


$result = list_files($dir);
foreach ($result as &$value) {
if(preg_match("/\.php/",$value)==1){

echo $value."
" ;

 $str="<?php \necho'<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3Econsole.log(%22.'%20%22%20'.%22'.microtime().'-TopDown---%22.%24value.%22%20%22.'%20%22%20'.%22)%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />';?>\n";
   $contents = file_get_contents($value);
   $contents = $str . "\n" . $contents;
   $re = file_put_contents($value, $contents);


   $a = fopen($value, "a");
  @fwrite($a, "\necho '<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3Econsole.log(%22.'%20%22%20'.%22'.microtime().'-BottomUp--%22.%24value.%22%20%22.'%20%22%20'.%22)%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />';\n");
  fclose($a);
}
}

function list_files($dir){
    $list = array();
    $files = scandir($dir);
    foreach($files as $file){
        if($file == '.' || $file == '..'){
            continue;
        } else if (is_file($dir . $file)){
            $list[] = $dir . $file;
        } else if( is_dir($dir . $file) ) {
           // $list[] = $dir;
            $list = array_merge($list, list_files($dir . $file . DIRECTORY_SEPARATOR));
        }
    //  echo   $file."
";
    }
    return $list;
}

修正が必要です1

PHPファイルをJavaScriptとして読み込む個所があるので、以下を修正してください。

wp-admin/adumin-header.phpの128行目
do_action( ‘admin_print_scripts’ );をコメントアウト
wp-admin/adumin-footer.php 92行目
do_action( ‘admin_print_footer_scripts’ );をコメントアウト

これにより、functions.phpで追加したJavascriptが
適切に挿入されなくなる場合がありますので、問題がある場合は元に戻してください。

修正が必要です2

画面にecho”と表示され、コンソールにユニックスタイムが表示されないファイルがいくつかあります。
これは、ファイルの中にPHPの閉じタグがあるケースで起こります。
気になる場合は、該当ファイルに開始タグをつけてください。

出力概要

ブラウザコンソールに、以下の出力が行われます。
下の例では、通常のトップページの読み込みを行っています。

 

 

出力結果の見方

  • 遅いファイルの調査では、ページ読込完了時のUNIX時間のマイクロ秒を見てください。
  • ファイル読込開始順を調べる場合、TOP-DOWNと書かれた出力を見てください。
  • ファイル読込完了順に調べる場合、BOTTOM-UPと書かれた出力を見てください。
  • 両方見ると、読込開始し出力完了した結果を推測することができます。
    HTMLのような入れ子構造となっています。

例えば、トップページを表示するとTOP-DOWN index.phpが出力され、
最後に、BOTTOM-UP index.phpが出力されます。

これは、このindex.phpファイルを一つ読み込む間に、
ロードに必要な全ファイルを読み込んだことを示します。

同様の推測で、ファイルの中身が以下のように想像できます。
動作の詳しい解析については、別の機会にします。

結論

私の環境で行った調査では、少し驚いた結果でした。以下にそれを纏めます。

 

WPはコンテンツをまとめた中核フォルダであるwp-contentを失っても
管理画面だけで動作する

(フロント画面で、wp-adminのファイルを一つも読み込まない)。

 

WPはwp-adminフォルダを失っても、フロント画面だけで動作する
(管理画面で、wp-content内のファイルを読み込まない。
 その時、プラグインとfunctions.phpは無視される)。

 

テーマファイルを読み込むのは、ロード動作の最後である
(web中で間違った記述が散見される)。

Ver4.9.7時点で1900あるファイルのうち、
通常動作で読み込むファイル数は、50~200である。

プラグインの設計を間違えると、極端に遅くなる。

逆に言うと、プラグインの適切な設計を行うと
インストール最初期とロードスピードは変わらない。

 

サーバースクリプトの動作を想像する

URLから入力されたパラメータを解析し、解析結果に合ったデータをDBから用意し、
ユーザーが使う可能性のある変数・関数・オブジェクトを用意し、
出力ページを準備し、出力完成するという流れが想像できます。

出力処理をどの程度詳細に分析する設計になっているかは、まだ不明です。
テンプレートファイルや、functions.phpをかなり後半に解析しているため、
ユーザーの設定の準備を、先にすべてしておいてからロードしている可能性が高く、
改良の余地があるかもしれません(ここはあくまで個人的推測です)。

 

最後までお読みいただき、ありがとうございました。

松永大地
CSVIT事業部 TS(テクニカルサービス)部 松永大地
シンプルで速いコードをみんなで共有しましょう!