[GENERIC] Zend_Translate:
[zend.git] / documentation / manual / ja / module_specs / Zend_Db_Table_Rowset.xml
blob52a7845315720e860e4c89ca3437948aed9fd59c
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <!-- EN-Revision: 20766 -->
4 <sect1 id="zend.db.table.rowset">
6     <title>Zend_Db_Table_Rowset</title>
8     <sect2 id="zend.db.table.rowset.introduction">
10         <title>導入</title>
12         <para>
13             テーブルクラスに対して <methodname>find()</methodname>
14             あるいは <methodname>fetchAll()</methodname> メソッドでクエリを実行すると、
15             返される結果は <classname>Zend_Db_Table_Rowset_Abstract</classname> 型のオブジェクトとなります。
16             行セットには、<classname>Zend_Db_Table_Row_Abstract</classname> を継承したオブジェクトが含まれます。
17             行セットを使用して各行オブジェクトに対して順にアクセスし、
18             行のデータを読み込んだり変更したりできます。
19         </para>
21     </sect2>
23     <sect2 id="zend.db.table.rowset.fetch">
25         <title>行セットの取得</title>
27         <para>
28             <classname>Zend_Db_Table_Abstract</classname> には <methodname>find()</methodname> と
29             <methodname>fetchAll()</methodname> というメソッドがあります。
30             これらはどちらも <classname>Zend_Db_Table_Rowset_Abstract</classname> 型のオブジェクトを返します。
31         </para>
33         <example id="zend.db.table.rowset.fetch.example">
35             <title>行セットの取得の例</title>
37             <programlisting language="php"><![CDATA[
38 $bugs   = new Bugs();
39 $rowset = $bugs->fetchAll("bug_status = 'NEW'");
40 ]]></programlisting>
42         </example>
44     </sect2>
46     <sect2 id="zend.db.table.rowset.rows">
48         <title>行セットからの行の取得</title>
50         <para>
51             通常は、行セットそのものよりもその中に含まれる行のほうが重要になります。
52             この節では、行セットを構成する行の情報を取得する方法について説明します。
53         </para>
55         <para>
56             正しい形式のクエリであっても、結果がゼロ行となることがありえます。
57             たとえば、抽出条件に一致する行がデータベース内に存在しない場合などです。
58             したがって、行セットオブジェクトの中身の行オブジェクトの個数がゼロになることもあります。
59             <classname>Zend_Db_Table_Rowset_Abstract</classname> は
60             <classname>Countable</classname> インターフェイスを実装しているので、
61             <methodname>count()</methodname> を使用すると行セット内の行の数を調べられます。
62         </para>
64         <example id="zend.db.table.rowset.rows.counting.example">
66             <title>行セット内の行の数を数える</title>
68             <programlisting language="php"><![CDATA[
69 $rowset   = $bugs->fetchAll("bug_status = 'FIXED'");
71 $rowCount = count($rowset);
73 if ($rowCount > 0) {
74     echo "見つかった行数は $rowCount です";
75 } else {
76     echo 'クエリにマッチする行がありません';
78 ]]></programlisting>
80         </example>
82         <example id="zend.db.table.rowset.rows.current.example">
84             <title>行セットからの単一の行の読み込み</title>
86             <para>
87                 行セットから行にアクセスするための一番簡単な方法は
88                 <methodname>current()</methodname> メソッドを使用することです。
89                 これは、行セットに含まれる行数がひとつである場合に最適です。
90             </para>
92             <programlisting language="php"><![CDATA[
93 $bugs   = new Bugs();
94 $rowset = $bugs->fetchAll("bug_id = 1");
95 $row    = $rowset->current();
96 ]]></programlisting>
98         </example>
100         <para>
101             行セットに含まれる行数がゼロの場合、<methodname>current()</methodname>
102             が返す値は <acronym>PHP</acronym> の <constant>NULL</constant> 値となります。
103         </para>
105         <example id="zend.db.table.rowset.rows.iterate.example">
107             <title>行セットの順次処理</title>
109             <para>
110                 <classname>Zend_Db_Table_Rowset_Abstract</classname> を継承したオブジェクトは
111                 <classname>SeekableIterator</classname> インターフェイスを実装しています。つまり、
112                 <methodname>foreach()</methodname> ループを使用できるということです。
113                 これを使用して取得した個々の値は <classname>Zend_Db_Table_Row_Abstract</classname>
114                 オブジェクトとなり、これがテーブルの各行に対応します。
115             </para>
117             <programlisting language="php"><![CDATA[
118 $bugs = new Bugs();
120 // テーブルのすべてのレコードを取得します
121 $rowset = $bugs->fetchAll();
123 foreach ($rowset as $row) {
125     // 出力は 'Zend_Db_Table_Row' あるいはそれに似たものとなります
126     echo get_class($row) . "\n";
128     // 行のカラムを読み込みます
129     $status = $row->bug_status;
131     // 現在の行のカラムの値を変更します
132     $row->assigned_to = 'mmouse';
134     // 変更をデータベースに書き出します
135     $row->save();
137 ]]></programlisting>
139         </example>
141          <example id="zend.db.table.rowset.rows.seek.example">
143             <title>行セット内の既知の位置への移動</title>
145             <para>
146                 <classname>SeekableIterator</classname> は、
147                 イテレータ内の特定の位置に移動できます。
148                 そのために使用するのが <methodname>seek()</methodname> メソッドです。
149                 行番号を渡すと、行セット内のその次の位置に移動できます。
150                 行番号は 0 から始まることに注意しましょう。
151                 インデックスが間違っている場合、あるいは存在しない場合は例外がスローされます。
152                 <methodname>count()</methodname> を使って結果の行数を確認してから移動するようにしましょう。
153             </para>
155             <programlisting language="php"><![CDATA[
156 $bugs = new Bugs();
158 // テーブルのすべてのレコードを取得します
159 $rowset = $bugs->fetchAll();
161 // イテレータを 9 番目の要素に移動します (最初の要素がゼロです)
162 $rowset->seek(8);
164 // それを取得します
165 $row9 = $rowset->current();
167 // そして使用します
168 $row9->assigned_to = 'mmouse';
169 $row9->save();
170 ]]></programlisting>
172         </example>
174             <para>
175                 <methodname>getRow()</methodname> は、位置がわかっている場合に
176                 行セット内の特定の行を取得するためのメソッドです。
177                 しかし、この位置はゼロから数え始めることを忘れないようにしましょう。
178                 <methodname>getRow()</methodname> の最初のパラメータは、位置を表す整数値です。
179                 2 番目のパラメータはオプションで、boolean 値を指定します。
180                 これは、Rowset イテレータも同時にその場所に移動させるのかどうかを表します
181                 (デフォルトは <constant>FALSE</constant> です)。このメソッドはデフォルトでは
182                 <classname>Zend_Db_Table_Row</classname> オブジェクトを返します。
183                 指定した位置が存在しない場合は例外をスローします。
184                 例を示します。
185             </para>
187             <programlisting language="php"><![CDATA[
188 $bugs = new Bugs();
190 // テーブルのすべてのレコードを取得します
191 $rowset = $bugs->fetchAll();
193 // 9 番目の要素を取得します
194 $row9->getRow(8);
196 // そして使用します
197 $row9->assigned_to = 'mmouse';
198 $row9->save();
199 ]]></programlisting>
201         <para>
202             個々の行オブジェクトにアクセスすると、後は
203             <link linkend="zend.db.table.row">Zend_Db_Table_Row</link>
204             で説明しているメソッド群を用いて行を操作できます。
205         </para>
207     </sect2>
209     <sect2 id="zend.db.table.rowset.to-array">
211         <title>行セットの配列としての取得</title>
213         <para>
214             行セット内のすべてのデータに対して配列としてアクセスするには、
215             行セットオブジェクトの <methodname>toArray()</methodname> メソッドを使用します。
216             これは、各行単位でひとつの要素となる配列を返します。
217             各エントリは連想配列となり、カラム名とその値が関連付けられています。
218         </para>
220         <example id="zend.db.table.rowset.to-array.example">
222             <title>toArray() の使用法</title>
224             <programlisting language="php"><![CDATA[
225 $bugs   = new Bugs();
226 $rowset = $bugs->fetchAll();
228 $rowsetArray = $rowset->toArray();
230 $rowCount = 1;
231 foreach ($rowsetArray as $rowArray) {
232     echo "row #$rowCount:\n";
233     foreach ($rowArray as $column => $value) {
234         echo "\t$column => $value\n";
235     }
236     ++$rowCount;
237     echo "\n";
239 ]]></programlisting>
240         </example>
242         <para>
243             <methodname>toArray()</methodname> が返す配列は、更新できません。
244             つまり、配列内の値を変更することは可能ですが、
245             それをデータベースに反映させることはできません。
246         </para>
248     </sect2>
250     <sect2 id="zend.db.table.rowset.serialize">
252         <title>行セットのシリアライズと復元</title>
254         <para>
255             <classname>Zend_Db_Table_Rowset_Abstract</classname> 型のオブジェクトはシリアライズ可能です。
256             個別の行オブジェクトをシリアライズするのと同じような方式で、
257             行セットをシリアライズして後ほどそれを復元できます。
258         </para>
260         <example id="zend.db.table.rowset.serialize.example.serialize">
262             <title>行セットのシリアライズ</title>
264             <para>
265                 <acronym>PHP</acronym> の <methodname>serialize()</methodname> 関数を使用して、
266                 行セットオブジェクトのバイトストリームを含む文字列を作成します。
267             </para>
269             <programlisting language="php"><![CDATA[
270 $bugs   = new Bugs();
271 $rowset = $bugs->fetchAll();
273 // オブジェクトをシリアライズします
274 $serializedRowset = serialize($rowset);
276 // これで、$serializedRowset をファイルなどに書き出すことができます
277 ]]></programlisting>
279         </example>
281         <example id="zend.db.table.rowset.serialize.example.unserialize">
283             <title>シリアライズした行セットの復元</title>
285             <para>
286                 <acronym>PHP</acronym> の <methodname>unserialize()</methodname> 関数を使用して、
287                 オブジェクトのバイトストリームを含む文字列を復元します。
288                 この関数は、もとのオブジェクトを返します。
289             </para>
291             <para>
292                 返された行セットオブジェクトは、
293                 <emphasis>接続が切断された</emphasis> 状態であることに注意しましょう。
294                 行セットオブジェクトやその内部の行オブジェクト、そしてそのプロパティを読み込むことはできますが、
295                 その値を変更することはできません。また、データベース接続を必要とするようなメソッド
296                 (たとえば従属テーブルに対するクエリなど) も実行できません。
297             </para>
299             <programlisting language="php"><![CDATA[
300 $rowsetDisconnected = unserialize($serializedRowset);
302 // これでオブジェクトのプロパティを使用できますが、読み込み専用です
303 $row = $rowsetDisconnected->current();
304 echo $row->bug_description;
305 ]]></programlisting>
307         </example>
309         <note>
310             <title>復元した行セットは、なぜ切断された状態なのですか?</title>
311             <para>
312                 シリアライズしたオブジェクトは、可読形式の文字列となります。
313                 データベースのアカウントやパスワードといった情報を
314                 暗号化せずにプレーンテキストにシリアライズして保存すると、
315                 セキュリティ上問題となります。
316                 そのようなデータを無防備な状態でテキストファイルに保存したりしたくはないでしょう。
317                 またメールなどで攻撃者に覗き見られることも好まないはずです。
318                 シリアライズされたオブジェクトは、
319                 正しい認証情報を知らない限りデータベースにアクセスすることはできません。
320             </para>
321         </note>
323         <para>
324             切断された行セットの接続を復活させるには、
325             <methodname>setTable()</methodname> メソッドを使用します。このメソッドへの引数としては、
326             <classname>Zend_Db_Table_Abstract</classname> 型のオブジェクトを作成して渡します。
327             テーブルオブジェクトを作成するには、データベースとの接続が必要です。
328             そのテーブルと行セットを関連付けることで、行セットがデータベースにアクセスできるようになります。
329             それ以降は、行オブジェクトの値を変更してデータベースに保存できるようになります。
330         </para>
332         <example id="zend.db.table.rowset.serialize.example.set-table">
334             <title>生きたデータとしての行セットの復活</title>
336             <programlisting language="php"><![CDATA[
337 $rowset = unserialize($serializedRowset);
339 $bugs = new Bugs();
341 // この行セットをテーブルに再接続し、
342 // データベースとの接続を復活させます
343 $rowset->setTable($bugs);
345 $row = $rowset->current();
347 // これで、行の内容を変更して保存できます
348 $row->bug_status = 'FIXED';
349 $row->save();
350 ]]></programlisting>
352         </example>
354         <para>
355             行セットを <methodname>setTable()</methodname> で復活させると、
356             その中に含まれる行オブジェクトもすべて復活した状態になります。
357         </para>
359     </sect2>
361     <sect2 id="zend.db.table.rowset.extending">
363         <title>行セットクラスの拡張</title>
365         <para>
366             <classname>Zend_Db_Table_Rowset_Abstract</classname> を継承した新たな具象クラスを作成し、
367             それを用いて行セットのインスタンスを作成できます。
368             独自の行クラスを指定するには、テーブルクラスの protected
369             メンバである <varname>$_rowsetClass</varname> を使用するか、
370             テーブルオブジェクトのコンストラクタの引数の配列で指定します。
371         </para>
373         <example id="zend.db.table.rowset.extending.example">
374             <title>独自の行セットクラスの指定</title>
375             <programlisting language="php"><![CDATA[
376 class MyRowset extends Zend_Db_Table_Rowset_Abstract
378     // ...独自の処理
381 // 独自の行セットを、テーブルクラスの全インスタンスで
382 // デフォルトとして使用するように設定します
383 class Products extends Zend_Db_Table_Abstract
385     protected $_name = 'products';
386     protected $_rowsetClass = 'MyRowset';
389 // あるいは、テーブルクラスの特定のインスタンスでのみ
390 // 独自の行セットクラスを使用するように設定します
391 $bugs = new Bugs(array('rowsetClass' => 'MyRowset'));
392 ]]></programlisting>
393         </example>
395         <para>
396             一般的には、標準の具象クラス <classname>Zend_Db_Rowset</classname>
397             でたいていの場合は十分でしょう。しかし、
398             特定のテーブルに固有の処理を行セットに追加したくなることもあります。
399             たとえば、行セット内のすべての行の内容の集計用のメソッドなどです。
400         </para>
402         <example id="zend.db.table.rowset.extending.example-aggregate">
403             <title>行セットクラスに新しいメソッドを追加する例</title>
404             <programlisting language="php"><![CDATA[
405 class MyBugsRowset extends Zend_Db_Table_Rowset_Abstract
407     /**
408      * 現在の行セットのなかで、'updated_at' カラムの値が
409      * 最大である行を見つけます
410      */
411     public function getLatestUpdatedRow()
412     {
413         $max_updated_at = 0;
414         $latestRow = null;
415         foreach ($this as $row) {
416             if ($row->updated_at > $max_updated_at) {
417                 $latestRow = $row;
418             }
419         }
420         return $latestRow;
421     }
424 class Bugs extends Zend_Db_Table_Abstract
426     protected $_name = 'bugs';
427     protected $_rowsetClass = 'MyBugsRowset';
429 ]]></programlisting>
430         </example>
432     </sect2>
434 </sect1>
435 <!--
436 vim:se ts=4 sw=4 et: