{"id":2473,"date":"2021-08-31T08:51:51","date_gmt":"2021-08-31T08:51:51","guid":{"rendered":"https:\/\/phptutorial.net\/?page_id=2473"},"modified":"2025-04-08T06:26:21","modified_gmt":"2025-04-08T06:26:21","slug":"php-upload-multiple-files","status":"publish","type":"page","link":"https:\/\/www.phptutorial.net\/php-tutorial\/php-upload-multiple-files\/","title":{"rendered":"PHP Upload Multiple Files"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn how to upload multiple files to the server in PHP securely.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-the-php-upload-multiple-files'>Introduction to the PHP upload multiple files <a href=\"#introduction-to-the-php-upload-multiple-files\" class=\"anchor\" id=\"introduction-to-the-php-upload-multiple-files\" title=\"Anchor for Introduction to the PHP upload multiple files\">#<\/a><\/h2>\n\n\n\n<p>In the previous tutorial, you learned <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-file-upload\/\">how to upload a single file from a client to the webserver in PHP<\/a>. All the rules of uploading a single file are relevant to multiple files.<\/p>\n\n\n\n<p>First, the HTML form element must have the <code>enctype<\/code> attribute sets to <code>\"multipart\/form-data\"<\/code> to enable file uploading. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;form action=<span class=\"hljs-string\">\"upload.php\"<\/span> method=<span class=\"hljs-string\">\"post\"<\/span> enctype=<span class=\"hljs-string\">\"multipart\/form-data\"<\/span>&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, the file input element must have the <code>multiple<\/code> attribute and its name must have the square brackets (<code>[]<\/code>) like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;input type=<span class=\"hljs-string\">\"file\"<\/span> name=<span class=\"hljs-string\">\"files&#91;]\"<\/span> id=<span class=\"hljs-string\">\"files\"<\/span> multiple \/&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In PHP, you can access the <code>$_FILES['files']<\/code> to get the information of the uploaded files:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\nvar_dump($_FILES&#91;<span class=\"hljs-string\">'files'<\/span>]);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>'files'<\/code> is the name of the file input element.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='php-upload-multiple-files-example'>PHP upload multiple files example <a href=\"#php-upload-multiple-files-example\" class=\"anchor\" id=\"php-upload-multiple-files-example\" title=\"Anchor for PHP upload multiple files example\">#<\/a><\/h2>\n\n\n\n<p>The following example reuses the existing functions and logic developed in the <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-file-upload\/\">file upload tutorial<\/a>.<\/p>\n\n\n\n<p>First, create the following project structure:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">\u251c\u2500\u2500 inc\n|  \u251c\u2500\u2500 flash.php\n|  \u2514\u2500\u2500 functions.php\n\u251c\u2500\u2500 index.php\n\u251c\u2500\u2500 upload.php\n\u2514\u2500\u2500 uploads<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, add the following code to the <code>index.php<\/code> to create the file upload form:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\nsession_start();\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/inc\/flash.php'<\/span>;\n<span class=\"hljs-meta\">?&gt;<\/span>\n&lt;!DOCTYPE html&gt;\n&lt;html lang=<span class=\"hljs-string\">\"en\"<\/span>&gt;\n&lt;head&gt;\n    &lt;meta charset=<span class=\"hljs-string\">\"UTF-8\"<\/span>\/&gt;\n    &lt;meta name=<span class=\"hljs-string\">\"viewport\"<\/span> content=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0\"<\/span>\/&gt;\n    &lt;title&gt;PHP upload multiple files&lt;\/title&gt;\n    &lt;link rel=<span class=\"hljs-string\">\"stylesheet\"<\/span> href=<span class=\"hljs-string\">\"https:\/\/phptutorial.net\/app\/css\/style.css\"<\/span> \/&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n<span class=\"hljs-meta\">&lt;?php<\/span> flash(<span class=\"hljs-string\">'upload'<\/span>) <span class=\"hljs-meta\">?&gt;<\/span>\n&lt;main&gt;\n    &lt;form action=<span class=\"hljs-string\">\"upload.php\"<\/span> method=<span class=\"hljs-string\">\"post\"<\/span> enctype=<span class=\"hljs-string\">\"multipart\/form-data\"<\/span>&gt;\n        &lt;div&gt;\n            &lt;label <span class=\"hljs-keyword\">for<\/span>=<span class=\"hljs-string\">\"files\"<\/span>&gt;Select files to upload:&lt;\/label&gt;\n            &lt;input type=<span class=\"hljs-string\">\"file\"<\/span> name=<span class=\"hljs-string\">\"files&#91;]\"<\/span> id=<span class=\"hljs-string\">\"files\"<\/span> multiple required\/&gt;\n        &lt;\/div&gt;\n        &lt;div&gt;\n            &lt;button type=<span class=\"hljs-string\">\"submit\"<\/span>&gt;Upload&lt;\/button&gt;\n        &lt;\/div&gt;\n    &lt;\/form&gt;\n&lt;\/main&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>index.php<\/code> does the following:<\/p>\n\n\n\n<p>1) Start  a new session or resume an existing session:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">session_start();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>2) Load the code from the <code>inc\/flash.php<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/inc\/flash.php'<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>3) Call the <code>flash()<\/code> function to show a message with the name <code>'upload'<\/code>. The <code>flash()<\/code> function is defined in the <code>flash.php<\/code> file.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span> flash(<span class=\"hljs-string\">'upload'<\/span>) <span class=\"hljs-meta\">?&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>4) Create an upload form that submits to the <code>upload.php<\/code> file.<\/p>\n\n\n\n<p>Third, add the following code to the <code>upload.php<\/code> file to validate and upload multiple files:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-meta\">&lt;?php<\/span>\n\nsession_start();\n\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/inc\/flash.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/inc\/functions.php'<\/span>;\n\n<span class=\"hljs-keyword\">const<\/span> ALLOWED_FILES = &#91;\n    <span class=\"hljs-string\">'image\/png'<\/span> =&gt; <span class=\"hljs-string\">'png'<\/span>,\n    <span class=\"hljs-string\">'image\/jpeg'<\/span> =&gt; <span class=\"hljs-string\">'jpg'<\/span>\n];\n\n<span class=\"hljs-keyword\">const<\/span> MAX_SIZE = <span class=\"hljs-number\">5<\/span> * <span class=\"hljs-number\">1024<\/span> * <span class=\"hljs-number\">1024<\/span>; <span class=\"hljs-comment\">\/\/  5MB<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> UPLOAD_DIR = <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/uploads'<\/span>;\n\n\n$is_post_request = strtolower($_SERVER&#91;<span class=\"hljs-string\">'REQUEST_METHOD'<\/span>]) === <span class=\"hljs-string\">'post'<\/span>;\n$has_files = <span class=\"hljs-keyword\">isset<\/span>($_FILES&#91;<span class=\"hljs-string\">'files'<\/span>]);\n\n<span class=\"hljs-keyword\">if<\/span> (!$is_post_request || !$has_files) {\n    redirect_with_message(<span class=\"hljs-string\">'Invalid file upload operation'<\/span>, FLASH_ERROR);\n}\n\n$files = $_FILES&#91;<span class=\"hljs-string\">'files'<\/span>];\n$file_count = count($files&#91;<span class=\"hljs-string\">'name'<\/span>]);\n\n<span class=\"hljs-comment\">\/\/ validation<\/span>\n$errors = &#91;];\n<span class=\"hljs-keyword\">for<\/span> ($i = <span class=\"hljs-number\">0<\/span>; $i &lt; $file_count; $i++) {\n    <span class=\"hljs-comment\">\/\/ get the uploaded file info<\/span>\n    $status = $files&#91;<span class=\"hljs-string\">'error'<\/span>]&#91;$i];\n    $filename = $files&#91;<span class=\"hljs-string\">'name'<\/span>]&#91;$i];\n    $tmp = $files&#91;<span class=\"hljs-string\">'tmp_name'<\/span>]&#91;$i];\n\n    <span class=\"hljs-comment\">\/\/ an error occurs<\/span>\n    <span class=\"hljs-keyword\">if<\/span> ($status !== UPLOAD_ERR_OK) {\n        $errors&#91;$filename] = MESSAGES&#91;$status];\n        <span class=\"hljs-keyword\">continue<\/span>;\n    }\n    <span class=\"hljs-comment\">\/\/ validate the file size<\/span>\n    $filesize = filesize($tmp);\n\n    <span class=\"hljs-keyword\">if<\/span> ($filesize &gt; MAX_SIZE) {\n        <span class=\"hljs-comment\">\/\/ construct an error message<\/span>\n        $message = sprintf(<span class=\"hljs-string\">\"The file %s is %s which is greater than the allowed size %s\"<\/span>,\n            $filename,\n            format_filesize($filesize),\n            format_filesize(MAX_SIZE));\n\n        $errors&#91;$filesize] = $message;\n        <span class=\"hljs-keyword\">continue<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/ validate the file type<\/span>\n    <span class=\"hljs-keyword\">if<\/span> (!in_array(get_mime_type($tmp), array_keys(ALLOWED_FILES))) {\n        $errors&#91;$filename] = <span class=\"hljs-string\">\"The file $filename is allowed to upload\"<\/span>;\n    }\n}\n\n<span class=\"hljs-keyword\">if<\/span> ($errors) {\n    redirect_with_message(format_messages(<span class=\"hljs-string\">'The following errors occurred:'<\/span>,$errors), FLASH_ERROR);\n}\n\n<span class=\"hljs-comment\">\/\/ move the files<\/span>\n<span class=\"hljs-keyword\">for<\/span>($i = <span class=\"hljs-number\">0<\/span>; $i &lt; $file_count; $i++) {\n    $filename = $files&#91;<span class=\"hljs-string\">'name'<\/span>]&#91;$i];\n    $tmp = $files&#91;<span class=\"hljs-string\">'tmp_name'<\/span>]&#91;$i];\n    $mime_type = get_mime_type($tmp);\n\n    <span class=\"hljs-comment\">\/\/ set the filename as the basename + extension<\/span>\n    $uploaded_file = pathinfo($filename, PATHINFO_FILENAME) . <span class=\"hljs-string\">'.'<\/span> . ALLOWED_FILES&#91;$mime_type];\n    <span class=\"hljs-comment\">\/\/ new filepath<\/span>\n    $filepath = UPLOAD_DIR . <span class=\"hljs-string\">'\/'<\/span> . $uploaded_file;\n\n    <span class=\"hljs-comment\">\/\/ move the file to the upload dir<\/span>\n    $success = move_uploaded_file($tmp, $filepath);\n    <span class=\"hljs-keyword\">if<\/span>(!$success) {\n        $errors&#91;$filename] = <span class=\"hljs-string\">\"The file $filename was failed to move.\"<\/span>;\n    }\n}\n\n$errors ?\n    redirect_with_message(format_messages(<span class=\"hljs-string\">'The following errors occurred:'<\/span>,$errors), FLASH_ERROR) :\n    redirect_with_message(<span class=\"hljs-string\">'All the files were uploaded successfully.'<\/span>, FLASH_SUCCESS);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>How the <code>upload.php<\/code> works:<\/p>\n\n\n\n<p>1) Start a new session or resume an existing one:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">session_start();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>2) Load the code from the <code>flash.php<\/code> and <code>functions.php<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/inc\/flash.php'<\/span>;\n<span class=\"hljs-keyword\">require_once<\/span> <span class=\"hljs-keyword\">__DIR__<\/span> . <span class=\"hljs-string\">'\/inc\/functions.php'<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Note that you should use the <code>flash.php<\/code> from the <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-flash-messages\/\">flash message tutorial<\/a> and <code>functions.php<\/code> from the <a href=\"https:\/\/phptutorial.net\/php-tutorial\/php-file-upload\/\">file upload tutorial<\/a>.<\/p>\n\n\n\n<p>Since the <code>upload.php<\/code> deals with multiple files, it will issue multiple error messages, one for each uploaded file. <\/p>\n\n\n\n<p>To make it convenient, we can define a function that returns a single error message from multiple error messages like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">format_messages<\/span><span class=\"hljs-params\">(string $title, array $messages)<\/span>: <span class=\"hljs-title\">string<\/span>\n<\/span>{\n    $message = <span class=\"hljs-string\">\"&lt;p&gt;$title&lt;\/p&gt;\"<\/span>;\n    $message .= <span class=\"hljs-string\">'&lt;ul&gt;'<\/span>;\n    <span class=\"hljs-keyword\">foreach<\/span> ($messages <span class=\"hljs-keyword\">as<\/span> $key =&gt; $value) {\n        $message .= <span class=\"hljs-string\">\"&lt;li&gt;$value&lt;\/li&gt;\"<\/span>;\n    }\n    $message .= <span class=\"hljs-string\">'&lt;ul&gt;'<\/span>;\n\n    <span class=\"hljs-keyword\">return<\/span> $message;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>And add this <code>format_messages()<\/code> function to the <code>functions.php<\/code> file.<\/p>\n\n\n\n<p>3) Return an error message if the request method is not <code>POST<\/code> or the <code>$_FILES<\/code> does not contain the <code>files<\/code> field:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$is_post_request = strtolower($_SERVER&#91;<span class=\"hljs-string\">'REQUEST_METHOD'<\/span>]) === <span class=\"hljs-string\">'post'<\/span>;\n$has_files = <span class=\"hljs-keyword\">isset<\/span>($_FILES&#91;<span class=\"hljs-string\">'files'<\/span>]);\n\n<span class=\"hljs-keyword\">if<\/span> (!$is_post_request || !$has_files) {\n    redirect_with_message(<span class=\"hljs-string\">'Invalid file upload operation'<\/span>, FLASH_ERROR);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>4) Get the uploaded files from <code>$_FILES<\/code> and the number of files uploaded:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$files = $_FILES&#91;<span class=\"hljs-string\">'files'<\/span>];\n$file_count = count($files&#91;<span class=\"hljs-string\">'name'<\/span>]);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>5) For each uploaded file, check the error code and validate the file size, type. If an error occurred, add an error message to the <code>$errors<\/code> array, skip the current validation loop, and validate the next file.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ validation<\/span>\n$errors = &#91;];\n<span class=\"hljs-keyword\">for<\/span> ($i = <span class=\"hljs-number\">0<\/span>; $i &lt; $file_count; $i++) {\n    <span class=\"hljs-comment\">\/\/ get the uploaded file info<\/span>\n    $status = $files&#91;<span class=\"hljs-string\">'error'<\/span>]&#91;$i];\n    $filename = $files&#91;<span class=\"hljs-string\">'name'<\/span>]&#91;$i];\n    $tmp = $files&#91;<span class=\"hljs-string\">'tmp_name'<\/span>]&#91;$i];\n\n    <span class=\"hljs-comment\">\/\/ an error occurs<\/span>\n    <span class=\"hljs-keyword\">if<\/span> ($status !== UPLOAD_ERR_OK) {\n        $errors&#91;$filename] = MESSAGES&#91;$status];\n        <span class=\"hljs-keyword\">continue<\/span>;\n    }\n    <span class=\"hljs-comment\">\/\/ validate the file size<\/span>\n    $filesize = filesize($tmp);\n\n    <span class=\"hljs-keyword\">if<\/span> ($filesize &gt; MAX_SIZE) {\n        <span class=\"hljs-comment\">\/\/ construct an error message<\/span>\n        $message = sprintf(<span class=\"hljs-string\">\"The file %s is %s which is greater than the allowed size %s\"<\/span>,\n            $filename,\n            format_filesize($filesize),\n            format_filesize(MAX_SIZE));\n\n        $errors&#91;$filesize] = $message;\n        <span class=\"hljs-keyword\">continue<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/ validate the file type<\/span>\n    <span class=\"hljs-keyword\">if<\/span> (!in_array(get_mime_type($tmp), array_keys(ALLOWED_FILES))) {\n        $errors&#91;$filename] = <span class=\"hljs-string\">\"The file $filename is allowed to upload\"<\/span>;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If an error occurred, redirect back to the <code>index.php<\/code> and show the error message:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">if<\/span> ($errors) {\n    redirect_with_message(format_messages(<span class=\"hljs-string\">'The following errors occurred:'<\/span>,$errors), FLASH_ERROR);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Note that we use the <code>format_messages()<\/code> function to convert the <code>$errors<\/code> array to a single formatted error message.<\/p>\n\n\n\n<p>6) If no error occurs, move each file to the upload directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ move the files<\/span>\n<span class=\"hljs-keyword\">for<\/span>($i = <span class=\"hljs-number\">0<\/span>; $i &lt; $file_count; $i++) {\n    $filename = $files&#91;<span class=\"hljs-string\">'name'<\/span>]&#91;$i];\n    $tmp = $files&#91;<span class=\"hljs-string\">'tmp_name'<\/span>]&#91;$i];\n    $mime_type = get_mime_type($tmp);\n\n    <span class=\"hljs-comment\">\/\/ set the filename as the basename + extension<\/span>\n    $uploaded_file = pathinfo($filename, PATHINFO_FILENAME) . <span class=\"hljs-string\">'.'<\/span> . ALLOWED_FILES&#91;$mime_type];\n    <span class=\"hljs-comment\">\/\/ new filepath<\/span>\n    $filepath = UPLOAD_DIR . <span class=\"hljs-string\">'\/'<\/span> . $uploaded_file;\n\n    <span class=\"hljs-comment\">\/\/ move the file to the upload dir<\/span>\n    $success = move_uploaded_file($tmp, $filepath);\n    <span class=\"hljs-keyword\">if<\/span>(!$success) {\n        $errors&#91;$filename] = <span class=\"hljs-string\">\"The file $filename was failed to move.\"<\/span>;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>8) Show the error message if the move has an error. Otherwise, show a success message:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$errors ?\n    redirect_with_message(format_messages(<span class=\"hljs-string\">'The following errors occurred:'<\/span>,$errors), FLASH_ERROR) :\n    redirect_with_message(<span class=\"hljs-string\">'All the files were uploaded successfully.'<\/span>, FLASH_SUCCESS);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><a href=\"https:\/\/phptutorial.net\/wp-content\/uploads\/2025\/04\/upload-multiple-files.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Download PHP upload multiple files<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set <code>enctype<\/code> attribute of the form to <code>\"multipart\/form-data\"<\/code> to enable file uploading in the form.<\/li>\n\n\n\n<li>Set the <code>multiple<\/code> attribute and add square brackets (<code>[]<\/code>) to the file input element to upload multiple files.<\/li>\n\n\n\n<li>Always validate the information in the <code>$_FILES<\/code> before processing them.<\/li>\n\n\n\n<li>Use the <code>move_uploaded_file()<\/code> function to move the upload files.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Did you find this tutorial useful?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"2473\"\n\t\t\t\tdata-post-url=\"https:\/\/www.phptutorial.net\/php-tutorial\/php-upload-multiple-files\/\"\n\t\t\t\tdata-post-title=\"PHP Upload Multiple Files\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"2473\"\n\t\t\t\tdata-post-url=\"https:\/\/www.phptutorial.net\/php-tutorial\/php-upload-multiple-files\/\"\n\t\t\t\tdata-post-title=\"PHP Upload Multiple Files\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\n\t\t\t<button class=\"btn btn-primary wth-btn-submit\">Send<\/button>\n\t\t\t<button class=\"btn wth-btn-cancel\">Cancel<\/button>\n\t\t\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn step by step how to upload multiple files to the server securely in PHP.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":15,"menu_order":95,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2473","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/2473","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/comments?post=2473"}],"version-history":[{"count":5,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/2473\/revisions"}],"predecessor-version":[{"id":3310,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/2473\/revisions\/3310"}],"up":[{"embeddable":true,"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/pages\/15"}],"wp:attachment":[{"href":"https:\/\/www.phptutorial.net\/wp-json\/wp\/v2\/media?parent=2473"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}