XOOPS Cubeの開発者なら必ず入れておきたいデバッグツール AdelieDebug について紹介します。
AdelieDebug(アデリーデバッグ)は、XOOPS Cube Legacy や TOKYOPen でモジュール・プリロードなどを開発するデベロッパー向けのパワフルな開発支援ツールです。どのあたりが、パワフルかいくつか特徴を紹介しましょう。
XOOPS Cube標準のデバッグモードでは、PHP・MySQL・Smartyなど各モードを切り替えなければなりません。一方、AdelieDebugではPHP・MySQLをひとつの画面に出すことができます。PHPについては、エラーがあれば赤でハイライトされて表示されるので、標準のものと違い見落とす危険性が少ないです。MySQLについては、クエリーログを表示します。もちろんエラーが起こっているクエリーはハイライト表示がされます。加えて、var_dump()で確認することが多い、$_GET, $_POST, $COOKIE, $_FILES, $_SESSION, $_SERVER, 送信されたHTTPヘッダなどの環境変数も自動で表示してくれます。
PHPやSQLのログはひとつのタイムラインにまとめて表示してくれます。これにより、処理の時系列や前後関係が把握しやすくなっています。例えば、あるクエリーがどこで発行されているか知りたい場合があります。従来であれば、var_dump(__FILE__, __LINE__); を随所に仕込んだうえで、出力されたファイル名と行数をなんとなく頭の中にいれて判断するといった具合でした。AdelieDebugでは、adump() を任意の箇所に仕込めば、タイムライン上でadump()とクエリーの関係を一目で知ることが可能です。
AdelieDebugは便利なデバッグ関数を提供します。それはvar_dump()よりも強力で、var_dump()+Xdebugよりも導入が簡単です。
adump(): var_dump()関数と同じ働きをしますが、出力内容を<pre>タグで囲むので見やすくなっています。var_dump()は、あちこちに仕込むとどこに仕込んだた分からなくなることがありました。adump()は仕込んだファイル名と行数を表示するので、見失う心配がありません。
adump($uid);
atrace(): その行がどの関数で呼ばれているかを表示します。PHPビルトイン関数のdebug_print_backtrace()と同等の働きをしますが、debug_print_backtrace()のようにメモリオーバーになる心配はありません。
atrace();
awhich(): オブジェクトやクラス、関数がどのファイルの何行目で定義されているかを表示します。awhich()を使えば、わざわざファイル全体をgrep検索する必要はありません。
awhich('Legacy_Controller');
awhich($mRoot);
asynop(): クラスやインターフェイスの概要(synopsys)を表示します。継承した親クラス、実装したインターフェイス、クラスが持っている定数・プロパティ・メソッドが一目でわかるようになります。
asynop('Legacy_Controller');
asynop($this);
XOOPS Cube Legacy は標準出力をバッファでのみこんでしまいます。なので var_dump() しても何も表示されず、すぐあとに exit() をつけないといけませんでした。さもなければ、<{stdout}>をテーマに書く必要がありました。AdelieDebugは、そのような手間は不要です。XOOPSのob_bufferを自動的に回避するからです。
var_dump() は問答無用で文字列を出力します。なので、XML出力画面にダンプしてしまって、Ajaxのテストがうまくできない、なんてことがありました。AdelieDebugでは、AJAXリクエストのときやHTML出力以外のコンテクストではデバッグ出力を自動でオフにすることで、そういったストレスを軽減します。
AdelieDebug は開発現場から生まれた実践的ツールです。XOOPSを用いたシステム開発を数多く手がける株式会社RYUSでは(地道な布教活動により 笑)プログラマに広く活用されています。
AdelieDebug はプリロードといわれるワンファイルのXOOPS Cube用のプラグインです。ですので、導入は至って簡単。こちらのAdelieDebug.class.phpをダウンロードして、 preload フォルダに放り込むだけです。
不要になった場合は、このプリロードを削除します。
PHP: array_diff - Manualをよく読むと、こんな注意書きが。
注意:
二つの要素は、(string) $elem1 === (string) $elem2 の場合のみ等しいと見直されます。言い換えると、文字列表現が同じ場合となります。
要素が配列だと、string(5) "Array"同士の比較になっちゃうのね(´・ω・`)
Please see here: http://drrrchat.com/localize.php
If your language has not be translated yet, I hope you translate it to your language. Copy English, just translate gray parts into your language, and please post it as this blog comment below↓. With the translation, I need to know how your language is written in your language. For example, Japanese is written as '日本語' in Japanese.
配列をデータベースやテキストファイルに保存したいときってありますよね。リレーショナルデータベース的には、ちゃんと最適化すべきだけど、並び替えや検索する必要がない場合は、とりあえず配列を文字列として保存したりします。serialize()関数を使う方法はよく知られています。この関数以外にも、PHPでは配列を文字列に変換できるものがあります。このエントリーでは、serialize()、var_export()、json_encode()、http_build_query()の4つの使い方について書きます。
今回文字列化を試す変数は、bool型・int型・float型・string型・添字配列・連想配列を含んだ連想配列です。
$data = array(
'bool' => true,
'int' => 1,
'float' => 1.23,
'string' => 'foobar',
'array' => array('apple', 'orange', 'strawberry'),
'key-value' => array(
'jp' => 'Japan',
'us' => 'USA',
'cn' => 'China',
),
);
この関数は変数を文字列化できることでよく知られています。変換された文字列は型・大きさ・値を保持するようになっています。
$serial = serialize($data);
var_dump($serial);
// string(285) "a:6:{s:4:"bool";b:1;s:3:"int";i:1;s:5:"float";d:1.229999999999999982236431605997495353221893310546875;s:6:"string";s:6:"foobar";s:5:"array";a:3:{i:0;s:5:"apple";i:1;s:6:"orange";i:2;s:10:"strawberry";}s:9:"key-value";a:3:{s:2:"jp";s:5:"Japan";s:2:"us";s:3:"USA";s:2:"cn";s:5:"China";}}"
シリアライズされた文字列を、再び配列に戻すにはunserialize()関数を使います。元のデータをしっかり復元してくれます。
$serialImported = unserialize($serial);
var_dump($serialImported);
/*
array(6) {
["bool"]=>
bool(true)
["int"]=>
int(1)
["float"]=>
float(1.23)
["string"]=>
string(6) "foobar"
["array"]=>
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(6) "orange"
[2]=>
string(10) "strawberry"
}
["key-value"]=>
array(3) {
["jp"]=>
string(5) "Japan"
["us"]=>
string(3) "USA"
["cn"]=>
string(5) "China"
}
}
*/
var_dump($data === $serialImported); // true
var_export()関数はPHPとして解釈可能な文字列に変換します。第二引数に何も指定しないと、文字列に変換した結果が出力されます。変数に代入するときは第二引数にtrueを指定します。
$php = var_export($data, true);
var_dump($php);
/*
string(267) "array (
'bool' => true,
'int' => 1,
'float' => 1.23,
'string' => 'foobar',
'array' =>
array (
0 => 'apple',
1 => 'orange',
2 => 'strawberry',
),
'key-value' =>
array (
'jp' => 'Japan',
'us' => 'USA',
'cn' => 'China',
),
)"
*/
var_export()関数には、unserialize()関数のようにインポートする直接的に対応する関数はありません。そのかわりに、eval()関数で文字列を評価します。
eval('$phpImported = '.$php.';');
var_dump($phpImported);
/*
array(6) {
["bool"]=>
bool(true)
["int"]=>
int(1)
["float"]=>
float(1.23)
["string"]=>
string(6) "foobar"
["array"]=>
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(6) "orange"
[2]=>
string(10) "strawberry"
}
["key-value"]=>
array(3) {
["jp"]=>
string(5) "Japan"
["us"]=>
string(3) "USA"
["cn"]=>
string(5) "China"
}
}
*/
var_dump($data === $phpImported); // true
json_encode()関数は、JSON形式の文字列に変換します。この関数はPHP5.2で導入されました。
$json = json_encode($data);
var_dump($json);
// string(143) "{"bool":true,"int":1,"float":1.23,"string":"foobar","array":["apple","orange","strawberry"],"key-value":{"jp":"Japan","us":"USA","cn":"China"}}"
再び配列に戻すときはjson_decode()関数を使います。第二引数を指定しないと、戻り値がオブジェクト型になります。戻り値を配列型として受け取るには、第二引数にtrueを指定する必要があります。
$jsonImported = json_decode($json, true);
var_dump($jsonImported);
/*
array(6) {
["bool"]=>
bool(true)
["int"]=>
int(1)
["float"]=>
float(1.23)
["string"]=>
string(6) "foobar"
["array"]=>
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(6) "orange"
[2]=>
string(10) "strawberry"
}
["key-value"]=>
array(3) {
["jp"]=>
string(5) "Japan"
["us"]=>
string(3) "USA"
["cn"]=>
string(5) "China"
}
}
*/
http_build_query()関数は、配列をクエリーストリング形式に変換します。この関数はPHP5から利用できます。
$query = http_build_query($data); var_dump($query); // string(170) "bool=1&int=1&float=1.23&string=foobar&array%5B0%5D=apple&array%5B1%5D=orange&array%5B2%5D=strawberry&key-value%5Bjp%5D=Japan&key-value%5Bus%5D=USA&key-value%5Bcn%5D=China"
デコードには、parse_str()関数を使います。第二引数を指定しないとextract()関数のように、配列のキーで変数を定義します。第二引数を変数すると、デコードした結果がその変数に代入されます。parse_str()関数はすべて文字列型に解釈するので注意が必要です。
parse_str($query, $queryImported);
var_dump($queryImported);
/*
array(6) {
["bool"]=>
string(1) "1"
["int"]=>
string(1) "1"
["float"]=>
string(4) "1.23"
["string"]=>
string(6) "foobar"
["array"]=>
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(6) "orange"
[2]=>
string(10) "strawberry"
}
["key-value"]=>
array(3) {
["jp"]=>
string(5) "Japan"
["us"]=>
string(3) "USA"
["cn"]=>
string(5) "China"
}
}
*/
var_dump($data === $queryImported); // false
氷川 XOOPS Module 開発室