忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2025/01/17 01:16 |
Smarty-04 Smarty関数

Smartyのテンプレートでは、表示を簡潔に行うための色々な関数があります。

{foreach}は、概要はPHPのforeachとほぼ同じで、配列の中身を並べて表示するのに役立ちます。
書式はPHPとだいぶ違い、以下のようになります。

{foreach from=$str key=str_key item=str_item name=str_name}
 {$str_key}
 {$str_item}
{/foreach}


foreach($str as $str_key=>$str_item){
 print($str_key);
 print($str_item);
}


以上の二つがほぼ同じ意味になります。

name=str_nameはPHPのforeachには存在しない特殊な内容で、ループに関する内容を取得できます。
{$smarty.foreach.str_name.iteration}で現在のループ回数が、
{$smarty.foreach.str_name.first}で最初のループか否か、
{$smarty.foreach.str_name.last}で最後のループか否かといった内容が取得できます。


{if}は、これもPHPのifと同じです。
書式もPHPのifとほぼ同じです。

{if $a==1}
 {$a}
{else}
 {$b}
{/if}


if($a==1){
 print($a);
}else{
 print($b);
}


条件演算子はそのまま使えます。
また特殊な指定として、{if $a is even}が「偶数なら」になるといった、表示するのに便利な指定が幾つかあります。

ifとforeachを組み合わせることで、配列からテーブルを作成し、最初のループだったら<table>と記入、偶数行だったら背景色を変更、といったことができるようになります。
ただfirstとかは、後述のようにループの外に書いた方がわかりやすいですが。

上記の{if}と{foreach}を使用して簡単なテーブルを作ってみました。

index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
    
    //Smarty
        require_once('./../../smarty/libs/Smarty.php');
    
    //変数
        $str=array(
             array(
                 'familyname'=>'小町'
                ,'firstname'=>'つぐみ'
                ,'ext'=>''
            )
            ,array(
                 'familyname'=>'茜ケ崎'
                ,'firstname'=>''
                ,'ext'=>''
            )
            ,array(
                 'familyname'=>'田中'
                ,'firstname'=>'優美清春香菜'
            )
        );
    
    //変数アサイン
        $smarty->assign('str',$str);
    
    //表示
        $smarty->display('index.html');


index.tpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html>
 
<table border="1">    {*開始/終了タグは外側に書いた方がわかりやすい*}
 
{*ループ開始*}
{foreach from=$str item=str_item name=str_name}
    {*偶数の場合のみbgcolorを表示*}
    <tr{if $smarty.foreach.str_name.iteration is even}
         bgcolor="#cccccc"
    {/if}>
        <td>{$str_item.familyname}</td>
        <td>{$str_item.firstname}</td>
        <td>
            {if $str_item.ext}
                {*$str_item.extが存在すれば*}
                {$str_item.ext}
            {else}
                {*$str_item.extが存在しなければ*}
                &nbsp;
            {/if}
        </td>
    </tr>
    {if $smarty.foreach.str_name.last}
        </table>{*最終ループなら終了タグを表示する、が少々分かり難い*}
    {/if}
{/foreach}{*ループ終了*}
 
</body></html>



出力は以下のようになります。

小町 つぐみ
茜ケ崎
田中 優美清春香菜  

{*コメント*}はSmartyのコメントで、HTMLのソースには出力されません。
出力されるコメントとしては普通に<!--コメント-->が使えます。

今回は中身が短いので却ってソースが長くなって分かり難く見えますが、Smartyを使い慣れると非常に使いやすくて便利になって手放せなくなります。

{cycle}?
黙れ。

PR


2009/07/17 17:09 | Comments(0) | TrackBack() | PHP
Smarty-03:カスタム修正子

Smarty/pluginsフォルダあたりを覗いてみると、modifier.escape.phpといったファイルが並んでいます。
実はこれが修正子の正体です。
仕組みは単純で、Smarty内で{$data|escape}という修正子が現れたらmodifier.escape.phpを読み込み、その中のsmarty_modifier_escapeという関数を実行するということになっています。

ところでtruncate修正子に日本語を突っ込むと、区切る文字数も正しくないし区切ったところが文字化けしたりします。
modifier.truncate.phpを見てみると、文字を区切るときにsubstrを使用しています。
substrは日本語に対応していないのでtruncate修正子では日本語を扱うことができません。

そこで日本語に対応したmb_truncate修正子を作成してみましょう。

まずpluginフォルダ内にmodifier.mb_truncate.phpを作成。
中身は簡単にこんなかんじ。

