Gmailの受信ボックスを表示する

Gmailの受信ボックスをPHPで表示する方法のメモ。
受信ボックスを表示する方法としては

・imap
・pop

の2通りがあるが、簡単に違いを説明すると
imapはメールをサーバに残したまま閲覧することに対して
popはメールをサーバからダウンロードしてくる。というものです。
なので今回は、閲覧するだけのimap関数を使用しました。

メールを閲覧して表示するだけでも
タイトルの有無
文字コードによって対処が変わってくるので
かなりの長いプログラムになりました。

その後、メールを変数に格納し
最後にHTMLのテーブルで表示しています。

ただし、すべてのメールを参照しに行っているので
メール件数が多いと処理がとても重くなってしまいます。

新着メールだけ表示したい場合は
別記事で別にまとめています。
http://qiita.com/ming/items/76fef528e5c60308a47d


メールは、古い順になっているので
新しいものから表示したい場合は
TABLEのfor文の条件を変更してください。

```php:MailBox.php

<?php

header('Content-Type: text/html; charset=UTF-8');

// 言語
mb_language('Japanese');
// 文字コード
mb_internal_encoding('utf-8');

// 必要な定数を設定
define('GMAIL_HOST','imap.googlemail.com');
define('GMAIL_PORT',993);
define('GMAIL_ACCOUNT','hogehoge@gmail.com');
define('GMAIL_PASSWORD','hogehoge');
define('SERVER','{'.GMAIL_HOST.':'.GMAIL_PORT.'/novalidate-cert/imap/ssl}');

// メールボックスへの IMAP ストリームをオープン
if (($mbox = @imap_open(SERVER."INBOX", GMAIL_ACCOUNT, GMAIL_PASSWORD)) == false) {
	// 失敗処理を記述...
}
// メールボックスの情報を取得
$mboxes=imap_mailboxmsginfo($mbox);

// メッセージ数の有無
if( $mboxes->Nmsgs != 0 ) {
	// 情報を格納する変数を初期化
	$mail=null;
	for( $mailno=1; $mailno<=$mboxes->Nmsgs; $mailno++ ) {
		// ヘッダー情報の取得
		$head=imap_header($mbox, $mailno);

		// アドレスの取得
		$mail[$mailno]['差出人']=$head->from[0]->mailbox.'@'.$head->from[0]->host;
		// タイトルの有無
		if( !empty($head->subject) ) {
			// タイトルをデコード
			$mhead=imap_mime_header_decode($head->subject);
			foreach( $mhead as $key=>$value) {
				if( $value->charset != 'default' ) {
					$mail[$mailno]['件名']=mb_convert_encoding($value->text,'UTF-8',$value->charset);
				}else{
					$mail[$mailno]['件名']=$value->text;
				}
			}
		}else{
			// タイトルがない場合の処理を記述...
			echo "no title";
		}
		// 格納用変数の初期化
		$charset=null;
		$encoding=null;
		$attached_data=null;
		$parameters=null;
		// メール構造を取得
		$info=imap_fetchstructure($mbox, $mailno);
		if( !empty($info->parts) ) {
			//
			$parts_cnt=count($info->parts);
			for( $p=0; $p<$parts_cnt; $p++ ) {
				// タイプにより処理を分ける
				// [参考] http://www.php.net/manual/ja/function.imap-fetchstructure.php
				if( $info->parts[$p]->type == 0 ) {
					if( empty( $charset ) ) {
						$charset=$info->parts[$p]->parameters[0]->value;
					}
					if( empty( $encoding ) ) {
						$encoding=$info->parts[$p]->encoding;
					}
				}elseif(!empty($info->parts[$p]->parts) && $info->parts[$p]->parts[$p]->type == 0){
					$parameters=$info->parts[$p]->parameters[0]->value;
					if( empty( $charset ) ) {
						$charset=$info->parts[$p]->parts[$p]->parameters[0]->value;
					}
					if( empty( $encoding ) ) {
						$encoding=$info->parts[$p]->parts[$p]->encoding;
					}
				}elseif($info->parts[$p]->type == 5){
					$files=imap_mime_header_decode($info->parts[$p]->dparameters[0]->value);
					if(!empty($files) && is_array($files) ) {
						$attached_data[$p]['file_name']=null;
						foreach($files as $key => $file) {
							if( $file->charset != 'default') {
								$attached_data[$p]['file_name'].=mb_convert_encoding($file->text, 'UTF-8', $file->charset);
							}else{
								$attached_data[$p]['file_name'].=$file->text;
							}
						}
					}
					$attached_data[$p]['content_type'] = $info->parts[$p]->subtype;
				}
			}
		}else{
			$charset=$info->parameters[0]->value;
			$encoding=$info->encoding;
		}
		if( empty($charset) ) {
			// エラー処理を記述...
		}
		// 本文を取得
		$body=imap_fetchbody($mbox, $mailno, 1, FT_INTERNAL);
		$body=trim($body);
		if( !empty($body) ) {
			// タイプによってエンコード変更
			switch( $encoding ) {
				case 0 :
					$mail[$mailno]['本文']=mb_convert_encoding($body, "UTF-8", $charset);
					break;
				case 1 :
					$encode_body=imap_8bit($body);
					$encode_body=imap_qprint($encode_body);
					$mail[$mailno]['本文']=mb_convert_encoding($encode_body, "UTF-8", $charset);
					break;
				case 3 :
					$encode_body=imap_base64($body);
					$mail[$mailno]['本文']=mb_convert_encoding($encode_body, "UTF-8", $charset);
					break;
				case 4 :
					$encode_body=imap_qprint($body);
					$mail[$mailno]['本文']=mb_convert_encoding($encode_body, 'UTF-8', $charset);
					break;
				case 2 :
				case 5 :
				default:
					// エラー処理を記述...
					break;
			}
		}else{
			// エラー処理を記述...
		}

	}

	echo "<table border=1>";
	echo"<tr> <th>MailNo.</th><th>差出人</th><th>件名</th><th>本文</th> </tr>";

	for($n=1; $n<$mailno; $n++){
		echo"<tr> <td>".$n."</td><td>".$mail[$n]['差出人']."</td><td>".$mail[$n]['件名']."</td><td>".$mail[$n]['本文']."</td> </tr>";
	}

	echo "</table><br><br>";
}

?>

```