スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

register_prefilter再び

どうも、僕です。

こんな僻地のブログでもGoogleさんがインデックスしてくれているお陰で、わざわざ足を運んでくださる方がいらっしゃるようで、大変有難いことです。

ところでこのブログ、どうせみんなTOKYO-TUBEの動画を保存してオフラインで鑑賞する方法が目的で訪問してくるんだろうと思ってたら、意外とSmartyのエラーで来てくれる人がいることがわかったので、register_prefilterについて追記したいと思います。

以前のエントリでは、外人のQA引っ張ってきて、黙ってregisterFilter使えよ的な回答をしたわけですが、もうちょっと具体的に書きたいと思います。


たとえばSmary2系でSmartyクラスを独自にextendしてregister_prefilterを使う場合、こんなふうに書きますね。

class SmartyExtends extends Smarty{ ←Smartyクラスを継承

    public function __construct(){ ←コンストラクタにプレフィルタを登録

        // prefiliter
        parent::register_prefilter( 'default_display_filter' ); ←前処理

        function default_display_filter( $tpl_src, &$Smarty ){ ←前処理の中身
        
            ----- 何か適当な処理 ---
            
            return $tpl_src;
        }
    }
}



まず先頭の

class SmartyExtends extends Smarty


で、SmartyをextendしたSmartyExtendsを作ります。
プログラムからnewするのはSmartyではなく、SmartyExtendsになります。

で、

function __construct(){ ... }


内にparent::register_prefilterすることで、SmartyExtendsがnewされた時点でdefault_display_filterが呼び出されるわけです。

newする度に呼び出されるのは効率的じゃなくね?っていう話もありますので、そういうのが気になる人はdisplayの中でもどこでも好きな様にやってもらって構いません。

さて、これをSmary3でやると、下記のNoticeが出ます

Notice: function call 'register_prefilter' is unknown or deprecated.




これを回避するためには、registerFilterを使うわけですが、こんな風に書き換えます。

class SmartyExtends extends Smarty{    ←Smartyクラスを拡張するのは一緒

    //テンプレート前処理
    function registerFilter($tpl_src, $type='pre'){    ←明示的に前処理を指定
        
        parent::registerFilter( $type,array('SmartyExtends','default_display_filter'));    ←前処理したい関数を登録

    }
    
    static function default_display_filter($tpl_src,$sobj){    ←実際の前処理を記述

         ----- 何か適当な処理 ---

        return $tpl_src;
    }
    
    function display($tempfile='',$cache_id = null, $compile_id = null, $parent = null){    ←display文の中でフィルタを呼ぶように変更
    
        $this->registerFilter($tempfile);    ←parent::displayする前に前処理を明示的に呼び出す
        
        parent::display($templatepath,$cache_id,$compile_id,$parent);    ←display
    }
}




先頭のextendは一緒ですが、Smarty3ではコンストラクタで処理しようとするとなぜかエラーになリます。

コンストラクタはやめて、今回はdisplay内で呼び出すことにします。

function display($tempfile='',$cache_id = null, $compile_id = null, $parent = null)


新たにdisplayクラスを作って、親のdisplayを呼び出すってやつなんですが、PHP5.3からはオーバーライドするときに
上書き元のclassと変数の数が一致しないとエラーを返すので、合わせてやる必要があります。

displayの中でプリフィルタを呼び出すわけですが、ExtendしたSmartyクラス内でカスタムしたregisterFilterを呼び出すように書き換えます。

$this->registerFilter($tempfile);



なんでこんな処理をする必要があるのかというと、後続の処理でプレフィルタにテンプレートを引き渡すためだそうです。
Smartyのサイトに書いてあったとおりです。ここで疑問を挟んではいけません。

    function registerFilter($tpl_src, $type='pre'){
        parent::registerFilter( $type,array('SmartyExtends','default_display_filter'));    
    }


はparent::registerFilterを呼び出すためだけのメソッドですが、直接parent::registerFilterを呼び出すとテンプレート$tpl_srcがプレフィルタに渡せないので、こんなふうに書きます。
Smartyのサイトに書いてあったとおりです。疑問を挟んではいけません。