modifier.mb_truncate.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
    
    function smarty_modifier_mb_truncate($string, $length = 80, $etc = '...'){
        //引数
            $length+=0;
            if(!$string || $length == 0){return '';}
        
        //返却
            if(mb_strlen($string)>$length){
                //長ければ切って返す
                return mb_substr($string,0,$length).$etc;
            }else{
                //短ければそのまま
                return $string;
            }
    }


使用するときはテンプレートに
{'あいうえお'|mb_truncate:3}
と書くだけです。
これで自動的にmb_truncate修正子を利用してくれます。

さて、このmb_truncateはSmarty改造の入り口みたいなもので、色々なサイトで解説されています。

http://webtech-walker.com/archive/2007/04/26154112.html
http://jbar.jp/ishimaken/xoops/
http://c-brains.jp/blog/wsg/07/06/14-160910.php

一番下のソースと全く同じことになってますが本当に偶然ですから。
誰が書いてもこんなもんだって。

 



2009/07/06 18:46 | Comments(0) | TrackBack() | PHP
PHP1-83:OSコマンドを直接実行

exec、passthru、バッククォートといった命令は直接OSコマンドを叩いてくれます。
正直これらの命令の違いがいまいちわからないのですが、バイナリじゃなければとりあえずexecでいいやー的な。

問題点としては、OSのコマンドを直接叩くので環境によって互換性がありません。
typeはLinuxではコマンドの詳細を表示するコマンドですが、Windowsではファイルを読み込んで表示するコマンドです。
うっかりバッククォートを使ってしまうと環境移動の際に大変な目に遭うこともありますが、PHPでは処理が面倒なことをシェルコマンドを使用することで非常に簡単に処理できたりするといったメリットもあります。

ディレクトリ内の一部ファイルをページャーつきで新しい順に取得したい、などといった要求があった場合、PHPだけで処理を行うのは非常に困難です。
標準関数ではopendir、readdir、is_fileあたりを駆使して一旦全ファイルを取得後ソートしなければなりません。
あるいはdirクラスやDirectoryIteratorなんかもありますが、これらには取得条件を変更するメソッドなどは無いので、やはり一旦全ファイルを取得して並び替える必要があります。
ファイルが少数ならまだいいですが、何年も動いてるWebサーバのアクセスログをどうにかしろとか言われてもご勘弁願いたいところです。

こんなときこそOSコマンド。
exec('ls -At /var/log/apache2 | grep user_log | head -100 | tail -20',$dir);
わずか一行で済んでしまいました。
あとはheadやtailのところに適当にページャを埋め込めばさくっとログビューアの完成です。

最初に書いたとおり互換性には乏しく、bashのコマンドを使用しているのでLinux専用となっています。
Windowsのコマンドプロンプトにはlsもgrepもheadもtailも/var/log/apache2も存在しないため、このコマンドは動作しません。
Windowsと両対応させるにはおとなしくopendir等を利用するしかないでしょう。



2009/07/03 18:38 | Comments(0) | TrackBack() | PHP
PHP1-82:出力バッファリングのちょっとだけ便利な使い方

配列を丸ごと保存して後で内容を確認したいとかいう場合、実はいまいち便利な関数がありません。
その場で表示するならvar_dump()するだけで中身を全部表示してくれますが、この関数、結果を返り値として受け取ることができません。
print_r()は結果を取得できますが、var_dump()程の詳細な情報は取得できません。
implode()は一次元配列しか使えませんし、serialize()だとPHPではわかりやすくても人間の目にはわかりづらくなってしまいます。
Pear::XML_Serializerに突っ込めば簡単にXMLになりますが、単に配列を表示したいだけなのにPearだのXMLだのをわざわざ使用するのもなんだかなーといった感じです。
結局foreachでぐるぐる回すといった力業になりがちです。

そんなときにバッファリング。

var_dump_buffering.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
    
    //なんか適当な配列
        $arr=array(
             1
            ,2
            ,3=>array(
                'hoge'=>'fuga'
            )
            ,4=>'aaaaa'
        );
    
    //文字列として取得
        $ret=ob_var_dump($arr);
        print($ret);
    
    //var_dumpの中身を返す関数
        function ob_var_dump($obj){
            ob_start();
            var_dump($obj);
            $ret=ob_get_contents();
            ob_end_clean();
            return $ret;
        }


出力を簡単に取得することができました。
これをそのままログに突っ込めば、後から人間に見やすい形になるでしょう。

まあ、この使い方はマニュアルに堂々と書いてあるんですがね。
http://jp.php.net/manual/ja/function.var-dump.php 


2009/06/30 19:38 | Comments(0) | TrackBack() | PHP
Smarty-02 修正子

Smartyでは変数の出力時に簡単にフィルタをかけることができます。

これらは修正子と呼ばれています。
{$str|escape}
と書くと、$strにhtmlspecialchars()が適用された上で表示されます。

他に{$str|nl2br}
とすると変数内の改行が<br />に、
{$str|replace:'a':'b'}
とすると$str中の'a'が'b'に置換されて表示されます。
引数がある場合は:で区切って指定します。

また、複数の修正子を|で連結させて適用することもできます。
{$str|upper|lower}
とすると、$strを大文字に変更し、その後小文字に変更して表示します(結局小文字になる)

それ以外にも、何気にマニュアルに書かれているとおり、すべてのPHP関数を修正子として利用できます。

{$str|substr:5:3}
とするとsubstr($str,5,3)と同じ意味になります。
この場合第一引数が$str、substrの後ろが順に第二以降の引数という解釈になります。
というわけでこれを使用して、
$smarty->assign('yesterday',time()-60*60*24);
{'Y-m-d H:i:s'|date:$yesterday}
みたいな書き方もできたりします。
このような書き方は結構知られてないような気がします。
まあ普通は
{$yesterday|date_format:"%Y-%m-%d %H:%M:%S"}
としますけれども。
どうでもいいがdate_formatって名前なのにstrftimeの解釈をするのはどうなんだ。

さて、XSS対策に毎回エスケープかけるのは面倒臭い、という場合のためにデフォルトでエスケープする、というオプションがあります。
$smarty->default_modifiers=array('escape:html');
これをSmarty.phpに書いてみましょう。
この場合、出力は常にエスケープされて表示され、例外的にエスケープしたくない場合に
{$str|smarty:nodefaults}
というふうにするとエスケープせずにそのまま表示することができます。
基本的にこのオプションを使うほうが安全ですが、明示的に:escapeした方が明らかにエスケープしたとわかりやすいですし、そこは場合によると言うことで。

古いSmartyにはdefault_modifiersを指定すると配列が使えなくなるというバグがあったようですが、2.6.22では修正されているようです。



2009/06/19 15:43 | Comments(0) | TrackBack() | PHP
Smarty-01:PHPでSmarty

プログラムの規模が大きくなってくると、ロジックとデザインを一緒にしていたのでは見通しの悪く分かり難いプログラムになってしまいます。
そこでMVCパターンを使用したロジックとデザインの分離が現場ではよく使われています。
PHPでも各種フレームワークの開発が盛んですが、今回はフレームワークと言うほど本格的ではなく気軽に使えて普遍性の高いSmartyを使ってみます。

まずはSmartyを解凍すると色々フォルダが出てきますが、必要なのはlibsフォルダだけです。

アップロードを行う場合、できるだけhtdocsより上のフォルダ、ブラウザからは見えないところに置きましょう。
レンタルサーバ等で権限がないなら仕方ありませんが、その場合は推測しにくいフォルダ名にした上で、.htaccessやダミーのindex.hrml等を設置して直接覗かれる可能性を減らしておきましょう。
一応言っておきますが、公開フォルダに置く=公開する、です。

今回はこのような形で設置しました。

homes
  ├htdocs
  │ └(各phpファイル)
  └smarty
     ├libsフォルダ
     │ ├Smarty.php
     │ └(各Smarty関連ファイル)
     ├templatesフォルダ
     └templates_cフォルダ

smarty/libsはSmartyファイルを置く場所です。
smarty/templatesは、表示用のテンプレートファイルを置きます。
画面表示のデザインなどはテンプレートファイルで行い、ロジックはhtdocs以下のphpファイルで行うことで、ロジックとデザインを切り離すことができます。

smarty/templates_cはコンパイルされたファイルを置きます。
Smartyの特徴として、一度表示されたファイルをその状態で保存しておくことができます。
二度目以降のアクセス時にはそのファイルを表示することで、ロジックを経由する時間と負荷を軽減することができます。
コンパイルフォルダはPHPが書き込みを行いますので、所有者と権限を変更しておきましょう。

smarty/libs/Smarty.phpは下記スクリプトで、Smartyクラスをインスタンス化し、上記のテンプレートの位置を決める等の初期設定を行います。
別にsmarty/libs/Smarty.class.php等を直接変更してカスタマイズしてもいいのですが、その場合元に戻したりするのが面倒なので別ファイルで行います。

