2023年10月21日18:00 by:コバ

CakephpにSSI機能を付けた話

システム2号のコバです。

突然ですがSSIという技術をご存知でしょうか?

SSIとは、Server Side Includeの略で、CGIと同じく動的にコンテンツ(HTML)を生成するための技術だとかHTMLに特別なコメントを記述すると置換してくれるとかまあ色々なところで色々説明されてるが……

要は1つのページを作ろうとした時に別ページを部品として持ってこれるからHP作るのが楽になるやつである。

だがこのSSIという技術、実はもう相当に古く枯れた技術らしい。検索すれば Google「おいおい、SSLだろ?誤字ってたから検索結果にSSL含めといたぜ!!」と言われ、フレームワークには「いや、file_get_contentあるっしょ?」とか言われるのである!!
(私が一時期検索しまくったからか、もしくは「SSIだけで検索」的なアレを指定したからか、今では普通に検索してくれるようになった)

今では色々なPHPフレームワークで、もはやSSIは対応していないらしく、ねこのしっぽのホームページで利用しているCakePHPもバージョンアップしたら使えなくなってしまったのである!!


しかし、ねこのしっぽには部品をSSIで取ってきているコンテンツがけっこういっぱいある。
それら全てを、PHP化することも出来ない(いや、厳密には出来なくは無いけど)

なので今回はフレームワークそのものを改造し、SSI対応したのである!!

本日のブログはその自分向け備忘録である。

こう↑書いておけばちょっとくらい変なことが書いてあっても許してもらえるのだ。
どこかのずんだもんもそう言っていたのだ……


閑話休題


例えばもし↓↓↓こんな感じ↓↓↓に弊社の(架空の)寿司メニューのページを表示させたいとする。
無題.png

この、エクセルで10秒で作ったような表を別ページとして作り、部品として使うという想定

こう↓書いておけば良いのだ。

<div class="tekito header">

    ヘッダー等々

</div>

<div class="sushi menu">

    <!--#include virtual="/neko/sushimenu/nigiri" -->

</div>

<div class="tekito content">

    文面がある

    と思ってください

</div>


<!--#include virtual="/neko/sushimenu/nigiri" -->

↑の部分に↓のサイトで作られた表が部品として配置されて画像のようになるのである。

 https://www.shippo.co.jp/neko/sushimenu/nigiri


これがCakephpでは挿入されない。

そこでerrorログを見ると

5023-15-51 11:45:14 Error: [MissingControllerException] Controller class NekoController could not be found.
Exception Attributes: array (
'class' => 'NekoController',
'plugin' => NULL,
)

リクエストが正確に解釈されていないっぽい。
と、いうことでCakephpでリクエストを処理しているCakeRequestを見てみると


        if (!empty($_SERVER['PATH_INFO'])) {

            return $_SERVER['PATH_INFO'];

        } elseif (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '://') === false) {

            $uri = $_SERVER['REQUEST_URI'];

        } elseif (isset($_SERVER['REQUEST_URI'])) {

            $qPosition = strpos($_SERVER['REQUEST_URI'], '?');

            if ($qPosition !== false && strpos($_SERVER['REQUEST_URI'], '://') > $qPosition) {

                $uri = $_SERVER['REQUEST_URI'];

            } else {

                $uri = substr($_SERVER['REQUEST_URI'], strlen(Configure::read('App.fullBaseUrl')));

            }

        } elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_NAME'])) {

            $uri = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']);

        } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {

            $uri = $_SERVER['HTTP_X_REWRITE_URL'];

        } elseif ($var = env('argv')) {

            $uri = $var[0];

        }


なるほど、見ていない。
そこで上記をこうする


        //REDIRECT_SCRIPT_NAME.shtmlを含む場合SSIと判断

        if(isset($_SERVER['REDIRECT_SCRIPT_NAME']) && strpos($_SERVER['REDIRECT_SCRIPT_NAME'], '.shtml') !== false){

            $uri = $_SERVER['REDIRECT_URL'];

        } elseif (!empty($_SERVER['PATH_INFO'])) {

            return $_SERVER['PATH_INFO'];

        } elseif (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '://') === false) {

            $uri = $_SERVER['REQUEST_URI'];

        } elseif (isset($_SERVER['REQUEST_URI'])) {

            $qPosition = strpos($_SERVER['REQUEST_URI'], '?');

            if ($qPosition !== false && strpos($_SERVER['REQUEST_URI'], '://') > $qPosition) {

                $uri = $_SERVER['REQUEST_URI'];

            } else {

                $uri = substr($_SERVER['REQUEST_URI'], strlen(Configure::read('App.fullBaseUrl')));

            }

        } elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_NAME'])) {

            $uri = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']);

        } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {

            $uri = $_SERVER['HTTP_X_REWRITE_URL'];

        } elseif ($var = env('argv')) {

            $uri = $var[0];

        }

これで対象のファイルがSSIを使っているかをフレームワーク側が検知してくれるようになりました。


タグ:PHP cakephp | Comment(0)
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。