$typeに指定できるのは、Smartyによれば

"pre", "post", "output" and "variable"


なので、呼び出すタイミングによって$typeを変えます。今回はpreを使いました。

もう一個の引数

array('SmartyExtends','default_display_filter')


SmartyExtendsが以前の&$SmartyにあたるSmartyオブジェクトで、default_display_filterが、プリフィルタしたい処理です。

default_display_filterの第一引数はテンプレート変数で、第二引数はSmartyオブジェクトが入ってます。

static function default_display_filter($tpl_src,$sobj){


第一引数には$this->registerFilter()したときの$tempfileがそのまま渡ってきてます。
第二引数を書いておけば、勝手にSmartyオブジェクトが入ってくれるので、フィルタ内でSmartyのメソッドが呼び出せるはず。

たぶんこれでSmarty3でもプリフィルタが使えるはず・・・!

スポンサーサイト

register_prefilterの挙動を変えるとかなしにしようぜSmartyさん

Smartyにはプリフィルタ機能ってやつがあって、それぞれテンプレートのコンパイル前に下記の挙動を行うっていうのはよく知られた話。


register_prefilter()・・・プレフィルタを実行
register_postfilter()・・・ポストフィルタを実行
register_outputfilter()・・・アウトプットフィルタを実行


Smartyを使うPHPユーザーは、だいたいこれを使ってテンプレートを出力する際に共通ヘッダ、フッタなんかを出したりしてると思います。



で、最近Smarty3を使って例のごとくプレフィルタを実行しようとしたら、エラー

Notice: function call 'register_prefilter' is unknown or deprecated.



Smartyのバージョンなんてしばらく上げてなかったので、焦ってググると同じような症状に悩んでる人を見つけた。


ドキュメント読めよカスとでも言いたげなリンク一文が貼ってあるのでクリックすると。。。。


...orz

Name

registerFilter() — dynamically register filters
Description
void registerFilter(string type,
mixed callback);

Use this to dynamically register filters to operate on a templates. It uses the following parameters:

type defines the type of the filter. Valid values are "pre", "post", "output" and "variable".

callback defines the PHP callback. it can be either:

A string containing the function name

An array of the form array(&$object, $method) with &$object being a reference to an object and $method being a string containing the method-name

An array of the form array($class, $method) with $class being the class name and $method being a method of the class.



とりあえずregisterFilter()を使えよ、と。
変なクラス使うなよと。

ていうかこのクラス、いつから使えるようになってたの。。。
もしかして_prefilterを使うのがイレギュラーだったの。。。。

にしてもリンクくらい貼っておいてよSmartyさん!ヽ(`Д´)ノ ウワァァァン

次回に続く。

気付けばPHPとMySQLのコンパイルオプションが変わっていたでござるの巻

こんにちは!僕です!
MySQL5.5がGAになってから5ヶ月近くが経ち、テスト環境構築を兼ねて現時点の最新版をインストールすることにしました。

まず現時点で最新のMySQLをダウンロード

$ wget http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.11.tar.gz/from/http://ftp.iij.ad.jp/pub/db/mysql/
$ tar zfx mysql-5.5.11.tar.gz
$ ./configure
-bash: ./configure: そのようなファイルやディレクトリはありません

ってあれ?configureが通らないの???


とりあえずconfigファイルの中身を確認しようとディレクトリの中身を調べると

-rw-r--r-- 1 7161 wheel 8479 3月 31 22:36 BUILD-CMAKE


CMAKE?
BUILD-CMAKEの中を読むとわかるが、MySQL5.5からビルドがconfigureからcmakeになったんですね。
しかもさらに調べるとコンパイルオプションも全然変わってるようで、比較的よく使うオプションはこうなる

--prefix=/usr/local/mysql/ → -DCMAKE_INSTALL_PREFIX=/usr/local/mysql
--localstatedir=/usr/local/mysql/data → -DMYSQL_DATADIR=/usr/local/mysql/data
--with-tcp-port=3306 → -DMYSQL_TCP_PORT=3306

その他のオプションについてはマニュアルをご参考ください。

ということで、cmakeが無い場合はコンパイルしてcmakeするとうまくいきます。
$ cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql
$ make
$ sudo make install


mysql_install_dbはパスが通ってないのか、ファイルがあるディレクトリに行かないとうまく動いてくれない。

# cd /usr/local/mysql/scripts/
# ./mysql_install_db



うまくいったら起動しましょう。
/usr/local/mysql/support-files/mysql.server start


mysql> show engines;
+--------------------+---------+------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+------------------------------------------------------------+--------------+------+------------+
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| CSV | YES | CSV storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
+--------------------+---------+------------------------------------------------------------+--------------+------+------------+


InnoDBがデフォルトストレージエンジンに変更されてます。

mysql> select @@innodb_version;
+------------------+
| @@innodb_version |
+------------------+
| 1.1.5 |
+------------------+


innodbプラグインもデフォルトで搭載


どうにかMySQLが入ったので、次にPHP5.3.6をインストール

$ ./configure --prefix=/usr/local/php \
      --with-apxs2=/usr/bin/apxs \
--with-mysqli=/usr/local/mysql/bin/mysql_config \
--with-pdo-mysql=/usr/local/mysql/bin/mysql_config

こちらはさすがにcmakeってことはないよね。





・・・あら?エラー?

checking for mysql_set_server_option in -lmysqlclient... no
configure: error: wrong mysql library version or lib not found. Check config.log for more information.


mysqlライブラリがないだとぅ?
調べてみると

$ ll /usr/local/mysql/bin/mysql_config
-rwxr-xr-x 1 root root 6924 3月 31 22:58 /usr/local/mysql/bin/mysql_config

ちゃんと存在してるわ!

心が病みつつhelpを読む

$ ./configure --help | grep mysql
--with-mysql[=DIR] Include MySQL support. DIR is the MySQL base
directory. If mysqlnd is passed as DIR,
--with-mysql-sock[=DIR] MySQL/MySQLi/PDO_MYSQL: Location of the MySQL unix socket pointer.
--with-mysqli[=FILE] Include MySQLi support. FILE is the path
to mysql_config. If mysqlnd is passed as FILE,
the MySQL native driver will be used [mysql_config]
--enable-embedded-mysqli MYSQLi: Enable embedded support
--with-pdo-mysql[=DIR] PDO: MySQL support. DIR is the MySQL base directory
If mysqlnd is passed as DIR, the MySQL native
--disable-mysqlnd-compression-support
Enable support for the MySQL compressed protocol in mysqlnd
--with-zlib-dir[=DIR] mysqlnd: Set the path to libz install prefix


ほうほう。
どうやらphp5.3系からはmysqlndというネイティブmysqlドライバが搭載されたようで、mysqlを使う場合は

--with-mysqli=[MySQLのベースディレクトリ]
--with-mysqli=mysqlnd


どちらかでいけるらしい。
mysql_configを指定してるのに入れてくれないのは何故かわからないが、とりあえずネイティブドライバを使うことにする。


$ ./configure --prefix=/usr/local/php \
      --with-apxs2=/usr/bin/apxs \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd


+--------------------------------------------------------------------+
| License: |
| This software is subject to the PHP License, available in this |
| distribution in the file LICENSE. By continuing this installation |
| process, you are bound by the terms of this license agreement. |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point. |
+--------------------------------------------------------------------+


今度はちゃんと通った。

あとは普通にmakeしてインストール

# make
# make install


ネイティブドライバが入った
20110426_94550.jpg

いちおうこれでコンパイルは通ったわけだけど、mysqliやmysqlpdoと全く同等にmysqlndが使えるのかどうかはこれから検証します。

とりあえず今回の作業で、毎日同じことだけ繰り返してると、いつの間にか周りに取り残されることだけは判りました(汗

このカテゴリーに該当する記事はありません。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。