メールメッセージの読み込みZend_Mail を使用すると、 ローカルあるいはリモートに保存されたメールを読み込むことができます。 すべての保存形式に共通の基本 API では、メッセージ数を数えたり メッセージを読み込んだりできます。また、 いくつかの保存形式では、特殊な追加機能も実装されています。 各保存形式で実装されている機能の概要については以下の表を参照ください。
Pop3 によるシンプルな読み込み例
ローカルに保存されたメールのオープンローカルのメール保存形式としては、Mbox および Maildir をサポートしています。これらはともに、もっともシンプルな形式です。 Mbox ファイルからメールを読み込むには、そのファイル名を Zend_Mail_Storage_Mbox のコンストラクタに渡すだけです。
Maildir もほぼ同様ですが、こちらはディレクトリ名を指定します。
どちらのコンストラクタも、もし読み込めなかった場合は Zend_Mail_Exception をスローします。 リモートに保存されたメールのオープンリモートの保存形式としては、もっとも有名なふたつである Pop3 と Imap をサポートしています。それぞれ、 ホスト名とユーザ名を指定して接続、ログインします。 デフォルトのパスワードは空の文字列で、デフォルトのポート番号は そのプロトコルの RFC で指定されているものです。
どちらの保存形式についても、SSL や TLS をサポートしています。 SSL を使用する場合、デフォルトのポートは RFC にあるとおりに変更されます。
どちらのコンストラクタも、エラーの形式によって Zend_Mail_Exception あるいは Zend_Mail_Protocol_Exception (Zend_Mail_Exception を継承したもの) をスローします。 メッセージの取得およびシンプルなメソッドストレージをオープンしたら、メッセージを取得できます。 メッセージを取得するには、メッセージ番号が必要です。 これは、最初のメッセージを 1 番とする連番となります。 メッセージを取得する際に使用するメソッドは getMessage() です。 配列形式のアクセスもサポートしていますが、 getMessage() に追加のパラメータを渡すことはサポートしていません。 なにも気にせずデフォルトでいいなら、このように使用します。 全メッセージについて順に処理するために、Iterator インターフェイスも実装されています。
保存されているメッセージ数を数えるには、 countMessages() メソッドあるいは配列形式のアクセスを使用します。
メールを削除するには、 removeMessage() メソッドあるいは配列形式のアクセスを使用します。
メッセージの操作getMessage() でメッセージを取得したら、 次にしたくなることは、ヘッダの取得やマルチパートメッセージの各パートの取得などでしょう。 すべてのヘッダには、プロパティあるいはメソッド getHeader() (一般的でないヘッダの場合) でアクセスできます。 ヘッダ名は、内部では小文字で表されます。 したがって、メールメッセージ内のでのヘッダ名は関係ありません。 また、ヘッダ名にダッシュが入っている場合は、 camel-case で保持されます。どちらの記法でもヘッダが見つからなかった場合は、例外がスローされます。 そんな場合は、 headerExists() メソッドを使用すれば ヘッダが存在するかどうかを調べることができます。
同名のヘッダが複数ある場合 (たとえば Received ヘッダなど)、 それを文字列ではなく配列として扱うこともできます。これは getHeader() メソッドを使用して行います。
getHeaders() メソッドは、すべてのヘッダを配列で返します。 キーはヘッダ名を小文字にしたもので、値は文字列 (そのヘッダがひとつの場合) あるいは文字列の配列 (そのヘッダが複数の場合) となります。
マルチパートメッセージがないのなら、その内容は getContent() で簡単に取得できます。ヘッダの場合とは異なり、 内容は必要になった時点で初めて取得します (いわゆる遅延取得っていうやつです)。
マルチパートメッセージであるかどうかを調べるには isMultipart() メソッドを使用します。マルチパートメッセージがある場合は、 getPart() メソッドで Zend_Mail_Part のインスタンスを取得します。 Zend_Mail_Part は Zend_Mail_Message の基底クラスなので、 getHeader() や getHeaders()、 getContent()、 getPart()、 isMultipart() といったメソッドを同様に使えます。 また、ヘッダもプロパティとして使用できます。
Zend_Mail_Part は RecursiveIterator も実装しています。 つまり、すべてのパートを順にスキャンすることも簡単にできます。また、 結果を簡単に出力できるよう、マジックメソッド __toString() を実装しています。このメソッドは、パートの中身を返します。
フラグのチェックMaildir および IMAP はフラグの保存をサポートしています。 Zend_Mail_Storage クラスには、maildir や IMAP で使用するすべてのフラグに対応する定数が定義されています。これは Zend_Mail_Storage::FLAG_<flagname> という名前です。 フラグをチェックするには、Zend_Mail_Message の hasFlag() メソッドを使用します。 getFlags() で、設定されているすべてのフラグを取得できます。
IMAP ではユーザやクライアントが独自にフラグを設定できます。 Zend_Mail_Storage で定数が定義されていない、 このようなフラグを取得することも可能です。これらは文字列として返され、 hasFlag() で同じようにチェックできます。
フォルダの使用法Pop3 以外のすべての保存形式は、フォルダをサポートしています。 これはメールボックスとも言います。各保存形式で、 フォルダをサポートするために実装しているインターフェイスが Zend_Mail_Storage_Folder_Interface です。 これらすべてのクラスでは、コンストラクタで追加のオプションパラメータ folder を指定できます。これは、ログイン後に使用するフォルダを指定するものです。 ローカルの保存形式では、Zend_Mail_Storage_Folder_Mbox あるいは Zend_Mail_Storage_Folder_Maildir のいずれかのクラスを使用します。どちらもパラメータ dirname が必須で、これは基底ディレクトリの名前となります。 maildir のフォーマットは maildir++ で定義されているもの (デフォルトの区切り文字はドットです)、一方 Mbox は Mbox ファイルのディレクトリ階層を使用します。Mbox の基底ディレクトリに INBOX という名前の Mbox ファイルがない場合は、 コンストラクタで別のフォルダを設定する必要があります。 Zend_Mail_Storage_Imap は、デフォルトでフォルダをサポートしています。 これらの保存形式をオープンする例を以下に示します。
getFolders($root = null) メソッドを使用すると、 ルートフォルダあるいは指定したフォルダから始まるフォルダ階層を取得できます。 返り値は Zend_Mail_Storage_Folder のインスタンスとなります。これは RecursiveIterator を実装しており、子要素もすべて Zend_Mail_Storage_Folder のインスタンスとなります。 これらの各インスタンスはローカル名およびグローバル名を持っており、 それぞれ getLocalName() メソッドおよび getGlobalName() メソッドで取得できます。 グローバル名とはルートフォルダからの絶対名称 (区切り文字を含む) で、 ローカル名とは親フォルダから見た名前のことです。
イテレータを使用する際は、要素のキーはローカル名となります。 グローバル名を取得するには、マジックメソッド __toString() を使用します。 フォルダによっては、選択できないものもあるかもしれません。 これは、そのフォルダにメッセージを保存できず、 メッセージを選ぼうとしてエラーになっていることを意味します。 これを確認するためのメソッドが isSelectable() です。 ツリー全体をビューに出力するのは、このように非常に簡単です。
現在選択されているフォルダを返すメソッドは getCurrentFolder() です。フォルダを変更するには selectFolder() メソッドを使用します。 このメソッドのパラメータには、グローバル名を指定しなければなりません。 区切り文字を書き込んでしまうことを防ぎたければ、 Zend_Mail_Storage_Folder インスタンスのプロパティを使用します。
高度な使用法NOOP の使用リモートの保存形式を使用しており、何らかの事情で接続をずっと保持し続けたい場合は noop を使用します。
インスタンスのキャッシュZend_Mail_Storage_Mbox、Zend_Mail_Storage_Folder_Mbox、Zend_Mail_Storage_Maildir および Zend_Mail_Storage_Folder_Maildir は、マジックメソッド __sleep() と __wakeup() を実装しています。 つまり、シリアライズが可能であるということです。 これで、ファイルやディレクトリツリーを何度もパースする必要がなくなります。 難点があるとすれば、Mbox や Maildir を変更することができなくなるということです。 簡単な解決策としては、最終更新時刻が変更されたときに Mbox ファイルをパースしなおしたり、 フォルダがなくなった場合にフォルダ構造を再パースしたり (これはエラーとなりますが、その後別のフォルダを検索できます) といったことが考えられます。よりよい方法は、シグナルファイル的なものを用意して 変更情報をそこに記録し、まずそれをチェックしてからキャッシュを利用するようにすることです。
プロトコルクラスの拡張リモートの保存形式では、ふたつのクラス Zend_Mail_Storage_<Name> および Zend_Mail_Protocol_<Name> を使用しています。 プロトコルクラスは、プロトコルのコマンドを処理して、レスポンスを PHP に受け渡しします。コマンドに対応したメソッド、 さまざまなデータ構造に対応した変数を保持します。 もう一方のメインクラスでは、共通インターフェイスを実装します。 プロトコルを追加したい場合は、プロトコルクラスを継承したものを作成し、 それをメインクラスのコンストラクタで使用します。 例として、PHP3 接続の前に別のポートをノックしなければならないという場面を考えてみましょう。
ご覧の通り、メインクラスのコンストラクタでは 接続、ログイン、(サポートされるなら) フォルダの選択 までを済ませているものと期待しています。 したがって、独自のプロトコルクラスを使用する場合は、 これらを確実に処理しておく必要があります。そうしないと、 その後のメソッドが失敗してしまいます。 容量制限の使用 (1.5 以降)Zend_Mail_Storage_Writable_Maildir は Maildir++ の容量制限をサポートしています。デフォルトではこの機能は無効になっていますが、 手動で使用することもできます。これは、自動チェックをしたくないとき (つまり appendMessage()、 removeMessage() および copyMessage() でチェックを行わず maildirsize ファイルにもエントリを追加しないとき) に使えます。 この機能を有効にすると、容量制限に達した maildir に書き込もうとしたときに例外がスローされます。 容量制限関連のメソッドは getQuota()、 setQuota() および checkQuota() の 3 つです。
checkQuota() は、より詳細な情報も返します。
maildirsize ファイルで指定したものではなく独自の容量制限を使用したい場合は、 setQuota() を使用します。
独自の容量チェックを追加するには、単一の文字をキーとして使用します。 キーが保存されます (が、チェックはされません)。 Zend_Mail_Storage_Writable_Maildir を継承して独自の容量制限 を定義することもできます。 maildirsize ファイルが存在しないときにのみ使用します (Maildir++ ではこれが起こりえます)。
|