自分のコーディングの様子を動画キャプチャしたら面白かった


例によって、taratail の回答用にコーディングしているときに画面をキャプチャしてみました。


> [画像をアップロードするときに画像ファイルを選択して送信したのに、画像が選択されていないと表示される。](https://teratail.com/questions/62350)

動画
[https://www.youtube.com/watch?v=PEDERfokvPU](https://www.youtube.com/watch?v=PEDERfokvPU)

```php
<?php
ini_set('display_errors', true);
error_reporting(E_ALL);

define('UP_DIR', 'updir');

function h($string)
{
    return htmlspecialchars($string, ENT_QUOTES, 'utf-8');
}

/**
 * ファイルアップロードエラーを判定する
 * @param type $upfile
 * @return bool
 * @throws Exception
 */
function check_error($upfile)
{
    switch ($upfile['error']) {
        case UPLOAD_ERR_OK:
            return true;
        case UPLOAD_ERR_INI_SIZE:
            $err = 'アップロードされたファイルは、php.ini の upload_max_filesize ディレクティブの値を超えています。';
            break;
        case UPLOAD_ERR_FORM_SIZE:
            $err = 'アップロードされたファイルは、HTML フォームで指定された MAX_FILE_SIZE を超えています。';
            break;
        case UPLOAD_ERR_PARTIAL:
            $err = 'アップロードされたファイルは一部のみしかアップロードされていません。';
            break;
        case UPLOAD_ERR_NO_FILE:
            $err = 'ファイルはアップロードされませんでした。';
            break;
        case UPLOAD_ERR_NO_TMP_DIR:
            $err = 'テンポラリフォルダがありません。';
            break;
        case UPLOAD_ERR_CANT_WRITE:
            $err = 'ディスクへの書き込みに失敗しました。';
            break;
        case UPLOAD_ERR_EXTENSION:
            $err = 'PHP の拡張モジュールがファイルのアップロードを中止しました。';
            break;
    }

    if (!empty($err)) {
        throw new Exception($err);
    }
}

/**
 * ファイルタイプをチェックし、拡張子を返す
 * @param type $upfile
 * @return bool
 */
function check_extension($upfile)
{
    $arr_accept_mimes = [
        'jpg' => 'image/jpeg'
        , 'png' => 'image/png'
        , 'gif' => 'image/gif'
    ];

    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime_type = finfo_file($finfo, $upfile['tmp_name']);

    if (in_array($mime_type, $arr_accept_mimes)) {
        return array_search($mime_type, $arr_accept_mimes);
    }

    $msg = '許可されていないファイルタイプです。';
    throw new Exception($msg);
}

if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') === 'POST') {

    try {

        $upfile = $_FILES['upfile'];

        // エラーチェック
        check_error($upfile);

        // ファイルタイプチェック
        $extension = check_extension($upfile);

        $tmp_name = $upfile['tmp_name'];

        // ファイル保存先 + ファイル名
        $base_name = sha1_file($tmp_name) . '.' . $extension;

        if (!file_exists(UP_DIR)) {
            $msg = sprintf('%s ディレクトリが存在しません。', UP_DIR);
            throw new Exception($msg);
        }
        if (!is_writable(UP_DIR)) {
            $msg = sprintf('%s に書き込み権限がありません。', UP_DIR);
            throw new Exception($msg);
        }

        $destination = UP_DIR . DIRECTORY_SEPARATOR . $base_name;
        if (file_exists($destination)) {
            $msg = sprintf('同一のファイルがすでにアップロードされています。', UP_DIR);
            throw new Exception($msg);
        }

        move_uploaded_file($tmp_name, $destination);
    } catch (Exception $e) {
        $err = $e->getMessage();
    }
}
?><!DOCTYPE HTML>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .error {
                color: red;
            }
        </style>
    </head>
    <body>
        <form action="" enctype="multipart/form-data" method="post">
            <?php if (isset($err)) : ?>
                <p class="error">エラー: <?= h($err); ?></p>
            <?php endif; ?>

            <p>
                <label for="upfile">画像ファイル</label>
                <input type="file" name="upfile" id="upfile" />
            </p>
            <p>
                <button type="submit">アップロード</button>
            </p>
        </form>
    </body>
</html>
```