phpでメールを受け取り処理をする
2016年10月19日 17時30分
今更感が強いですがやる度に調べてる感じがしたのでメモ。
メールをパースするのにphp-mime-mail-parser/php-mime-mail-parserが便利なのでインストール。
|
composer require php-mime-mail-parser/php-mime-mail-parser |
もし下のエラーが発生した場合はエクステンションが足りないのでyum等でインストールする必要があります。
|
$ composer require php-mime-mail-parser/php-mime-mail-parser Problem 1 - Installation request for php-mime-mail-parser/php-mime-mail-parser ^2.5 -> satisfiable by php-mime-mail-parser/php-mime-mail-parser[2.5.0]. - php-mime-mail-parser/php-mime-mail-parser 2.5.0 requires ext-mailparse * -> the requested PHP extension mailparse is missing from your system. ; 別途エクステンションをインストール $ sudo yum install --enablerepo=epel,remi-php70 -y php-pecl-mailparse $ composer require php-mime-mail-parser/php-mime-mail-parser Using version ^2.5 for php-mime-mail-parser/php-mime-mail-parser ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) - Installing php-mime-mail-parser/php-mime-mail-parser (2.5.0) Downloading: 100% |
MTA側も設定します。今回はpostfixです。
直接コマンドをaliasに記述することも可能ですが実行ユーザがnobodyになってしまうので一番簡単な実行ユーザを変える方法としてincludeを使用します。
下の例ではnotice宛にメールを受け取ると/path/to/commandの所有者でコマンドが実行されます。
/etc/alias
|
... notice: :include:/path/to/command |
includeを使用するためにはconfigでincludeを許可する必要があります。
/etc/postfix/main.cfに以下の設定を追加します。
|
allow_mail_to_commands = alias,forward,include |
実際のコマンドは/path/to/commandの中に記述します。
|
"| /usr/bin/php /path/to/command.php >> /path/to/command/log/command.log" |
php側ではstdinにメール内容が入ってくるのでそれを処理
|
$parser = new PhpMimeMailParser\Parser(); $parser->setStream(fopen("php://stdin", "r")); // 本文取得 $parser->getMessageBody(); // https://github.com/php-mime-mail-parser/php-mime-mail-parser に大体書いてある |
絵文字とか文字コードとかはかなり制限された内容だったので今回は関係なかったので特にハマる場所無し。
php5.6からphp7へ移行した
2016年01月01日 14時40分
年も明けたのでこのサーバ(CentOS7)のphpを5.6から7に移行しました。
評判通り体感できるレベルで高速化された。
バージョンあげるだけで速度が改善されるなんてありがたい。
その際の作業メモ。
インストール手順
|
# php5.6のアンインストール sudo yum remove php* # remi リポジトリは追加済み sudo yum install --enablerepo=epel,remi,remi-php70 php php-cli php-devel php-mbstring php-pecl php-xml php-json php-imagick # http server 再起動 systemctl restart httpd |
Laravel4製のアンテナサイトは全くのノントラブル、piwik、mediawikiも問題なし。
ただWordpressが画面真っ白になってしまったので調査開始。
トラブル.1 SSH2ライブラリがyum経由でインストールできない
yumでssh2エクステンションをインストールしようとするとエラーが発生してインストールできない。
ssh2エクステンションはWordpressのアップデートで使用している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
sudo yum install --enablerepo=epel,remi,remi-php70 php-ssh2 --> Finished Dependency Resolution Error: Package: php-pecl-ssh2-0.12-3.el7.remi.5.4.x86_64 (remi) Requires: php(api) = 20100412-64 Installed: php-common-7.0.1-1.el7.remi.x86_64 (@remi-php70) php(api) = 20151012-64 Available: php-common-5.4.16-36.el7_1.x86_64 (base) php(api) = 20100412-64 Available: php-common-5.4.45-1.el7.remi.x86_64 (remi) php(api) = 20100412-64 Available: php-common-5.4.45-2.el7.remi.x86_64 (remi) php(api) = 20100412-64 Available: php-common-7.0.0-1.el7.remi.x86_64 (remi-php70) php(api) = 20151012-64 Error: Package: php-pecl-ssh2-0.12-3.el7.remi.5.4.x86_64 (remi) Requires: php(zend-abi) = 20100525-64 Installed: php-common-7.0.1-1.el7.remi.x86_64 (@remi-php70) php(zend-abi) = 20151012-64 Available: php-common-5.4.16-36.el7_1.x86_64 (base) php(zend-abi) = 20100525-64 Available: php-common-5.4.45-1.el7.remi.x86_64 (remi) php(zend-abi) = 20100525-64 Available: php-common-5.4.45-2.el7.remi.x86_64 (remi) php(zend-abi) = 20100525-64 Available: php-common-7.0.0-1.el7.remi.x86_64 (remi-php70) php(zend-abi) = 20151012-64 You could try using --skip-broken to work around the problem You could try running: rpm -Va --nofiles --nodigest |
しょうがないからソースからコンパイルしてインストール。
|
wget https://github.com/Sean-Der/pecl-networking-ssh2/archive/php7.zip unzip php7.zip cd pecl-networking-ssh2-php7 phpize ./configure make make install echo "extension = ssh2.so" > /etc/php.d/ssh2.ini systemctl restart httpd.service |
無事、認識した。
トラブル.2 プラグインがphp7対応できていない
ログを確認してみるとplugins/以下のファイルでsplitとかeregiなどが使われていてエラーになっていた。
消しても問題無さそうなプラグインだったので削除して回避。
発生したトラブルはこれだけだった。
本体は全く問題なく動いている。
7.0移行用のチェッカーを使うとソース側の問題は先に潰すことができる。
PHP 7 Compatibility Checker(php7cc)
https://github.com/sstalle/php7cc
phpカンファレンス2014に参加してきた
2014年10月12日 01時01分
phpカンファレンス2014に参加してきたので忘れる前に書き留めます。
ちなみに去年のやつはこちら。
mysqlnd 徹底解説
あんまり意識しないレイヤーのlibmysqlとmysqlnd違いをライブラリのソースコードレベルで解説。
fetchの中の挙動とかディープな内容だった。
とりあえず意識しないといけないのはmysqlnd使っててPrepared Statement使う場合。
クライアントサイド(PDO::ATTR_EMULATE_PREPARES : true)とサーバサイド(PDO::ATTR_EMULATE_PREPARES : false)で結果の型が違って、場合によっては値が違ってくるのは衝撃的でした。
これ知らずにハマってたら解決まで長引きそう。
このセッションで受けた印象としてはmysqlndはまだ枯れてないという感じ。
mysqlndの作成理由がlibmysqlのライセンス(GPLv2)が主ということなら、それが問題にならないケースの場合はlibmysqlでええんでないかいと思う程には保守的です。
安全なPHPアプリケーションの作り方2014 〜必要最低限のセキュリティ対策はこれだ〜
目当ての徳丸先生セッション。(徳丸さん×大垣さんはその場に居るだけで胃が痛くなりそうなのでパスしました)
3大脆弱性(CSRF、XSS、SQL Injection)を解説、デモ、対策を順にやって説明。
やっぱ実演があるととても分かりやすいです。
以下、セッション中の徳丸先生の話の中で気になったもの。
○ 独学で本一冊を最後まで仕上げる(やりきる)のは大変、その点は褒められるべき
「その点」というのは『脆弱性を含む本で勉強していても』という流れだったような気がします。
積み本してる身としては耳が痛い言葉だったけど、だからこそ本当にそう思います。
特に仕事で必要に迫られてじゃなく知的好奇心とかが動機だとその行為は何よりも尊いし大切にしたい。
○ サンプルプログラムの乱数生成方法
乱数を生成するのにuniqidやmt_randを使うのは避けてopenssl_random_pseudo_bytesか/dev/urandomを使いましょう。という先生のサンプルの乱数生成方法がこんな感じだった。
なるほどという感じ。
|
bin2hex(file_get_contents('/dev/urandom', false, null, 0, 24)); |
今日から始める PHPエンジニアのためのアクセスログ解析基盤構築入門
http://who-you-me.github.io/slides/phpcon2014/#/
入門的なセッションの場合はそういうツールがあるよというのを知るのが大切(なはず)。
実際、ツールの紹介と基本的な使い方が主。
ということで出てきたツールやサービス一覧
-
Elasticsearch
-
オープンソース検索エンジン
-
Kibana
-
上記ElasticsearchのGUI。サードパーティ製だと思ってたらオフィシャルだった。
-
BigQuery
-
Google社のSaaS型データストア。
課金が安いらしい。
-
fluentd
-
treasuredata製のログ収集管理ツール。
この辺りに関しては去年試してみるかと思い立って調べてみたけど、結局サーバがVPS一台しかなかったのでやるのは今じゃないという結論に達したのを思い出した。
なんかフル活用出来るようなサービスを立ち上げたい。
今年は3セッションで体力尽きました。
でも公式見たらustreamで動画公開してくれてるのでそれ後でチェックしよう。
スタッフや関係者の方々、素晴しい発表していただいた方々、素敵な時間をありがとうございました。
第12回本当は怖くないシェル芸勉強会に参加してきた
2014年08月04日 01時15分
第12回本当は怖くないシェル芸勉強会&第29回本が出たよUSP友の会定例会に参加してきました。
http://usptomo.doorkeeper.jp/events/12763
シェル芸本を買ったは良いけど時間とれずにろくに読めて無く、awkを使ったことがほぼ無い状態でしたがサイン欲しかったというミーハーな理由のみで参戦してみました。
電子書籍の売上は芳しいけど紙の初版を売り切らないと今後のシェル芸本にも悪い影響が出そうなニュアンスをイントロで言っていたので買ってない人は紙媒体もよろしくお願いします。
私は本の冒頭のやり取りだけで十分新しい知見を得られました。
イントロが終わったら急に問題を紹介されて「さ、やってみて」と言われて「えっ、もうやるんすか!?」状態だったけどなんていうかアルゴリズム考えるこの感じ、すっごい久しぶりで学生の時のゲーム作ってる時のような感覚を久々に味わえました。
普段はアルゴリズムというよりはフレームワークに乗っかってひたすら手続き書いてるようなことが多いので頭使う部分がやっぱ全然違うんだということを再認識。
やっぱ何か解決することを考えるのに道が色々あってそれを導きだすのは楽しいです。
ただね、この勉強会は色々なコマンド知ってないと歯が立たないです。
普段からパイプでコマンド3つ以上繋げて無意識にシェル芸している人じゃないと問題に立ち向かえない気がする。
そこでPHPerな私はPHPワンライナーで立ち向かったのです!
というかPHPのワンライナー機能があることをこの会場で調べて初めて知りました。
|
cat filename | php -B '{最初に一回行う処理}' -R '{各行に行う処理}' -E '{最後に一回行う処理}' |
PHPにもBEGINとENDがあるんですよ。
-Rには $argnという変数に各行の内容が入り$argiに行番号が入ります。
これで戦える。
問題と正解例を上田さんのブログで公開されています。
http://blog.ueda.asia/?p=3535
で、ノリで下のTweetしたらまさかのピックアップですよ。
そんでもって上田さんのPCで実行したらphpがインストールされてないからphp-cliをapt-getしろと出てるのを見てphpの場違いさを肌に感じた次第です。
いるのか分からないけど折角だからPHPワンライナーの例です。(可読性の為に改行してますがコマンドは一行です)
続きをみる
PHPで送ったメールをOutlookで確認するとヘッダが本文に表示されたり改行が倍になったりする
2014年01月24日 19時53分
サーバ環境が変わったとたんに秘伝のソースプロジェクトから送られたメールをOutlook(報告があったのは2003,2007)で確認すると本文中にメールヘッダが出てきたり、本文中の改行が2倍になったりする症状が発生した。
こんな感じ。
環境の違いはガッツリ変わっててMTAがsendmailからpostfixに変更。
また、phpのバージョンが5.1から5.5になった。
調べてみるとやっぱり同じ症状に悩む人が結構いたらしくすぐ情報が見つかる。
共通して言ってることはqmailやpostfixの場合は改行コードを統一しないとまずいということ。
LFに統一したらすぐ治ったが全くの思い込みでドハマリしたのがヒアドキュメント中の改行コード。
今までコード中の改行コードがそのまま反映されるものと思っていたがどうもPHP_EOLになる挙動をする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
// コード中の改行コードは全てCRLF // ヒアドキュメントのみ $message1 = <<<COUT hello, world! COUT; $inner_message = "hello, world!\r\n"; // ヒアドキュメント中に改行(\r\n)を持つ変数を展開 $message2 = <<<COUT {$inner_message} COUT; var_dump(str_replace(array("\r", "\n"), array("<CR>", "<LF>"), $message1)); var_dump(str_replace(array("\r", "\n"), array("<CR>", "<LF>"), $message2)); var_dump(str_replace(array("\r", "\n"), array("<CR>", "<LF>"), PHP_EOL)); |
Windows(Win7, Apache2.2, PHP5.5)で確認すると改行は全てCRLFで思った通りの改行コードになっている。
|
string(37) "<CR><LF>hello, world!<CR><LF><CR><LF>" // ヒアドキュメントのみ string(37) "<CR><LF>hello, world!<CR><LF><CR><LF>" // ヒアドキュメント中に改行(\r\n)を持つ変数を展開 string(8) "<CR><LF>" // PHP_EOL |
しかし、Linux(CentOS6.5, Apache2.2, PHP5.5)で確認すると変数に入れた\r\nのみCRLFで、ヒアドキュメント中の改行は全てLFになっていた。
|
string(25) "<LF>hello, world!<LF><LF>" // ヒアドキュメントのみ string(29) "<LF>hello, world!<CR><LF><LF>" // ヒアドキュメント中に改行(\r\n)を持つ変数を展開 string(4) "<LF>" // PHP_EOL |
こうなるとMTA側でLFをCRLFに変換した時にCRCRLFという改行コードができてメーラーによってマチマチの挙動になっていたと納得。
後、注意すべき点としてはmb_encode_mimeheaderも長い場合は自動で改行するので引数渡して改行コードを指定し、本文の改行コードと合わせる必要がある。
- PHP: mb_encode_mimeheader
-
http://www.php.net/manual/ja/function.mb-encode-mimeheader.php