例によって、taratail の回答用にコーディングしているときに画面をキャプチャしてみました。
動画
https://www.youtube.com/watch?v=PEDERfokvPU
<?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>