拡張機能のセクションではユーザーインターフェースと関係のない しばしば必要とされるアプリケーション機能を提供する非GUIクラスを カバーしています。いくつかの拡張クラスはコア機能に依存していますが、 その他は独立したクラスとなっています。
拡張クラスは prepend.php3
によって自動的にインクルー
ドされない点でコアクラスとは区別されます。必要に応じて明示的に
クラス定義をインクルードするか prepend.php3
を改変する必要があります。
Cartクラスはプログラム上は独立クラスですが、
インスタンスが何らかの持続性を有している場合にのみ意味があります。
Cartクラスは、その start()
関数でセッション変数として
自身を自動的に登録します。
Cartクラスは買い物かご(Shopping Cart)を実装しています。 現時点では、買い物かごの中の品物はそれぞれ独立しています。 かごは単純な品物だけを持つことができます。それが機能するために他の品物を 必要としたり、それに依存する品物への基礎を提供するといった複合品目の サポートは将来追加されます。
単純品目の例としては、他のオプションを持たない品物すべて、 例えばリンゴや本などがあげられます。複合品目の一般的な例としては、 ピザ(アメリカ、イタリアいずれのスタイルにおいても、正しく機能する ためにはトッピングとチーズが必要です)およびコンピュータシステム (正しく機能するためには、ケース、マザーボード、RAM、ビデオカード等が 必要です)があります。
注意: Cart
はリリース5まではコアクラスで
した。もしあなたのアプリケーションが Cart
クラスを使って
いるなら、あなたは明示的にあなたのファイルで指示されている
prepend.php3
ファイル内に include("cart.inc")
文を
加えなければなりません。
注意:ページ管理関数はcart
機能について
Cart クラスを準備し開始する機能をもはやサポートしません。
cartを自動的に開始する代わりにSession
のauto_init
機能を用いるか、cartを手動で設定することが推奨されます。
classname | シリアル化ヘルパー:このクラスの名前です。 |
persistent_slots | シリアル化ヘルパー:全ての持続的スロットの名称。 |
item | カゴの中の品物を示す多次元配列 |
currentItem | 品物の位置を示すカウンター |
|
指定した品目番号$art
を持つ品物がカゴの中にあるかどうかを
チェックします。ブール値と整数値の配列を返します。もしブール値がtrue なら
カゴ中の品目番号に対応する品種の個数が戻ります。
現在のカゴの中のすべての品物を削除し、$this->currentItem を1に リセットします。常にtrueを返します。
現在の買い物カゴの中の品目数を返します。もしカゴが空ならfalseを返します。
互換性上の理由から、この機能は tot_arts
としても存在します
(が、もしこの名前を使用した場合には警告が出力されます)。
品目番号$art
を持つ品目を$num
個現在の買い物
カゴに追加します。買い物カゴ内の $art
の位置を示す数字
(位置番号)を返します。
もし十分な個数が
買い物カゴから品目番号 $art
を持つ品目を $num
個削除します。
ただし、削除する個数以上の物が買い物カゴにある場合に限ります。
もし成功すれば
$art
の位置番号を返し、もしカゴから取り除くのに$art
が
十分な個数を持っていなければ false を返します。もしこの関数が false を返したら
カゴはいかなる変更も受けません。
買い物カゴの中の品種番号 $art
の個数を正確に $num
個に
セットします。もし $num
がゼロならば、品目はカゴから取り除かれます。
買い物カゴ中の $art
の位置番号を返します。
もし買い物カゴが空ならば、show_empty_cart()
を一度コールし
復帰します。
show_item_open()
を買い物カゴの一覧表示を開始する時に一度コールし、
次に買い物カゴの各品物ごとに show_item()
をコールします。買い物カゴ
一覧表示の終了時に show_item_close()
を一度コールします。
この関数はユーザーが提供するべきです。カートからある一つの品物を
表示するための HTML 文を生成します。$art
はその品物の品目番号で
あり、カゴにはそれが $num
個あります。
この関数はユーザーが提供するべきです。買い物カゴ一覧を表示するときに 先立って表示される HTML を生成します。
この関数はユーザーが提供するべきです。買い物カゴ一覧を表示するときに 最後に表示される HTML を生成します。
この関数はユーザーが提供するべきです。空のカゴを象徴する適切な メッセージを出力します。
show_item()
の実装を提供するために Cart
の
サブクラスを用います。
class My_Cart extends Cart {
var $classname = "My_Cart";
// 品目の個数を求める
var $database_class = "DB_Article";
var $database_table = "articles";
var $db;
var $sum = 0;
function show_cart_open() {
printf("<table class=cart_table>\n");
$this->sum = 0;
}
function show_cart_close() {
printf("</table>\n");
printf("全部で %s 個あります\n", $this->sum);
}
function show_item($art, $num) {
if (!is_object($this->db)) {
$class = $this->database_class;
$this->db = new $class;
}
$query = sprintf("select * from %s where artid = '%s'",
$this->database_table,
$art);
$this->db->query($query);
while($this->db->next_record()) {
printf(" <tr class=cart_row>\n <td class=cart_cell>%s</td>\n",
$this->db->Record["name"]);
printf(" <td class=cart_cell>%s</td>\n",
$this->db->Record["price"]);
printf(" <td class=cart_cell>%s</td>\n",
$num);
$rowsum = $num * $this->db->Record["price"];
$this->sum += $rowsum;
printf(" <td class=cart_cell>%s</td>\n",
$rowsum);
printf(" </tr>\n");
}
}
}
カゴを使用する際には、Cart
サブクラスのインスタンスを作成し、
start()
をコールしてください。これにより、自動的にcart
が
登録されます。
local.inc
中のSession
サブクラス中の
スロット$auto_init
を値setup.inc
に設定し、
以下のコードを含む同名のファイルを作ることが推奨されます。
global $cart; // $cart はグローバル変数
$cart = new My_Cart; // My_Cart インスタンス名を $cart にする
$cart->start(); // そしてそれにそれ自身を登録させる
作成したCartを動作させる際には、add_item()
とremove_item()
を使用して下さい。
$cart->add_item("101", 2); // "101" 番を2個追加
$cart->remove_item("101", 1); // "101" 番を1個削除
カゴの中身を表示するためには、show_all()
を使用して下さい。
$cart->show_all(); // とにかくカゴの中身はなんだい?
Cart クラスを用いる際には、データベース中に自分の店が 販売する全ての品目をリストする新しいテーブルを定義する必要があります。。 PHPLIBとMySQLの組み合わせでは、それぞれの仮想Webサーバー毎に PHPLIB のインスタンスを生成し、それぞれの顧客ごとに新しいデータベースを 生成することが推奨されます。 このデータベースは、物品リストのようなアプリケーション固有の テーブルと同時にactive_sessionsやauth_userテーブルを保持する必要があります。 言い換えると、MySQLと組み合わせる場合には、PHPLIBとMySQLディレクティブとで database_nameを共有することは絶対にやめるべきです。 もしそうしたとしても何のサポートもありません。 (もっとも、PHPLIB はオープンソースであり、あなたは あなた自身のリスクにおいて使っているので、私たちの言うとおりやったと しても何の保証もありませんが・・)
ここで、大変簡単な新規テーブル articles
を
以下のような構造で定義したと仮定しましょう。
# テーブル 'articles' の構造
#
CREATE TABLE articles (
name text,
price float(8,2),
artid int(11) DEFAULT '0' NOT NULL auto_increment,
PRIMARY KEY (artid)
);
このテーブルは artid
と呼ばれる品目番号を持ち、それぞれの
artid
ごとに品目の説明 name
と価格
price
があります。この最小限の定義に品種グループを追加するとか、
品種の画像などを格納するための BLOB を追加するなど目的に応じて拡張すること
が可能ですが、例を示すという意味ではこれで充分です。
このテーブルに目的に応じていくつかの製品を登録して下さい。
次なるステップは、cart クラスをPHPLIBに教えることです。 そうするためには以下の3つのステップが必要です。
Cart
クラスを全てのページでインクルードしなければいけません。
Cart
クラスを使わないページにおいてもです。
Cart
を使うページにおいて、cart サブクラスをインスタンス化し保存します。
続く全てのページでその Cart
オブジェクトが再現され、またCart
オブジェクトを再現可能とするために、PHPはCart
オブジェクトの内容を知る必要が
あります。ユーザーが最初の品物を Cart
に入れた後に
どのページをユーザーが読み出すかを知ることはできないので、全ての
ページにCart
の定義を含める必要があります。
したがって、cart.inc
によりCart
定義をインクルードする設定を
指定するのに適切な場所はprepend.php3
です。
prepend.php3
を編集し、このファイルのコメントにしたがって
require("cart.inc")
を加えます。
Cart
のサブクラスを目的に応じて作成します。
Cart
のサブクラスを、この例ではExample_Cart
として
コールします。実際には好きな名前を付けていいですが、それを一貫して用いなければなりません。
Example_Cart
の定義は local.inc
のどこかで定義した
Example_Session
の定義の下に置きます。これは以下のようになります。
class Example_Cart extends Cart {
var $classname = "Example_Cart";
}
auto_init
呼ばれています。
local.inc
を開き、Session
のサブクラスを
編集してください。以下のような内容を含むコードを書くと思います。
class Example_Session extends Session {
var $classname = "Example_Session";
...
}
Example_Session
の定義に追加します。
var $auto_init = "setup.inc",
setup.inc
ファイルを
作成します。このファイルにあるコードは、新しいセッションを生成するたびに
実行されます。そのコードは、$sess
, $auth
,
$perm
オブジェクトがロードされ初期化された後に実行されますが、
関数コンテキスト内で実行されます。その関数コンテキストからエクスポートしたい
全ての定義についてglobal
とする必要があります。
setup.inc
内で$cart
という名前で
Example_Cart
のグローバルなインスタンスを生成し、
PHPLIBにその変数を登録して下さい。
<?php
global $cart;
$cart = new Example_Cart;
// $sessは既にグローバル変数です。
$sess->register("cart");
?>
ここまでの作業によりPHPLIBを用いる全てのページでデフォルトで利用可能な
$cart
オブジェクトが作成されました。このオブジェクトは
セッション開始時に自動的に生成され、PHPLIB のセッション管理によって
ページからページへと伝達され、セッション記録を刈り取るガーベージコレクションで
削除されます。cartクラスについてこれ以上心配する必要はなく、単純に
page_open()
と page_close()
の間で常に使用する
ことができます。PHPLIBが残りの作業を行います。
実際Cart
クラスはほとんど何もしません。
このクラスは、ユーザーが購入した商品の記録を保持する配列
$cart->item[]
を維持します。
各要素$cart->item[$x]
は、$cart->item[$x]["art"]
(ユーザーの購入希望商品の品目番号)と$cart->item[$x]["num"]
(購入希望のその品目番号の商品の個数)からなっています。
$cart->currentItem
は、$cart->item[]
に商品を
追加する際に用いられる$xの次の値です。
買い物カゴに品目を追加するには以下のようにして下さい。
You add articles to the shopping cart with
$x = $cart->add_item($art, $num)
これにより品目番号$art
の$num
個の品物がカゴに
追加されます。既に同じ品目番号の品物を持っていた場合には、この品目の個数が
$num
だけ加算されます。
そうでなければ新しい品目エントリが作成され、$num
にセットされます。
この関数は、インデックス番号$x
をその品目の$cart->item[]
配列に返します。
買い物カゴから品物を削除するには、以下のようなコードを使用します。
$x = $cart->remove_item($art, $num)
これにより、カゴに十分な個数の商品が入っていたら、カゴから当該品目番号
$art
を持つ商品を$num
だけ削除します。
カゴに$art
がないか、カゴに$art
が$num
個
ない場合には、この関数はfalseを返し、カゴからは何も削除しません。
それ以外の場合、品目番号$art
を持つ商品が$num
個だけ
カゴから取り除かれ、その結果当該品目の個数がゼロになったら配列からその要素は
削除されます。
ある品種についてカゴの中にいくつあるかチェックすることができます。
list($have, $num) = $cart->check($art)
このチェック関数は二つの要素をもつ配列を返します。対象の品目がカゴの中に
あったら最初の要素 $have
は true です。$have
が
true であれば、$num
はカゴの中のその品目ごとの個数を保持し、
そうでなければ $num
は未定義です(実際には 0 ですが、それを
あてにしてはいけません)。
ついに私たちは以下の関数を使用します。
$cart->show_all()
このコードは、買い物カゴを走査し、Example_Cartに対して商品のリストを
生成する際にコールすることが可能です。
この関数は、最初に$cart->show_cart_open()
をコールします。
作成したサブクラスでこの関数のコード実装を提供することが可能です。
次にカゴの中の各商品について$cart->show_item($art, $num)
を
コールします。
デフォルトのCartの実装では意味のあることはしないようになっていますが、
Example_Cart
においてより洗練されたコードを提供することも可能です。
カゴの一覧表示の終わりに$cart->show_cart_close()
がコールされます。
ここでも独自のコードを実行させることができます。
前のセクションの例では、Cart サブクラスのより洗練された実装を
示しています。その実装においてshow_cart_open()は、
(CSSクラスでフォーマットされた)表の開始タグを生成し、
カウンター $cart->sum
をゼロにセットしています。
show_cart_close()では表が閉じられ、$cart->sum
の
カウンターが表示されます。
容易に想像できるかと思いますが、show_item($art, $num)
はそれぞれの
品目番号についてデータベースに問い合わせを行い、記述と価格を取り出し、最終的に
各商品の個数を考慮しながら全ての値段を合計しています。
更にこの関数は、表の行を作成し、顧客に見易い伝票を出力します。
注意: もしこれが FastTemplates のようなものだと思っているならば、 注意して読んでください。そうではありません。
Template クラスにより、PHP のコードを全く含まない、しかし置換可能な 複数のフィールドを有するHTMLコードを保持することを可能にします。 このクラスは、置換用フィールドに任意の文字列を代入することが可能な 関数を提供します。代入する文字列は、表全体といったように非常に 大きなものとすることができます。
classname | 文字列。シリアル化ヘルパ。このクラスの名前です。 |
debug | 論理値。trueに設定された場合、このクラスはデバッグ用出力を行います。 |
unknowns | "keep", "comment", "remove" (デフォルト)のどれかです。 Templateの出力時に未解決の変数名をどのように扱うかを定義します。 "keep"が設定された場合、それらの変数名はそのままにされます。 "comment"が設定された場合、未解決の変数名はエラーを報告するHTMLコメントに変形されます。 "remove"設定された場合、未解決の変数名は暗黙の内に削除されます(デフォルト)。 |
halt_on_error = "yes" | "yes" (デフォルト), "report", "no" のどれか一つ。 Temlateのエラー処理条件を定義します。"yes"に設定された場合(デフォルト)、 エラーが報告され、実行が中断されます。 "report"が設定された場合にはエラーが報告され"false" を返しますが、実行は継続されます。 "no"が設定された場合、エラーは暗黙の内に無視され、"false"を返しますが、実行は継続されます。 |
last_error = "" | この変数に直近のエラーメッセージを保持します。 |
|
file | 文字列のハッシュ。変数名をファイル名に変換する変換テーブル。 |
root | 文字列(パス名)。templateのファイルがロードされる際のベースになるディレクトリ。 |
varkeys | 文字列のハッシュ。変数名をその変数名に関する正規表現へと変換する変換テーブル。 |
varvals | 文字列のハッシュ。各varkeysについて変数名を置換する値に 変換する変換テーブル。 |
|
コンストラクタ。2つの省略可能なパラメータを付けてコールされます。
最初のパラメータはtemplateのディレクトリ(set_root()
を
参照)を設定し、2番目のパラメータは未定義の変数の処理に関する
ポリシーを設定します。
この関数は、$root が適正なディレクトリかどうかチェックし、 templateを格納するベースディレクトリとしてこのディレクトリを設定します。
この関数は未解決の変数名の処理に関する指針を設定します。設定される値は、 "remove", "comment", "keep" のどれかになります。 "keep"が設定された場合、それらはそのままにされます。 "comment"が設定された場合、未解決の変数名はエラーを報告する HTML コメントに変形されます。"remove" に設定された場合、 未解決の変数は黙って削除されます(デフォルト)。
この関数は、変数の初期値を定義するファイルの名前を定義します。 これは、$handle/$filenameの組もしくは$handle/$filenameの組の ハッシュでコールすることが可能です。 ファイルはこの時点ではまだ参照されず、必要な時に初めて参照されます。
変数$parentは$handleで名前が指定された変数ブロックを保持することが できます。この関数は$parentからその変数ブロックを取り除き、 $nameという名前の変数リファレンスに置換します。 $nameを省略した場合、この名前は$handleと同じとみなされます。
この関数は、変数の初期値を設定します。 初期値は、$varname/$value の組または$varname/$valiue の組のハッシュ でコールすることが可能です。
この関数は、$handle で名前が指定された変数のうち、定義済みの 値を持つものを全て返します。結果文字列は "最終的なもの" ではありません。 すなわち、未定義の変数名に関する指針はまだ適用されていません。
この関数は、print $this->subst($handle)
の短縮形です。
この関数は、$handleという名前の全ての定義済み変数の値を置換し、 $targetという名前の変数に結果を格納するか付加します。
$handleが変数名の配列の場合、$appendは無視されます。 $handleという名前の変数は順番に置換され、それぞれの 置換処理の結果は$targetに格納されます。置換結果は、 $targetという名前の変数において順番に$handleに関する処理結果を たどることにより参照可能です。
print $this->parse(...)
の短縮形です。
全ての定義ずみの変数の値のハッシュをその変数名がキーとして定義された 状態で返します。
$varname で名前が指定されている変数の値を返します。$varname が あるファイルを参照し、そのファイルがまだロードされていない場合には、 その変数はemptyとして報告されます。
変数名の配列が指定してコールした場合には、 それらの名前をキーとして定義したハッシュが返されます。
この関数は、$handle 中の未解決の変数名を変数名をキーとしたハッシュ (つまり、$a[$name] = $name の形式のハッシュ)として返します。
この関数は、$str の最終バージョンを返します。すなわち、 未解決の変数名に関する指針は、$str にも適用されます。
この関数は $varname で名前が指定された変数の値の最終バージョンを出力します。
この関数は $varname で名前が指定された変数の値の最終バージョンを返します。
この関数は、 作成するTemplateサブクラスにより上書きすることが可能です。 表示するエラーメッセージを引数としてコールされます。
相対パス名でコールされた際に、この関数は $this->root が先頭に 付加されたパス名を返します。絶対パス名は変更されません。
filenameで指定されるファイルは存在している必要があり、 さもなくばエラーが発生します。
この関数は指定した変数名に関する変数名の正規表現を作成します。
ある変数が未定義(unknown)か空(empty) であり、ファイル名が後ろに付いている場合、後続のファイルが ロードされ、そのファイルの内容はその変数の値として代入されます。
この関数はエラーが起きたときにコールされ、 $this->halt_on_error で定義されたポリシーに従ってエラーが処理されます。
このクラスは、文字列で一連の変数を管理します。これらの文字列は "{変数}" の形式で他の変数へのリファレンスを含んでいます。パースされるか 置換された際にこの変数へのリファレンスはその変数の値で置換されます。
変数の値は、set_var("name","value")
をコールすることにより
手動で定義することが可能で、また、set_file("name","filename.ihtml")
をコールすることによりファイルで定義することも可能です。
後者では、ファイルの内容は(可能な限り遅くまで)必要に応じてロードされ、
その変数の値として設定されます。
変数の値を定義する3番目の方法は、set_block("parent",
"block", "name");
をコールすることです。この場合、
parent
で名前が指定された変数の中の
<!-- BEGIN block -->
で始まり <
!-- END block -->
で終わる文字列ブロックが検索されます。
この文字列は変数 parent
から取り除かれ、
block
で名前が指定された変数に代入されます。
代わりにparent
においてname
への変数リファレンスが
置換されます。
オプションのパラメータ "name"
が省略された場合、
"block"
が代わりに使用されます。
Template
を直接使うか、または必要に応じて
Template
のサブクラスを定義して下さい。
page.ihtml という名前のtemplateファイルを以下のように定義します。
<html>
<head><title>{PAGETITLE}</title></head>
<body bgcolor="#ffffff">
<table border=1 cellpadding=4 cellspacing=0 bgcolor="#eeeeee">
<tr>
<td colspan=2><h1>{PAGETITLE}</h1></td>
</tr>
<tr>
<td>{OUT}</td>
<td>Content</td>
</tr>
</table>
</body>
</html>
このファイルは、変数pagetitle
およびout
という
名前の変数へのリファレンスを有しています。
これとは別の box.ihtml という名前のtemplateファイルは、
3つの変数リファレンス {TITLE}, {NUM}, {BIGNUM} を有するrowという
名前のブロックを有しています。
<!-- start box.ihtml -->
<table border=1 bgcolor="#cccccc" cellpadding=4 cellspacing=0>
<tr>
<td colspan=2><b>{TITLE}</b></td>
</tr>
<!-- BEGIN row -->
<tr>
<td>{NUM}</td>
<td>{BIGNUM}
</tr>
<!-- END row -->
</table>
<!-- end box.ihtml -->
以下の php3 ファイルはこれらのtemplateの使い方を示しています。
<?php
include("./template.inc");
# $t という名前のTamplateのインスタンスを作成
$t = new Template("/page/to/webserver/template", "keep");
# page と box という名前の、ファイルを参照する変数を定義
$t->set_file(array(
"page" => "page.ihtml",
"box" => "box.ihtml"));
# "box" から "row" という名前のブロックを抽出し、
# "box" の {rows} へのリファレンスを作成
$t->set_block("box", "row", "rows");
# 変数 TITLE と PAGETITLE を定義
$t->set_var(array("TITLE" => "Testpage",
"PAGETITLE" => "hugo"));
# NUM と BIGNUM を定義し、"row" を "rows" に追加...
for ($i=1; $i<=3; $i++) {
$n = $i;
$nn = $i*10;
$t->set_var(array("NUM" => $n, "BIGNUM" => $nn));
$t->parse("rows", "row", true);
}
# box から out を作成し、次に page から out を作成...
$t->parse("out", array("box", "page"));
# 完了したら出力
$t->p("out");
?>
<hr>
<?php
# もしあれば、未定義の変数をレポートします
print implode(", ", $t->get_undefined("rows"));
?>