mb_send_mailでメールフォーム

投信の会社などは、メールフォームがないのがトレンドのようですが、
さて、mb_send_mailを使います。vagrant postfixで設定している為、fromの挙動が異なります。

form.php

<title>Form</title>
<body>
	<form action="send.php" method="post">
	件名:<br>
	<input type="text" name="subject" size="30" value=""/><br>
	送信者名:<br>
	<input type="text" name="name" size="30" value=""/><br>
	メールアドレス:<br>
	<input type="text" name="mail" size="30" value=""/><br>
	本文:<br>
	<textarea name="message" cols="30" rows="5"></textarea><br>
	<br>
	<input type="submit" value="送信する"/>
	</form>
</body>

send.php

<?php

$message = "名前:" .htmlspecialchars($_POST&#91;"name"&#93;)."\n本文:".htmlspecialchars($_POST&#91;"message"&#93;);
if(!mb_send_mail("hoge@gmail.com", $_POST&#91;"subject"&#93;, $message, "From:".$_POST&#91;"mail"&#93;)){
	exit("error");
}
?>
<p>メールが送信されました</p>

php-imapのインストール

Postfixのdependency(remi)を解消してsudo yum install php-imap後、php.iniでextension=imap.soを追加しても、
全くphpinfo()に反映されず、vagrant haltしたり、php.iniを編集したり、
他のサイトを見ながら5時間くらい色々試しても全然ダメで、
あきらめてカタ焼きそば食って再度vagrant upしてみたら、入っている!? 何故だ? さっぱりわからん。

とりあえずエラーは出ない模様

$imapPath = '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX';
$username = 'hoge@gmail.com';
$password = 'pass';
 
// try to connect
$inbox = imap_open($imapPath,$username,$password) or die('Cannot connect to Gmail:'.imap_last_error());
$mailHost = 'imap.googlemail.com';
$mailPort = 993;
$mailAccount = 'hoge@gmail.com';
$mailPassword = '';
$mailBox = imap_open('{' . $mailHost . ':' . $mailPort . '/novalidate-cert/imap/ssl}' . "INBOX", $mailAccount, $mailPassword);
if (!$mailBox) {
	echo '接続失敗';
}
echo '接続成功';

あれあれあれ

vagrantでのメール送受信

サーバーにグローバルなドメインが設定されていない場合、送受信できないとのこと。理由として、mail.hoge.localのドメインがLAN内のみ有効で世界のインターネット上では名前解決出来ない為。

個人情報に関わるからでしょうか、かなり厳しいですね。。

IMAPとは?

Internet Message Access Protocol(インターネット・メッセージ・アクセス・プロトコル)
メールを取り込む手順

->「POP」では、メールをいったんスマホやパソコンにダウンロードして取り込むと、サーバーから無くなってしまう
->「IMAP」では、ダウンロードするのはメールのコピー(キャッシュ)で、メール本体はサーバーに残ったまま

とりあえず、gmailのimapをonにします。

う~ん。。。

dovecot

1.インストール
sudo yum install -y dovecot

2.バックアップ
sudo cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.org

3.maildir形式
mail_location = maildir:~/Maildir

4.起動
sudo service dovecot start

smtpサーバーをsmtp.gmail.comで設定している場合、dovecot入れても意味ないのかな。
作りたいのはメールボックスそのものなんだが。

phpmailerで複数アドレス(配列)にBCCで送信

複数アドレス($addressの配列)をforeach の$mail->addBCC($value);で回せばOKですね。
$mail->addAddress(”);、$mail->addCC(”);は使わなければ、コメントアウトします。

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$address = array('target1@gmail.com','target2@hotmail.com','target3@yahoo.co.jp');

$mail = new PHPMailer(true);
try{
	$mail->SMTPDebug = 2;
	$mail->isSMTP();
	$mail->Host = 'smtp.gmail.com';
	$mail->SMTPAuth = true;
	$mail->Username = 'fromhoge@gmail.com';
	$mail->Password = 'app pass';
	$mail->SMTPSecure = 'tls';
	$mail->Port = 587;

	$mail->setFrom('fromhoge@gmail.com');
	// $mail->addAddress('');
	// $mail->addCC('');
	foreach($address as $value){
		$mail->addBCC($value);
	}
	
	$mail->addAttachment('test.gif');

	$mail->isHTML(true);
	$mail->Subject = 'Here we comes!';
	$mail->Body = 'This is the HTML message body <b>in bold</b>';
	$mail->AltBody = 'This is the body in plain text for non-HTML';

	$mail->send();
	echo 'messeage has been sent';
} catch (Exception $e){
	echo "Message could not be send, Mailer Error:", $mail->ErrorInfo;
}

BCCで問題なく届いてます。これは想像以上だな~

vagrant でphpmailerを使ってみる

まずは、composerを入れて、パッケージをダウンロード

[vagrant@localhost mail]$ curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer (version 1.6.3) successfully installed to: /home/vagrant/mail/composer.phar
Use it: php composer.phar

[vagrant@localhost mail]$ php composer.phar require phpmailer/phpmailer
Using version ^6.0 for phpmailer/phpmailer

続いて、コードを書いていきます。mail->Passwordはgmailのアプリパスワード。

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);
try{
	$mail->SMTPDebug = 2;
	$mail->isSMTP();
	$mail->Host = 'smtp.gmail.com';
	$mail->SMTPAuth = true;
	$mail->Username = 'fuga@gmail.com';
	$mail->Password = 'google app pass';
	$mail->SMTPSecure = 'tls';
	$mail->Port = 587;

	$mail->setFrom('fuga@gmail.com');
	$mail->addAddress('fuga@gmail.com');
	$mail->addCC('foo@hotmail.com');
	$mail->addBCC('hoge@yahoo.co.jp');

	$mail->addAttachment('test.gif');

	$mail->isHTML(true);
	$mail->Subject = 'Here we comes!';
	$mail->Body = 'This is the HTML message body <b>in bold</b>';
	$mail->AltBody = 'This is the body in plain text for non-HTML';

	$mail->send();
	echo 'messeage has been sent';
} catch (Exception $e){
	echo "Message could not be send, Mailer Error:", $mail->ErrorInfo;
}

なんじゃこりゃ、postfixとmb_send_mail()で頑張ってたのが、一瞬でできたぞ。

silicon valleyの人気テックニュースをphp x crontabで毎日自分のメールに送る

評価が高いフィードはこちら
https://www.techmeme.com/feed.xml
techmeme@sanfransisco

英語のニュースはブラウザで見ようと思っても長続きしないので、毎日メール&Cronで強制的に読む習慣をつける
フィードを見ると、画像はdescription内のIMGタグの中にあるので、正規表現preg_match_allで画像URLを取得する。
titleは見やすいように工夫。
クライアントからのリクエストはないので、ファイルはローカルに置いて、cron設定。

$rss = simplexml_load_file('https://www.techmeme.com/feed.xml');

mb_language("Japanese");
mb_internal_encoding("UTF-8");

$to = "notwatch@gmail.com";
$date = date("m月d日");
$subject = "Techmeme (" . $date.")";

$mime_type = "application/octet-stream";

$boundary = "__BOUNDARY__";

$additional_headers = "Content-Type: multipart/mixed;boundary=\"".$boundary."\"\n";
$message = "--" . $boundary . "\n";
$message .= "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n\n";
$i =0;
foreach($rss->channel->item as $value){
	if($i < 10){
	$k = $i + 1;
	$message .= $k.".".$value->title ."\n";
	$message .= $value->link . "\n";
	}
	$i++;
}
$message .="--" . $boundary . "\n";

$i = 0;
foreach($rss->channel->item as $value){
	if($i < 10){
	$description = $value->description;
    preg_match_all('|SRC=\"(.*?).jpg\"|', $description, $match);
    $url = $match[1][0].".jpg";
	$data = file_get_contents($url);
	$pass = "image/tech".$i.".jpg";
	file_put_contents($pass, $data);
	$message .="Content-Type:". $mime_type . "; name=\"" .basename($pass) . "\"\n";
	$message .="Content-Disposition: attachment; filename=\"" .basename($pass) ."\"\n";
	$message .="Content-Transfer-Encoding: base64\n";
	$message .= "\n";
	$message .= chunk_split(base64_encode(file_get_contents($pass)))."\n";
	$message .="--" . $boundary . "\n";
	}
	$i++;	
}

 
mb_send_mail($to, $subject, $message, $additional_headers);

話題は基本アメリカか中国かsamsungですね。日本終わってるなwww

RSSで取得した複数の画像をmb_send_mailで自動送信

画像もforeachで回します。

$rss = simplexml_load_file('https://jp.techcrunch.com/feed/');

mb_language("Japanese");
mb_internal_encoding("UTF-8");

$to = "notwatch@gmail.com";
$date = date("m月d日");
$subject = "今日のTech Chrunch (" . $date.")";

$mime_type = "application/octet-stream";

$boundary = "__BOUNDARY__";

$additional_headers = "Content-Type: multipart/mixed;boundary=\"".$boundary."\"\n";
$message = "--" . $boundary . "\n";
$message .= "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n\n";
foreach($rss->channel->item as $value){
	$message .= $value->title ."\n";
	$message .= $value->link . "\n";
}
$message .="--" . $boundary . "\n";

$i = 0;
foreach($rss->channel->item as $value){
	$url = $value->children('media', true)->thumbnail->attributes()->url;
	$data = file_get_contents($url);
	$pass = "img/tech".$i.".jpg";
	file_put_contents($pass, $data);
	$message .="Content-Type:". $mime_type . "; name=\"" .basename($pass) . "\"\n";
	$message .="Content-Disposition: attachment; filename=\"" .basename($pass) ."\"\n";
	$message .="Content-Transfer-Encoding: base64\n";
	$message .= "\n";
	$message .= chunk_split(base64_encode(file_get_contents($pass)))."\n";
	$message .="--" . $boundary . "\n";
	$i++;	
}

mb_send_mail($to, $subject, $message, $additional_headers);

あれ? これいいじゃん。

phpでRSSで取得したテキスト・画像を自動メール送信

media:thumbnail url=”hoge”は、以下で取得します。
$value->children(‘media’, true)->thumbnail->attributes()->url;

$rss = simplexml_load_file('https://jp.techcrunch.com/feed/');

$i = 0;
foreach($rss->channel->item as $value){
	$url = $value->children('media', true)->thumbnail->attributes()->url;
	$data = file_get_contents($url);
	$pass = "img/tech".$i.".jpg";
	file_put_contents($pass, $data);
	$i++;
}

mb_language("Japanese");
mb_internal_encoding("UTF-8");

$to = "notwatch@gmail.com";
$date = date("m月d日");
$subject = "今日のTech Chrunch (" . $date.")";

$filepath = "img/tech0.jpg";
$mime_type = "application/octet-stream";

$boundary = "__BOUNDARY__";

$additional_headers = "Content-Type: multipart/mixed;boundary=\"".$boundary."\"\n";
$message = "--" . $boundary . "\n";
$message .= "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n\n";
foreach($rss->channel->item as $value){
	$message .= $value->title ."\n";
	$message .= $value->link . "\n";
}
$message .="--" . $boundary . "\n";
$message .="Content-Type:". $mime_type . "; name=\"" .basename($filepath) . "\"\n";
$message .="Content-Disposition: attachment; filename=\"" .basename($filepath) ."\"\n";
$message .="Content-Transfer-Encoding: base64\n";
$message .= "\n";
$message .= chunk_split(base64_encode(file_get_contents($filepath)))."\n";
$message .="--" . $boundary . "--";
 
mb_send_mail($to, $subject, $message, $additional_headers);

お、まぁまぁいいやんけ!

写真複数いきたいですね。