[PHP]ソケット接続(fsockopen)でメール受信(POP3)

POP before SMTP をする際など、ちょっとした POP 認証をしておきたい時のために
単純なメール受信クラスを作ってみました。
open() でメールサーバーに接続し retrieve() で受信できます。

【注意】
このクラスは学習目的のサンプルです。
実用の際は PEAR::Net_POP3 などを利用して下さい。

・Pop3Retrieve.php

<?php
class Pop3Retrieve{
	private $connect;

	//接続
	function open($host, $user, $pass, $port=110){
		$this->connect = fsockopen( $host, $port, $err, $errno );
		if ( !$this->connect ) {
			return false;
		}
		
		fputs($this->connect, "USER {$user}\r\n");
		if(!$this->check_response()) return false;

		fputs($this->connect, "PASS {$pass}\r\n");
		if(!$this->check_response()) return false;
	}
	
	//レスポンスコード確認
	function check_response(){
		$buf = fgets($this->connect, 512);
		if( substr($buf, 0, 3) != '+OK' ) {
			return false;
		} else {
			return true;
		}
	}

	//メール数確認
	function status(){
		fputs($this->connect, "STAT\r\n");
		
		if( !$this->check_response() ) return false;
		$buf = fgets($this->connect, 512);
		sscanf($buf, '+OK %d %d', $num, $size);
		
		return $num;
	}
	
	//num番目のメールを受信
	function retrieve($num=1){
		$default_timeout = ini_get('default_socket_timeout');
		stream_set_timeout($this->connect, 3);
		
		fputs($this->connect, "RETR {$num}\r\n");

		if( !$this->check_response() ) return false;
		
		$data = "";
		$line = "";
		
		while ( !feof($this->connect) ) {
			$meta_data = stream_get_meta_data($this->connect);
			if($meta_data["timed_out"]) break;
			
			$line = fgets($this->connect);
			if($line === false || preg_match("/^\.\r\n/", $line)) break;
			$line = preg_replace("/^\.\./", ".", $line);
			$data .= $line;
		}
		
		stream_set_timeout($this->connect, $default_timeout);
		
		return $data;
	}
	
	//削除
	function delete($num=1){
		fputs($this->connect, "DELE {$num}\r\n");

		if( !$this->check_response() ) return false;
	
	}

	//終了
	function close(){
		fputs($this->connect, "QUIT\r\n");
		if( !$this->check_response() ) return false;
		
		fclose($this->connect);
	}
}

・使い方

<?php
include_once "Pop3Retrieve.php";

$host = 'tcp://mail.sample.com';
$user = 'user';
$pass = 'password';
$port = 110;

$pop3 = new Pop3Retrieve();
$pop3->open($host, $user, $pass, $port);

//総数を確認
$count = $pop3->status();

//全て受信
$mail = array();
for($i=1;$i<=$count;$i++){
	$mail[] = $pop3->retrieve($i);
}

$pop3->close();

取得されたメールはデコードされていない状態なので、
本文や件名などをパースする場合は PEAR の Mail_mimeDecode などを使うのが便利です。

POP Before SMTP 対策だけが目的であれば imap_open() 関数を使ったほうが簡単かもしれません。

$result = imap_open( sprintf('{%s:%d/pop3}INBOX', $host, $port), $user ,$pass );

サーバーによっては「/notls」フラグを追加する必要があります。

$result = imap_open( sprintf('{%s:%d/pop3/notls}INBOX', $host, $port), $user ,$pass );

MacでのPHP開発におすすめのテキストエディタ比較

以前 Windows でのPHP開発に便利なテキストエディタのレビュー記事を書きましたが、
今回は Mac 対応のテキストエディタをいくつか比較してみます。

今回ソフトウェアを選ぶ際、次の点を重要視しました。

  • Shift-JIS、EUC-JP の自動認識に対応していること
  • プログラミング言語に応じた色分けができること
  • 関数一覧からその行にジャンプできること
  • 複数行をまとめてインデントできること

注意: 記事に使われているスクリーンショットは設定変更後のものです


Atom

https://atom.io

atom

Github社によって作られたクロスプラットフォームのテキストエディタ。
初期状態でも十分な機能を持ち、プラグインで拡張すれば強力なデバッグツールにもなります。
各種文字コードへの対応、入力補完、優秀なインデントができ、定番のテキストエディタといえる程の人気があります。

Visual Studio Code

https://code.visualstudio.com

Microsoft が開発した Electron ベースのテキストエディタです。
Shift-JIS、EUC-JP などの文字コードに標準で対応し、入力補完、マルチカーソル、画面分割機能などの便利な機能を一通り備えています。
拡張機能にも対応しているので Git との連携なども簡単にできます。JSON むき出しの設定画面はいまひとつ洗練されていない印象を受けますが動作自体は概ね安定しており、Atom とは良きライバルのような状態です。


Sublime Text

http://www.sublimetext.com

sublimetext
(※写真はベータ版のものです)

かなり愛用者の多いテキストエディタです。オートインデントや入力補完が他のテキストエディタ以上に優秀で、快適な作業ができるのが魅力です。
プラグインに対応しており、自由に拡張できます。そのせいかプラグイン依存度が高く、ConvertToUTF8 等のプラグインを利用しないと Shift-JIS や EUC-JP などのマルチバイト文字を扱うことができません。(執筆時 ver. Build 3059)
本体や OS のアップデートによりプラグインとの相性問題が発生した場合プラグインのアップデートを待つ必要が生じるのはリスクが有りますが、UTF-8 以外を使うことが無いのであれば最高のテキストエディタだと思います。
最近では上述の Atom や VS Code の登場によりシェアを奪われつつ有ります。


