7085


cPanelのフォワーダーで.phpへメールをパイプし、その本文内の日本語の文字列を検索しようとしていますが、どうしても見つけてくれません。

具体的には、Yahoo!JAPANの路線情報メールを受け取り、その内容の一部を切り取ってデータベースにINSERTする、ということをしようとしています。自分のPC(MAC)から同じメールアドレスにメールを送信した場合は、しっかり"路線名"という文字列を認識し処理をしてくれるのですが、Yahoo!から届くオリジナルメールはスルーされてしまいます。

恐らく、メールやサーバーの文字コードの違いによって認識できていないのだと思われますが、どのような設定、あるいはPHP内での文字コードの変換を行えば、認識できるようになるのでしょうか。

以下、PHPコードと、Yahoo!から届くメール(Header部分含め)を添付いたします。

よろしくお願いいたします。

[code]

    #!/usr/local/bin/php
    <?
    
    $stdin = fopen('php://stdin' , 'r');
    while (!feof($stdin))
    {
        $line = trim(fgets($stdin, 4096));
        $wmail .= "\n" . $line;
    }
    fclose ($stdin);
    
    // 解析
    $findme = "路線名";
    $start_position = strpos($wmail, $findme);
    if ($start_position === false) 
    {
        // "路線名"が見つからなかった場合の処理
        exit();
    }
    
    // 見つかった場合の処理
    
    ?>
    
[/code]

[code]

    From alerts-error@err.yahoo.co.jp Tue Feb 17 08:01:44 2015
    Received: from n30.bulk.ogk.yahoo.co.jp ([124.83.144.223]:46009)
    by vps6.globroad.com with smtp (Exim 4.84)
    (envelope-from <alerts-error@err.yahoo.co.jp>)
    id 1YNUfg-0008Ep-Fe
    for xxx@xxx.xxx; Tue, 17 Feb 2015 08:01:44 +0900
    Comments: DKIM? See http://antispam.yahoo.co.jp/efforts_dk.html
    DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mail.yahoo.co.jp; s=bulk201106; t=1424127704; bh=adAS1ct13jodmmWHHOrFRdKNPlPEkpjM09JThfYz3G8=; h=Received:Received:Date:Message-Id:Received:X-yahoo-newman-expires:X-yahoo-newman-id:X-yahoo-newman-property:From:To:Reply-To:Errors-To:Subject:MIME-Version:Content-Type:X-Yahoo-Bounces:X-Yahoo-AlertId:X-Yahoo-Alerts-DLV-Time:X-Yalerts-EncodeEmail; b=WtJA36tgZ3+PrlhrO6SeARq9fnD6IESPnwjrF9KHUf8AhUNhV3GBVwpay9GPko31qgIyKGVvqmrdj/D9XuIVKfDHCg95lmAuVYWLuD32EWY9GEDsgaGXlQFuUeI5Co83pI9UhUcyAZP/NICxnvmfftsxI6IFfL9hLZXO/Hhz898=
    DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=bulk201106; d=mail.yahoo.co.jp;
    b=GIOinzlt6c1liFJ2oBM81AZNg2soi8yFPCdQLALGIWR+QmU6n8zsugJprJVMylChX0ug1pxeXRjxJ3Wp/DVgcsoKrueJZTEDIglj9vJoixXhyp0q75hW3Soi5cj5m7hhmTsZweil3FEl2NWKdFC2le1ohnfmmXVr8XH09VVzekw=;
    Received: from [124.83.172.207] by n30.bulk.ogk.yahoo.co.jp with NNFMP; 16 Feb 2015 23:01:44 -0000
    Received: from [183.79.46.251] by m06.bulk.ogk.yahoo.co.jp with NNFMP; 16 Feb 2015 23:01:44 -0000
    Date: 17 Feb 2015 08:01:44 +0900
    Message-Id: <54e276d8-000067ff-2fdc29976311e6dd2eaed9de484e011c-7948@dlv136.alerts.kks.yahoo.co.jp>
    Received: from [127.0.0.1] by dlv136.alerts.kks.yahoo.co.jp with NNFMP; 16 Feb 2015 23:01:44 -0000
    X-yahoo-newman-expires: 1424134812
    X-yahoo-newman-id: dlv136.alerts.kks-27117-1424127704-transit-dinfo
    X-yahoo-newman-property: alerts
    From: "Yahoo! Alerts - Transit"<alerts-transit@mail.yahoo.co.jp>
    To: husky_train@location.serverrush.com
    Reply-To:"Yahoo! Alerts - Transit"<alerts-transit@mail.yahoo.co.jp>
    Errors-To: alerts-error@reply.yahoo.co.jp
    Subject: =?ISO-2022-JP?B?GyRCQW1JcEtcQH4bKEJbGyRCQGlNVSFBRDg7UhsoQl0gGyRCMT8bKEI=?=
    =?ISO-2022-JP?B?GyRCOVQ+cEpzGyhCIFlhaG9vIRskQk8pQH4+cEpzGyhC?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset="iso-2022-jp"
    X-Yahoo-Bounces: 1
    X-Yahoo-AlertId: 145639393
    X-Yahoo-Alerts-DLV-Time: Tuesday, February 17, 2015, 08:01 AM JST
    X-Yalerts-EncodeEmail: iso-2022-jp
    
    Yahoo!路線情報 運行情報
    ==========================================
    xxxさんの登録した路線において、遅延、事故、運転見合わせなどが発生しました。
    
    路線名：総武本線[千葉〜銚子]
    
    07:15頃、総武線(快速)内で線路内点検を行った影響で、千葉〜佐倉駅間の一部列車に遅れが出ています。
    （2月17日8時00分現在）
    
    最新の情報はこちらでご確認ください。
    http://transit.loco.yahoo.co.jp/traininfo/detail/62/0/
    
    -------------------------------------------------------------------------------
    <お知らせ>
    飛行機の運航情報もYahoo!路線情報サイトでご確認いただけます。
    国内線も国際線も、日本の航空路線の多くをカバーする主要5空港の情報をお届けします。
    フライト情報はこちら（※メール配信機能は現在対応しておりません）
    http://yahoo.jp/NR78YH
    -------------------------------------------------------------------------------
    このメールに返信されても、運行情報に関するお問い合わせにはお答えできません。
    運行情報メールの配信停止・設定変更: http://transit.loco.yahoo.co.jp/diaedit/mail
    ヘルプ・お問い合わせ: http://help.yahoo.co.jp/help/jp/transit/
    -------------------------------------------------------------------------------
    Copyright (C) 2015 レスキューナウ All rights reserved.
    Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved.
    