smarty/Smarty.php 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
 
    //定義
        //Smartyの場所(SMARTY_DIRはSmarty内部でも使用)
        define('SMARTY_DIR',dirname(__FILE__).'/');
        //テンプレートファイル置き場
        $smarty_templates_dir=SMARTY_DIR.'../templates/';
        //コンパイル済ファイル置き場
        $smarty_templates_c_dir=SMARTY_DIR.'../templates_c/';
    
    //Smartyセット
        require_once(SMARTY_DIR.'Smarty.class.php');
        $smarty=new Smarty();
        $smarty->template_dir = $smarty_templates_dir;
        $smarty->compile_dir  = $smarty_templates_c_dir;


このファイルをincludeすることで、$smartyでSmartyインスタンスにアクセスすることができるようになります。
簡単に使ってみましょう。
htdocs/index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
    
    //Smarty
        require_once('./../smarty/libs/Smarty.php');
    
    //変数
        $str='string';
        $arr=array(
             'hoge'=>'<b>11111</b>'
            ,'hage'=>'<i>22222<i>'
        );
    
    //変数アサイン
        $smarty->assign('a',$str);
        $smarty->assign('b',$arr);
    
    //表示
        $smarty->display('index.html');

Smartyインスタンスにaとbふたつの変数をアサインし、index.htmlを表示せよ、と書かれています。
というわけで最後にindex.htmlを作ります。

smarty/templates/index.html
1
2
3
4
5
<html><body>
    $str:{$a}<br />
    $arr->hoge:{$b.hoge}<br />
    $arr->hage:{$b.hage|escape}<br /></body></html>

これでどうなるかというと、
<html><body> $str:string
$arr->hoge:11111
$arr->hage:<i>22222<i>
</body></html>
 

このようなソースが出力されます。

 

Smartyテンプレート中で{$a}と書くと、その部分が$smarty->assignした変数の内容で置き換えられます。
同様に{$b.hoge}はアサインされた配列$b['hoge']が表示されます。

このように、テンプレート側では表示以外のことをさせないことで、表示のためにロジックをいじられたりすることを防ぐことができます。
またロジック側でも、表示側を考えることなく必要な変数をSmartyインスタンスに投げ込むだけでよくなります。
分業を行うことで、プログラムの見通しをよくすることができます。
またロジックを書くPG、テンプレートを書くコーダー等複数人が関わるプロジェクトに対し開発効率が上昇します。

逆に問題点としては、両者で変数の命名規則や配置方法などについてしっかり取り決めておかないと、あの変数は何処にあるんだ等行方不明になりやすくなったり、うまく表示するために奇怪なロジックを組んだりしなくてはならなくなったりします。
 



2009/06/15 12:17 | Comments(0) | TrackBack() | PHP
PHP1-81:OpenSSL続き

前回の続き?

文字列の暗号化とサーバ←→クライアント間の暗号化はまったく別のレイヤのお話です。

単に文字列だけではなく、サーバからの応答それ自体を暗号化しないといけませんので、PHPで云々ではなくApacheの設定、httpd.confの編集が必要です。
XAMPPの場合、関連する内容毎に設定ファイルを分けてくれていますので、C:\xampp\apache\conf\extra\httpd-ssl.confあたりがSSL関連の設定になります。
で、SSLCertificateFileSSLCertificateKeyFileあたりがその設定になるのですが……実はhttpsでアクセスした場合、XAMPPでは最初から前回作成したserver.crt、server.keyが自動的に使われるようになっています。
これまでのURLを単にhttpsにするだけで、普通にSSLによる暗号化通信が可能となります。

問題点としては、認証局に認証を受けていないオレオレ証明書なので、初回通信時に警告が現れ、「許可する」を選ばない限り通信ができません。
これは、その証明書が、ルート認証局を辿れないだけの正しい証明書なのか、それとも悪人が途中ですり替えた偽物の証明書なのか区別が付かないためです。
これを銀行なんかがやってしまうと大問題なわけですが、個人レベルで高い金払って購入するのも馬鹿っぽいのでまあこんなものでいいでしょう。

さて、httpd-ssl.confにある、
<VirtualHost _default_:443>
の部分がSSL接続時の動作となっています。
デフォルトではhttp通信時と同じになっていますが、ここを変更することでSSL通信時のみの挙動を変更するなんてことができます。