PhpStorm

http://www.jetbrains.com/phpstorm/

phpstorm

PHP 専用の IDE です。
デバッグ機能に優れており、エラー箇所を色で簡単に判別できます。
大型プロジェクトの開発を行うなら必須と言っても過言ではありません。
起動やインデックス作成にはやや時間がかかりますが、起動後は比較的に快適です。
年間アップデートライセンスという方式をとっており、ライセンス購入後一年間は無償でアップデートできます。
ライセンスが切れた場合はアップデートができなくなりますが、使用を継続することはできます。
オープンソースプロジェクトの開発や教育関係者(教師・生徒)に限り無料で利用することもできます。


BBEdit (Mac専用)

http://www.barebones.com

bbedit

HTML の編集に特化したテキストエディタで、タグなどを定型文として簡単に挿入できます。
内部ブラウザを搭載し、変更と同時にプレビューをすることができるので、HTML のみを編集する際は便利です。
ファイルの差分を調べたり、FTP/SFTP を使ってサーバーに保存する事もできます。

各種言語の関数名予測補完、正規表現を使ったフォルダ内ファイル検索を備えています。
タブ形式ではなく、サイドバーのファイル一覧からファイルを選択するタイプです。

やや高価ではあるものの、軽量で起動が早く、テキストエディタとしての機能が充実しているので使いやすいです。


Text Wrangler (Mac専用)

http://www.barebones.com

textwrangler

上記 BB Edit の無償版です。
基本的な機能はそのままで、HTMLタグの定型文挿入機能や内部ブラウザによるプレビュー機能等が省略されています。
関数名の予測補完も有りませんが、その分動作は軽く、無料で使えるテキストエディタの中ではかなり優秀です。


Komodo Edit

https://www.activestate.com/komodo-edit

komodo-edit

Active State の Komodo IDE からテキスト編集機能を独立させたフリーのテキストエディタです。Mac、Windows、Linux で利用でき、多数の言語のハイライトに対応しています。
括弧の自動対応、矩形選択、関数の自動補完を備えるプログラマ向けのソフトウェアで、PHP インタープリターへのパスを設定しておくと、PHP の構文エラーを自動的に検出してくれます。
日本の文字コードも標準で扱うことができ、UTF-8 はもちろん Shift_JIS、EUC-JP も使用可能です。


Textastic

http://www.textasticapp.com/mac.html

textastic

もともとは iPad 向けのテキストエディタを Mac 用に移植したものです。
全体的にはシンプルですが、押さえるべきところをきちんと押さえてあって良い印象です。
Shift-JIS, EUC-JP 等の文字コードが扱えて、PHP の関数補完もできるので基本的に困ることはありません。
安価かつ軽量なテキストエディタを求めるのであれば良い選択肢になり得ると思います。


mi

http://www.mimikaki.net

mi
※写真はベータ版のものです

国産のテキストエディタであるため、日本特有の文字コードの自動認識に強いです。
テキストエディタに求められるほとんどの機能を網羅している上に無料で利用できるので重宝します。
円記号とバックスラッシュの使い分けにも対応しているので安心できます。


Coda (Mac専用)

http://panic.com/jp/coda/

coda
※画像は Coda 2 のものです

Coda は PHP というよりも HTML 中心のサイト構築・管理に特化したテキストエディタ+FTPツールのようなものです。
プロジェクトをサイト単位で管理でき、本格的な FTP 機能で簡単にサイトの編集ができます。
内部ブラウザによるプレビューや透明度に対応した独自のカラーピッカーなどを備え、関数の補完も可能です。
「普段は HTML しか使わないけどたまには Javascript や PHP も使う」というタイプのユーザー向きです。


CotEditor (Mac専用)

http://coteditor.com/

coteditor

かなりシンプルなテキストエディタです。
大きなファイルではカラーリングに時間がかかることもありますが、関数名の入力候補表示や
関数リストによるジャンプ、矩形選択、バックスラッシュと円マークの切り替えなどの
基本的な機能は全て備えています。

[PHP]テキストに自動で段落分け<p>、改行<br />タグをつける(文字列のHTML化)

通常のテキストを自動整形して HTML 文書として出力するには、preg_split() で段落分けをし、
nl2br() で改行タグを付ける方法が簡単です。

2つ以上改行が連続した場合を段落分けと判断し、その他を改行として処理します。

<?php
$str = <<<EOD
段落1
二行目

段落2
二行目
EOD;

echo html_paragraph($str);

function html_paragraph($str, $xhtml=true){
	$arr = preg_split("/\R\R+/", $str, -1, PREG_SPLIT_NO_EMPTY);
	$result = "";
	foreach($arr as $value){
		$value = htmlspecialchars($value, ENT_QUOTES);
		$result .= '<p>' . nl2br($value, $xhtml) . "</p>\n";
	}
	return $result;
}

[出力結果]

<p>段落1<br />
二行目</p>
<p>段落2<br />
二行目</p>

「<br /><br />」のように改行タグを連続して使用するよりは
ソースとして綺麗になるのでブログの記事内容を出力する時などに使えると思います。