[/code]


CC BY-SA 3.0
2015-02-23T11:48:58.707
6970
2015-03-03T22:55:37.903
2015-02-24T01:32:11.000
8501
8501
question
php
PHPにパイプしたメールの日本語文字列の検索ができません。


コメントしてくださった方々のおかげで解決いたしましたので、まとめておきます。

[code]

    mb_convert_encoding($wmail, 'UTF-8', 'ISO-2022-JP');
    
[/code]

を挿入したところ、無事に日本語文字列を検索することができました。メールのencodingと、phpのencodingを統一する必要があったようです。

mb_convert_encodingは、`string mb_convert_encoding ( string $str , string
$to_encoding [, mixed $from_encoding = mb_internal_encoding() ] )`  
と定義されているように、`mb_convert_encoding(変換する文字列, 変換後のencoding,
変換前のencoding);`の順番です。encodingは両方とも指定する必要があります。

メールのencodingはメールのheader内で確認できますが、転送などを行うと、headerが書き換えられてしまうので要注意です。検証を行う際、メールをtextファイルにして、以下のようにパイプしました。textファイルを保存する際は、encodingをISO-2022-JPなど、オリジナルのencodingにすることに注意してください。

[code]

    $ cat test.txt | parse.php
    
[/code]

以下、Yahoo!路線情報から受信したメールをforwarderでパイプし、「路線名：」から「現在）」までの文字列をMySQLにINSERTする.phpのコードです。

[code]

    #!/usr/local/bin/php
    <?
    
    $stdin = fopen('php://stdin' , 'r');
    while (!feof($stdin))
    {
        $line = trim(fgets($stdin, 4096));
        $wmail .= "\n" . $line;
    }
    fclose ($stdin);
    
    $wmail = mb_convert_encoding($wmail, 'UTF-8', 'ISO-2022-JP');
    
    // 解析
    $findme = "路線名：";
    $start_position = strpos($wmail, $findme);
    if ($start_position === false) exit();
    
    $findme = "現在）";
    $end_position = strpos($wmail, $findme);
    if ($end_position === false) exit();
    
    $end_position = $end_position + 9;
    
    $message = mb_substr($wmail, $start_position, $end_position - $start_position);
    
    // databaseへinsert
    $db = mysqli_connect('localhost', 'xxxxx', 'xxxxx', 'xxxxx');   
    if (!$db) exit();
    
    mysqli_set_charset($db, "utf8");
    
    $sql = sprintf("INSERT INTO xxx SET 
    message = '%s'",
    strip_tags($message));
    mysqli_query($db, $sql);
    
    ?>
    
[/code]


CC BY-SA 3.0
2015-02-25T13:32:47.227
7085
2015-03-03T22:55:37.903
2015-03-03T22:55:37.903
8501
8501
6970
answer