<VirtualHost _default_:443>
    DocumentRoot "C:/xampp/htdocs_ssl"


このようにすると、httpで接続した場合は元々の表示先であるところの"C:/xampp/htdocs"フォルダが、https接続の場合はこちらで設定した"C:/xampp/htdocs_ssl"フォルダがドキュメントルートになります。
このようにフォルダを分けることで、httpではどうやっても"C:/xampp/htdocs_ssl"に接続できない、といった設定を行うことができます。
会員登録などで必ずSSLを使わせたい場合などに有効です。
ただし、本気で個人情報を扱うような場合、オレオレ証明書は使用してはいけません。


しまった、PHP関係ない。



2009/06/08 14:01 | Comments(0) | TrackBack() | PHP
PHP1-80:OpenSSL

XAMPPには最初からOpenSSLが付属しているので、簡単にオレオレ証明書を作成できます。

SSLで暗号化通信をするためには暗号化キーの受け渡しが必要ですが、その暗号化キー自体が本当に正しいものなのかどうかは、それ自身だけではわかりません。
サーバが正しい鍵を送信したつもりでも、途中で不正な鍵にすり替えられてクライアントに届き、それを使って暗号化したつもりが覗かれ放題、という可能性があるからです。
それを防ぐため、サーバではベリサインなどの"信用できる"認証局から証明書を発行してもらい、それを自分の証明書に組み合わせて新しい暗号化キーを作ります。
ブラウザ側では、その鍵にベリサインなどの"信用できる"証明書が含まれていればその証明書は正しいと判断します。
まあ↑の説明は端折りすぎて正しくないので知ったかしないように。私のことですかそうですか。

そんなわけで個人情報の厳重な取り扱いが必要な企業などでは正しい証明書を発行するべきですが、個人でテストするレベルではそんな必要もないでしょう。
第一種または第四種オレオレ証明書となるでしょう。
さくっとやってみます。

 C:\xampp\apache\bin>openssl version
 WARNING: can't open config file: /usr/local/ssl/openssl.cnf
 OpenSSL 0.9.8i 15 Sep 2008


いやあ……なんだそれ?

 $res=openssl_pkey_new();
 print($res);
 bool(false)

あるぇー?


というわけで証明書を作成してくれるバッチファイルが提供されています。
デフォルトだとここらへんにあると思われます。
C:\xampp\apache\makecert.bat
コマンドプロンプトから実行して質問に適当に答えていくと、自動的に暗号化キーが作成されます。
C:\xampp\apache\conf\ssl.crt\server.crtが公開鍵、C:\xampp\apache\conf\ssl.key\server.keyが秘密鍵となります。
無かったら適当にそこら辺を探してください。

鍵のペアができましたので、とりあえず暗号化してみます。

encrypt_decrypt.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
    
    //暗号化する文字列
        $str='あいうえお';
    
    //公開鍵
        $key_public=file_get_contents('C:\xampp\apache\conf\ssl.crt\server.crt');
    //秘密鍵
        $key_private=file_get_contents('C:\xampp\apache\conf\ssl.key\server.key');
    
    //暗号化
        $ret=openssl_public_encrypt($str,$str_encrypt,$key_public);
        if($ret===false){print_openssl_error();}
    
    //復号化
        $ret=openssl_private_decrypt($str_encrypt,$str_decrypt,$key_private);
        if($ret===false){print_openssl_error();}
    
    //確認
        print("<html><pre>");var_dump($str,$str_encrypt,$str_decrypt);die();
    
    //失敗したときにエラーログを拾う関数
        function print_openssl_error(){
            while($msg = openssl_error_string()){
                print($msg.'<br />');
            }
        }

$strと$str_decryptが同じになり、無事に復号化できました。
ちなみに$str_encryptは実行するたびに違う値になります。びっくりですね。


さて、暗号化復号化ができるのはわかったが、で、これでどうやってサーバ←→クライアント間を暗号化するんだ?



2009/06/05 14:54 | Comments(0) | TrackBack() | PHP
PHP1-79:APCキャッシュの具体的使用法

なんといってもAPIです。
他サイトにリクエストを投げるわけですからどうしても時間がかかってしまいます。
またリクエスト回数が増えると負荷もかかるので、多くのサイトでは上限回数が指定されているはずです。
そんなときこそAPCです。やってみましょう。
題材は適当にググって引っかかったサムネイル画像作成API
http://img.simpleapi.net/

まずは普通に実行

thumbnail.php

