プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
PHP、WEBメールを作ってみる(3)受信メールの未読・既読を表示する
PHP、WEBメールを作ってみる(1)受信メールの一覧を取得して画面に表示する
PHP、WEBメールを作ってみる(2)受信メールの詳細を取得して画面に表示する」で
PHPによるお手軽Webメールもどきを作ってみました。

今回はそれをちょっと改良してメールの未読・既読を管理するようにしてみます。

理屈は恐らく単純だと思うのですよね。
メールの未読・既読ってのはメールサーバ側ではなくメールクライアント側の領域です。

1.既読メールのリストをどこかに保持
2.メール本文を開いたときに「1.」のリストを更新
3.メールの一覧を表示するときに「1.」のリストと突き合わせチェックして未読・既読を判定

でいけるんじゃないかな~と予想してみました。

いや、実際のWebメールがどんな仕組みになっているのかは分かりませんけどね。
多分、似たようなことをやってるんじゃなかんべか(--?

今回はお試しということで、既読メールのリスト(既読リスト)は連想配列のキーで管理することにして、
それをserialize/unserializeを使ってファイルに保持することにしてみました。

ちなみにメールの特定はMessage-Idを使います。

ほんで、あれやこれやとアレして、前回のコードに手を加えて出来上がったのがこんな感じφ(--)

■mail_list.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
    <title>webmail</title>
</head>
<body>

<?php
    require_once dirname(__FILE__) . '/inc.php';

    //-------------------------------
    //既読リスト取得
    //-------------------------------
    if(file_exists($arl_file)){
        $alreadyReadList = unserialize(file_get_contents($arl_file));
    }else{
        $alreadyReadList = array();
    }


    //-------------------------------
    //接続&ログイン
    //-------------------------------
    require_once dirname(__FILE__) . '/mail_connect.php';

    //-------------------------------
    //受信メール件数取得
    //-------------------------------
    fputs($fp, "STAT\r\n");
    $line = fgets($fp, 512);
    print $line . "<br>";    //STAT結果表示

    //STAT結果を変数に展開
    list($status, $cnt, $size) = explode(' ', $line);

    //受信メール件数チェック
    if(intVal($cnt) == 0){
        print "受信メール無し<br><br>";
    }else{
        print "受信メールあり<br><br>";
    }

    //テスト用に件数制限入れておきます(100件を超える場合は100件まで)
    $cnt = ($cnt > 100 ? 100 : $cnt);

    //-------------------------------
    //受信メール一覧表示
    //-------------------------------
    for($i = 1; $i <= $cnt; $i++){
        //メッセージヘッダ取得
        //「TOP」が使えない環境の人は「RETR」で代用してください
        //fputs($fp, "RETR $i\r\n");
        fputs($fp, "TOP $i 0\r\n");

        do{
            $line = fgets($fp, 512);

            //件名を表示する
            if(preg_match("/^Subject/", $line)){
                $subject = mb_decode_mimeheader($line);
                $subject = preg_replace("/^Subject:/", "", $subject);
                print '<a href="mail_detail.php?no=' . $i . '" target="blank">';
//                print $i . ":" . mb_convert_encoding($subject, $enc, "auto") . "<br>";
                print $i . ":" . mb_convert_encoding($subject, $enc, "auto");

                print '</a>';
            }

            //既読・未読を表示する
            if(preg_match("/^Message-Id/", $line)){
                //Message-Idを取得する
                preg_match('/<(.*)>/', $line, $msgIdAry);
                $messageId = $msgIdAry[1];

                //既読リストと比較
                if(!array_key_exists($messageId, $alreadyReadList)){
                    print " 未読";
                }
            }
        }while (!preg_match("/^\.\r\n/", $line));

        print "<br>";
    }

    //切断
    require_once dirname(__FILE__) . '/mail_disconnect.php';
?>

</body>
</html>

■inc.php
<?php
    //-------------------------------
    //パラメータ定義
    //-------------------------------
    //文字エンコード
    $enc = "UTF-8";
    //POPサーバ
    $mail_host = "mail.example.com";
    //ポート
    $mail_port = 110;
    //ユーザ
    $mail_user = "mailuser";
    //パスワード
    $mail_pwd = "mailpwd";

    //already read list既読メール情報
    $arl_file = dirname(__FILE__) . '/ar_list.dat';

■mail_connect.php
<?php
    require_once dirname(__FILE__) . '/inc.php';

    //-------------------------------
    //接続&ログイン
    //-------------------------------
    //接続
    $fp = fsockopen($mail_host, $mail_port);

    //ログイン
    $line = fgets($fp, 512);
    fputs($fp, "USER $mail_user\r\n");    // USER名
    $line = fgets($fp, 512);        
    fputs($fp, "PASS $mail_pwd\r\n");    // パスワード
    $line = fgets($fp, 512);
    if(!preg_match("(OK)", $line)){    // ログイン失敗?
        fclose($fp);
        die("ログイン失敗");
    }

■mail_disconnect.php
<?php
    require_once dirname(__FILE__) . '/inc.php';

    //切断する
    fputs($fp, "QUIT\r\n");
    fclose($fp);

■mail_detail.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
    <title>webmail</title>
</head>
<body>

<?php
    require_once dirname(__FILE__) . '/inc.php';

    //-------------------------------
    //パラメータ取得
    //-------------------------------
    $no = $_GET['no'];
    if(empty($no) || !is_numeric($no)){
        die("なんかおかしいよ");
    }

    //-------------------------------
    //接続&ログイン
    //-------------------------------
    require_once dirname(__FILE__) . '/mail_connect.php';

    //-------------------------------
    //メール詳細を表示
    //-------------------------------
    fputs($fp, "RETR $no\r\n");
    do{
        $line = fgets($fp, 512);

        //件名を表示する
        if(preg_match("/^Subject/", $line)){
            $subject = mb_decode_mimeheader($line);
            print mb_convert_encoding($subject, $enc, "auto") . "<br>";
        }else{
            print mb_convert_encoding($line, $enc, "auto") . "<br>";

            //Message-Idを取得する&保存
            if(preg_match("/^Message-Id/", $line)){
                //Message-Id抽出
                preg_match('/<(.*)>/', $line, $msgIdAry);
                $messageId = $msgIdAry[1];

                //既読リスト取得
                if(file_exists($arl_file)){
                    $alreadyReadList = unserialize(file_get_contents($arl_file));
                }else{
                    $alreadyReadList = array();
                }

                //既読リストに追加
                $alreadyReadList[$messageId] = "既読";

                //既読リスト保存
                file_put_contents($arl_file, serialize($alreadyReadList));
            }

        }

    }while (!preg_match("/^\.\r\n/", $line));


    //切断
    require_once dirname(__FILE__) . '/mail_disconnect.php';
?>

</body>
</html>

前回からの変更点は大きく分けて3つです。

1.「inc.php」に既読リストのファイル名を定義
2.「mail_list.php」で既読リストとメール一覧のMessage-Idを比較して未読だったらマークをつける
3.「mail_detail.php」で表示メールのMessage-Idを既読リストに保存する

ってなところですね。

エラー処理は入れてないし、件数が増えればいろいろ問題が出てくると思いますが、
理屈としてはこんな感じじゃないでしょーか。

と言うわけで、PHPで作ったWebメールもどきへの未読・既読の表示、これにて完了\(--)/
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:● PHP  thema:システム開発 - genre:コンピュータ  Posted by ササキマコト 

  関連記事