モンスターカレンダー

« 2004年9月 »
123456789101112131415161718192021222324252627282930

2004年9月アーカイブ

Authでユーザ認証をしている。
ログイン機能と、ログイン中かどうかはマニュアルなどのサンプルで作った。(でもSmartyとからませて、エラーメッセージを出すのにはちょっと苦労したけど。。またこの話も書きたい)

ログイン中の場合に、その人の名前を出そうというお客さんの希望が出た。よく「XXさん、こんにちは」などとショッピングサイトででているやつ。
AuthでいうusernameはIDのことなので氏名とは違う。
要はユーザテーブルの他の情報を、ログイン時にとってこれればいいわけで。。。。

getAuthData() がそれか? 発行してみるが何も返ってこない。setAuthData()で、自力でセットした値だけを保持する器なのか?
だったら、ユーザテーブルにアクセスする時点で何か自分でコードを追加して保持させようか。

と、いろいろとあちこちにメッセージ入れて実行させて追って行って、、分かりました。
Authのインスタンス作成時にある指定をすると、ユーザレコードの内容を配列で取得し、getAuthData()で取れるようになるのでした。


$dsn=DATASET_NAME;
$params = array(
"dsn" => $dsn,
"table" => "user_table",
"usernamecol" => "user_id",
"passwordcol" => "pass",
"db_fields" => "*" //←ここ!!
);

$a = new Auth("DB", $params, "loginFunc", false);

$a->start();
$a->setIdle(300);
$a->setExpire(300);

$data = $a->getAuthData(); //これでユーザデータの配列がとれる

こんなのマニュアルのどこにも書いてないし。。ソースにしか書いてないし。。。。

DB_DataObjectをアップグレードしたら、CreateTable.phpがエラーになってしまい、テーブル定義の自動生成ができない。
1.5.3 より上の、1.6, 1.7ともだめだった。
Webでの検索にもエラーはひっかかってこない。

しばらく放置しておいたが、いつまでも古いままというのも情ない。じっくり調べてみた。

エラー:
db_dataobject_generator : 0 : CREATING FOR test