1
2
3
4
5
6
7
8
9
10
<?php
    
    //画像を拾ってくる
        $url='http://img.simpleapi.net/small/http://www.google.co.jp/';
        $ret=file_get_contents($url);
    
    //画像表示
        header('Content-Length: '.strlen($ret));
        header('Content-Type: image/jpeg');
        print($ret);

リクエストがあると毎回img.simpleapi.netまで画像を取りに行きます。
次にAPCを使ってみます。

thumbnail_apc.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
    
    //APCからキャッシュロード
        $api_cache=apc_fetch('thumbnail_cache');
    
    //キャッシュロードに失敗したら
        if($api_cache===false){
            //画像を拾ってくる
                $url='http://img.simpleapi.net/small/http://www.google.co.jp/';
                $api_cache=file_get_contents($url);
            //APCにキャッシュを保存
                apc_store('thumbnail_cache',$api_cache,3600);
    }
    
    //画像表示
        header('Content-Length: '.strlen($api_cache));
        header('Content-Type: image/gif');
        print($api_cache);

APCにデータが無ければ拾ってきてそれを突っ込みますが、あればAPIにアクセスすること無しにキャッシュから画像を表示します。
というわけであっさり成功。

さて、ここらへん見てみるとどうもAPCにはさらに別の使い方があるようで、というかこっちが主題でapc_fetch()とかがおまけっぽくない?
http://neta.ywcafe.net/000952.html
http://www.maido3.com/server/option/php.html


ちなみにapc_fetchに第二引数を渡したらエラーになりました。
mixed apc_fetch ( string $key [, bool &$success ] )
Warning: apc_fetch() expects exactly 1 parameter, 2 given

はて??

 



2009/06/01 15:57 | Comments(0) | TrackBack() | PHP
PHP1-78:APCキャッシュ

お天気予報APIなどをアクセスがあるたびに呼びに行く必要はありません。
毎秒1アクセスがある人気サイトだった場合、毎日86400回もリクエスト要求を出してしまうことになります。
これを例えば1分キャッシュを保存しておくだけで一日のリクエスト回数を1440回に激減させることができます。
一時間に一回なら一日に24回です。
更新頻度が重要でないものは積極的にキャッシュを利用しましょう。

また、APIでなく内製のものでも、毎回DBやファイルにアクセスして動的にページを作成するのに時間や負荷がかかる場合、動的にページを作成した結果をキャッシュしておいてその後は単にそれを表示するだけ、というのはよい考えです。
たとえばSmartyなんかはテンプレートをファイルとしてキャッシュしています。
逆にリアルタイム更新が必要な掲示板やブログの投稿やコメント、ショッピングカートの中身などにはキャッシュを使ってはいけません。

とりあえず使用が簡単なAPCを使ってみます。
最初は使用できない状態ですが、XAMPPならphp.iniの
;extension=php_apc.dll
となってる行のコメントを外せばいきなり使用できます。

パッケージがない場合はpeclから持ってきましょう。
peclのパッケージにはAPCの状態をビジュアルに見ることができるサンプルが含まれているのですが、当方の環境ではApache毎落ちてしまいます。何故。 //GDが悪いっぽい

APCの使い方は非常に簡単。

a.php 

1
2
3
4
<?php
    
    //APCキャッシュに保存
        apc_store('a','データ');

b.php
1
2
3
4
5
6
<?php
    
    //APCキャッシュから取得
        $ret=apc_fetch('a');
    
        var_dump($ret);


a.phpを実行した後にb.phpを実行すると、a.phpで保存した内容が表示されます。
見ての通りセッションも何も使っていませんが、apc_store()で突っ込んだデータは、そのままapc_fetch()で取り出すことができます。
まあ平たく言うとアプリケーションスコープのようなものです。

さて、最初の設定のままだといつまでもAPCキャッシュの中身が残り続けてデータが際限なく増えていくので、
php.iniの[APC]の項目に
apc.ttl=3600
apc.user_ttl=3600

と書いておきます。
これで、APCに突っ込んで3600秒たったデータは自動的に削除されます。
ソース側でapc_store()に生存秒数を指定することができ、またapc_clear_cache()を使用すれば手動で削除できますが、うっかり忘れた場合のためにも面倒なことはPHP本体に任せてしまいましょう。

次回はAPCキャッシュの具体的な使い方でも。

 



2009/05/29 16:57 | Comments(0) | TrackBack() | PHP

<<前のページ | HOME | 次のページ>>
忍者ブログ[PR]