alt sendmail

メールを送信するプログラムを作るときのローカルテストでは、メールをデータベースに保存し、実際には送信しないようにしています。
内容の確認は専用の Web インターフェースで...と言いたいところですが、psql
以下はそのための設定と PHP スクリプトです。


php.ini

sendmail_path = "/usr/local/bin/keepmail"


/usr/local/bin/keepmail

#!/usr/local/bin/php
<?php
error_reporting(E_ALL & ~E_STRICT);
require_once 'Mail/mimeDecode.php';

$input = stream_get_contents(STDIN);
$params = array(
    'include_bodies' => true,
    'decode_bodies'  => true,
    'decode_headers' => true,
    'input' => $input,
    'crlf'  => "?r?n",
);
$mime = Mail_mimeDecode::decode($params);

if (PEAR::isError($mime)) {
    fwrite(STDERR, $mime->getMessage());
    fwrite(STDERR, PHP_EOL);
    exit(1);
}

$headers = $mime->headers;
$body = '';
if (property_exists($mime, 'body') && is_string($mime->body)) {
    $body = $mime->body;
} elseif (property_exists($mime, 'parts') && is_array($mime->parts)) {
    foreach ($mime->parts as $part) {
        if (property_exists($part, 'body') && is_string($part->body)) {
            $body = $part->body;
            break;
        }
    }
}

mb_convert_variables('UTF-8', 'ISO-2022-JP-MS,UTF-8,CP51932,SJIS-win,ISO-8859-1', $headers, $body);
$body = preg_replace('/??r??n|??r|??n/u', "?n", $body);

try {
    $dbh = new PDO('pgsql:host=localhost port=5432 dbname=mail user=mail password=mail');
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $sql = 'INSERT INTO "mail_log"'
         . ' ("from", "to", "subject", "headers", "body", "raw")'
         . ' VALUES (:from, :to, :subject, :headers, :body, :raw)';
    $sth = $dbh->prepare($sql);
    foreach (array('from', 'to', 'subject') as $param) {
        if (array_key_exists($param, $headers)) {
            $sth->bindParam(":$param", $headers[$param], PDO::PARAM_STR);
        } else {
            $sth->bindParam(":$param", null, PDO::PARAM_NULL);
        }
    }
    $sth->bindParam(':headers', serialize($headers),    PDO::PARAM_STR);
    $sth->bindParam(':body',    $body,                  PDO::PARAM_STR);
    $sth->bindParam(':raw',     base64_encode($input),  PDO::PARAM_STR);
    $sth->execute();
} catch (PDOException $e) {
    fwrite(STDERR, $e->getMessage());
    fwrite(STDERR, PHP_EOL);
    exit(1);
}

exit(0);

/*
CREATE TABLE "mail_log" (
    "id"        serial,
    "date"      timestamp with time zone NOT NULL default CURRENT_TIMESTAMP,
    "from"      text,
    "to"        text,
    "subject"   text,
    "headers"   text NOT NULL,
    "body"      text NOT NULL,
    "raw"       text NOT NULL,
    PRIMARY KEY ("id")
);
CREATE INDEX "mail_log_date_idx" ON "mail_log" ("date");
*/
?>