[db_error: message="DB Error: insufficient data supplied" code=-20 mode=return level=notice prefix="" info="SELECT c.relname as "Name"
FROM pg_class c, pg_user u
WHERE c.relowner = u.usesysid AND c.relkind = 'r'
AND not exists (select 1 from pg_views where viewname = c.relname)
AND c.relname !~ '^pg_'
UNION
SELECT c.relname as "Name"
FROM pg_class c
WHERE c.relkind = 'r'
AND not exists (select 1 from pg_views where viewname = c.relname)
AND not exists (select 1 from pg_user where usesysid = c.relowner)
AND c.relname !~ '^pg_' [nativecode=ERROR: relation "sql_features" does not exist]"]

その辺りのソースを見てみたり、iniファイルに何か設定すべきものが増えているのか?と最新のexample.iniを見てみたり(実際増えていたが、この現象とは関係ないものだった)。

ふと、「DB」パッケージをアップグレードしてみたらどうだろうか。。との考えが浮かんだ。
1.6.4(だと思う。。。もしかしたら1.6.2だったかも)→1.6.5へ。

で、実行してみたら、あっさり通ってしまいました。
そんなことだったのかぁぁぁぁ。

現在は DB_DataObject : 1.7.2 となりました。

=======================================

おまけ。iniファイルに、viewの定義も生成してくれる build_views という項目が増えていたので、1を設定してやってみた。
。。。が、エラーとなった。

エラー:

db_dataobject_generator : 0 : CREATING FOR test

[db_error: message="DB Error: insufficient data supplied" code=-20 mode=return level=notice prefix="" info="SELECT viewname FROM pg_views [nativecode=ERROR: relation "table_constraints" does not exist]"]

これも、そのうち。。。。

DB_DataObject.phpを見てみました。


function factory($table) {

//略
if (!$class) {
return DB_DataObject::raiseError(
"factory could not find class $class from $table",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
}
}

で、「DB_DataObject」のraiseErrorを呼び出していました。


function raiseError($message, $type = null, $behaviour = null)
{
global $_DB_DATAOBJECT;

if ($behaviour == PEAR_ERROR_DIE && @$_DB_DATAOBJECT['CONFIG']['dont_die']) {
$behaviour = null;
}

if (PEAR::isError($message)) {
$error = $message;
} else {
$error = PEAR::raiseError($message, $type, $behaviour);
}
// this will never work totally with PHP's object model.
// as this is passed on static calls (like staticGet in our case)

if (@is_object($this) && is_subclass_of($this,'db_dataobject')) {
$this->_lastError = $error;
}

$_DB_DATAOBJECT[
'LASTERROR'] = $error;

// no checks for production here?.......
DB_DataObject::debug($message,"ERROR",1);
return $error;
}

エラーの場合は、lastErrorにセットすると同時にたしかに PEAR::raiseError でreturnはちゃんとPEAR::Errorになってますね。
factoryはreturnで拾えるということですね。

しかし、他のメソッドは
...なんでもいいんですが、エラー時にはDB_DataObject::raiseErrorしてもそれはreturnしていないです。
return値はTrue/False。
内容を見るにはやはり _lastErrorを取得する必要がありますね。。

#なんでfactoryと同じようにPEAR::Errorを返してくれないんだろう。
#そして_lastErrorを取得するメソッドがないのは。。。?? _lastError使っていいんですね??

*** version : 1.5.3 ***

PEARのERRORの拾い方

| コメント(0)

PEARは本当に便利でいくつか使っているが、エラーの拾い方がよく分からなかった。

DBに関しては雑誌にもネットにもあって

$db = DB::connect($dsn);
if (PEAR::isError($this->db)) {
 $reason = $db->getMessage();
 return;
}

と、$dbオブジェクト自体をisErrorしていた。

DB_DataObjectなども同じかと思いそのように書いていたら実は違っていた。

$user = DB_DataObject::factory("m_user");
if (PEAR::isError($user->_lastError)) {
 $reason = $user->_lastError->getMessage();
 return;
}

と、$user->_lastError がPEARのエラーオブジェクトだった。。。

print_r($user);

としてみて、初めて知った事実(--;;

PEARは資料が少くて。。。。やってみて初めて分かる、またはソースをみて初めて分かるってことが多い。それでも徐々に情報は出てきているのだけど。

ちょっと気になるのが 「_(アンダースコア)」付きのメソッド(プロパティ)ってプライベートなのか。。外から呼んじゃいけないのか。。。。でも他に呼ぶ手立てが、ない。はず。

xmllib また使ってみる

| コメント(0)

よく使うような使いかた。

あるXMLデータを加工する。DOMです。




appleredfood


pikminredcreature?


pikminyellowcreature?


goldenkiwiyellowfood


lemonyellowfood


cucumbergreenfood

--------------------------------------------------------------------------------

(1)とりあえず全データを配列に入れる。

■スクリプト

require_once("XML/Parser.php");
define("CHAR_CODE", "EUC-JP");
 echo "";
 echo '';
 echo "";
 test1();
 echo "";
 echo "";

//すべてよみこみ、配列化
function test1(){

$doc = domxml_open_file("xmltest31.xml",
DOMXML_LOAD_DONT_KEEP_BLANKS); //不要な空白等除去

$color_nodes = $ctx->xpath_eval("/alldata/data");
$elements = $color_nodes->nodeset;
foreach ($elements as $data) {
 $nodes = $data->child_nodes();
 foreach ($nodes as $node) {
 $array[$node->tagname] = $node->get_content();
}
 $data_array[] = $array;
}

print_r($data_array);
}

■実行結果

Array (
[0] => Array ( [name] => apple [color] => red [kind] => food )
[1] => Array ( [name] => pikmin [color] => red [kind] => creature? )
[2] => Array ( [name] => pikmin [color] => yellow [kind] => creature? )
[3] => Array ( [name] => golden kiwi [color] => yellow [kind] => food )
[4] => Array ( [name] => lemon [color] => yellow [kind] => food )
[5] => Array ( [name] => cucumber [color] => green [kind] => food )
)

--------------------------------------------------------------------------------

(2)特定の条件のデータを配列に入れる。
XPathを使用して絞りこむ

■スクリプト

function test2(){

$doc = domxml_open_file("xmltest31.xml",
DOMXML_LOAD_DONT_KEEP_BLANKS); //不要な空白等除去

$ctx = xpath_new_context($doc);

$target = 'red';
$color_nodes = $ctx->xpath_eval("/alldata/data/color[text()='" . $target . "']"); //color="red"を抽出
$elements = $color_nodes->nodeset;
foreach ($elements as $element) {
 $node = $element->parent_node(); //親=dataノード取得
 $nodes = $node->child_nodes();
 foreach ($nodes as $val) {
  $array[$val->tagname] = $val->get_content();
 }
$data_array[] = $array;
}
print_r($data_array);
}

■実行結果

Array (
[0] => Array ( [name] => apple [color] => red [kind] => food )
[1] => Array ( [name] => pikmin [color] => red [kind] => creature? )
)

--------------------------------------------------------------------------------

(3)特定の条件のデータを配列に入れる:日本語データの場合

いろいろ試してみたところ、UTF-8で比較する必要があるようだ。
DOM関数を使用した時点でUTF-8となってしまう?
どこかで指定できるのかとマニュアル見てみたが、分からず。




りんごあかたべもの


ピクミンあかいきもの?


ピクミンきいろいきもの?


ゴールデンキウイきいろたべもの


レモンきいろたべもの


きゃべつみどりたべもの

■スクリプト

function test3(){

$doc = domxml_open_file("xmltest31.xml",
DOMXML_LOAD_DONT_KEEP_BLANKS); //不要な空白等除去

$ctx = xpath_new_context($doc);

$target = 'きいろ';
$target = mb_convert_encoding($target, "UTF-8", "EUC-JP"); //文字コード変換
$color_nodes = $ctx->xpath_eval("/alldata/data/color[text()='" . $target . "']");

$elements = $color_nodes->nodeset;
foreach ($elements as $element) {
 $node = $element->parent_node(); //親=dataノード取得
 $nodes = $node->child_nodes();
 foreach ($nodes as $val) {
//内部文字コードに変換
  $tag = mb_convert_encoding($val->tagname, "EUC-JP", "UTF-8");
  $cont = mb_convert_encoding($val->get_content(), "EUC-JP", "UTF-8");
  $array[$tag] = $cont;
 }
$data_array[] = $array;
}
print_r($data_array);
}

■実行結果

Array (
[0] => Array ( [name] => ピクミン [color] => きいろ [kind] => いきもの? )
[1] => Array ( [name] => ゴールデンキウイ [color] => きいろ [kind] => たべもの )
[2] => Array ( [name] => レモン [color] => きいろ [kind] => たべもの ) )
)