しばしばMVC的に「まずはメインのphp(=コントローラ)にアクセスさせる」ような作り方をすることがあります。ユーザがアクセスするURLをコントローラ側で解析して処理を分岐させるわけですね。

 

.htaccessを使って(ディレクトリやファイルが存在しない)すべてのアクセスを所定のphpスクリプトに引き渡します。

 

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /mysystem/index.php [L]

で、コントローラ(/mysystem/index.php)ではこんな感じで処理します。

<?php
// QueryString を取り出して分解
$QRYSTR = $_SERVER['QUERY_STRING'];
parse_str($QRYSTR, $QRYARR);

// RequestURI を解析
if (isset($_SERVER['REQUEST_URI'])) {
    $requri = $_SERVER['REQUEST_URI'];
    //    ? 以降(QueryString)を削除
    if ($pos = strpos($requri, '?')) $requri = substr($requri, 0, $pos);
    //    先頭が / だったら削除
    while (substr($requri, 0, 1) === '/') $requri = substr($requri, 1);
    //    最後が / だったら削除
    if (substr($requri, strlen($requri)-1) === '/') $requri = substr($requri, 0, strlen($requri)-1);
    $REQPATH = explode('/', $requri);
} else {
    heaader('content-type: text/plain');
    die('abort');
}
// pathの第一階層の文字列に該当するincファイルがあればそれを呼び出して終了

if (count($REQPATH) > 0) {
    $inc = $REQPATH[0] . '.inc';
    if (file_exists($inc)) {
        array_shift($REQPATH);
        include($inc);
        exit;
    }
}
// 処理できなければ404エラーにする
include ('404.inc');

#上記ソースは手元でテストしている環境のものです

 

 

ちなみに404エラーも多少凝ってます(苦笑

 

【404.inc】

<?php
session_start();
if ($_POST) include('mail.inc');

$token = sha1(microtime());
$_SESSION = [];
$_SESSION['token'] = $token;

header('HTTP/1.1 404 Not Found');
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<title>404:Not Found</title>
</head>
<body>
<div style="width:70%; margin-left:15%">
<h2>404&nbsp;:&nbsp;お探しのページは見つかりませんでした</h2>
当該URL(<?= $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] ?>)は移動または削除された可能性があります
</div>
<hr color="orange" style="color:orange; width:70%; margin-top:25px; margin-bottom:25px">
<div style="width:400px; margin-left:auto; margin-right:auto">
サイトに問題があれば、下記よりお知らせください。
<form method="post">
<table style="width:430px; margin-top:20px;">
<tr><td style="width:150px; padding-left:10px">お名前</td><td style="padding-left:10px"><input type="text" name="お名前" style="width:200px"></td></tr>
<tr><td style="padding-left:10px">E-Mail</td><td style="padding-left:10px"><input type="text" name="E-Mail" style="width:200px"></td></tr>
<tr><td style="padding-left:10px">メッセージ</td><td style="padding-left:10px"><textarea name="メッセージ" style="width:300px; height:150px"></textarea></td></tr>
<input type="hidden" name="*url" value="<?= $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] ?>" readonly style="width:300px">
<input type="hidden" name="*serverinfo" value="<?= htmlspecialchars(json_encode($_SERVER), ENT_QUOTES) ?>" readonly style="width:300px">
<input type="hidden" name="type" value="confirm">
<input type="hidden" name="token" value="<?= $token ?>">
<tr><th colspan="2"><input type="submit"></th></tr>
</table>
</form>
</body>
</html>

【mail.inc】

<?php
$html = [];
if ((isset($_POST['type']))&&(isset($_POST['token']))) {
    // token チェック
    $token = isset($_SESSION['token']) ? $_SESSION['token'] : '';
    if ($_POST['token'] !== $token) {
        header('content-type: text/plain');
        die('illegal access');
    }
    if ($_POST['type'] === 'mailsend') {
        // メール送信
        $html[] = '<div style="width:60%px; margin-left:20%">';
        $html[] = '<h2>下記内容を送信しました</h2>';
        $html[] = '</div>';
        $html[] = '<div style="width:400px; margin-left:auto; margin-right:auto">';
         $html[] = '<table style="width:430px; margin-top:20px;">';
         $mail = [];
         foreach ($_SESSION as $name=>$value) {
             if ($name === 'token') continue;
             if (substr($name, 0, 1) !== '*') {
                 $html[] = sprintf('<tr><td>%s</td><td>%s</td></tr>', $name, nl2br(htmlspecialchars($value, ENT_QUOTES)));
                 $mail[] = '[' . $name . ']';
                 $mail[] = $value;
             }
         }
        $mail[] = '----------------------------------------------------------------------';
        if (isset($_SESSION['*url'])) {
            $mail[] = 'URL';
            $mail[] = '    ' . $_SESSION['*url'];
        }
        $mail[] = '----------------------------------------------------------------------';
        if (isset($_SESSION['*serverinfo']))
            foreach (json_decode($_SESSION['*serverinfo'], true) as $name=>$value)
                if ($name !== 'PATH') {
                    $mail[] = $name;
                    $mail[] = '    ' . trim(str_replace(['<address>', '</address>'], '', $value));
                }
        $html[] = '</table>';
        mb_language('ja');
        mb_internal_encoding('utf-8');
        if (mb_send_mail('自分のメールアドレス', '404ページからの連絡', implode("¥r¥n", $mail)) === false)
            $html[] = 'Sending failed';
    }
    if ($_POST['type'] === 'confirm') {
        // 確認画面作成
        $token = sha1(microtime());
        $_SESSION['token'] = $token;
        $html[] = '<div style="width:60%px; margin-left:20%">';
        $html[] = '<h2>下記内容を送信します。よろしいですか?</h2>';
        $html[] = '</div>';
        $html[] = '<div style="width:400px; margin-left:auto; margin-right:auto">';
        $html[] = '<form method="post">';
        $html[] = '<table style="width:430px; margin-top:20px;">';
        foreach ($_POST as $name=>$value) {
            if (($name === 'type')||($name === 'token')) continue;
            if (substr($name, 0, 1) !== '*')
                $html[] = sprintf('<tr><td>%s</td><td>%s</td></tr>', $name, nl2br(htmlspecialchars($value, ENT_QUOTES)));
            $_SESSION[$name] = $value;
        }
        $html[] = '<input type="hidden" name="type" value="mailsend">';
        $html[] = '<input type="hidden" name="token" value="' . $token . '">';
        $html[] = '<tr><th colspan="2"><input type="submit"></th></tr>';
        $html[] = '</table>';
        $html[] = '</form>';
    }
}
if (count($html) === 0) {
    header('content-type: text/plain');
    die('type error');
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Mail send</title>
</head>
<body>
<?= implode(PHP_EOL, $html) ?>
</body>
</html>

自分(管理者)宛てなので、手抜きしてmb_send_mailです(外に送るならphpmailer必須)。

関連する記事
コメント
コメントする