此篇文章主要講解如何封裝一個php的用於文件上傳下載的函數,可以用於本demo中的頭像上傳功能,順便講解一下多文件上傳的方式。如果對於文件上傳特別熟悉可以跳過此節。
還是使用之前那個介面。
addUser.php:
<code><span><!doctype html></span><span><<span>html</span>></span><span><<span>head</span>></span><span><<span>meta</span><span>charset</span>=<span>"utf-8"</span>></span><span><<span>title</span>></span><span></<span>title</span>></span><span></<span>head</span>></span><span><<span>body</span>></span><span><<span>H3</span>></span>添加管理员<span></<span>H3</span>></span><span><<span>FORM</span><span>action</span>=<span>"doAdminAction.php?act=addUser"</span><span>method</span>=<span>"post"</span>></span><span><<span>TABLE</span><span>width</span>=<span>"60%"</span><span>border</span>=<span>"1"</span><span>cellpadding</span>=<span>"5"</span><span>cellspacing</span>=<span>"0"</span><span>bgcolor</span>=<span>"#cccccc"</span>></span><span><<span>tr</span>></span><span><<span>TD</span><span>align</span>=<span>"right"</span>></span>用户名称<span></<span>TD</span>></span><span><<span>TD</span>></span><span><<span>input</span><span>type</span>=<span>"text"</span><span>name</span>=<span>"username"</span><span>placeholder</span>=<span>"请输入用户名称"</span>/></span><span></<span>TD</span>></span><span></<span>tr</span>></span><span><<span>tr</span>></span><span><<span>TD</span><span>align</span>=<span>"right"</span>></span>用户密码<span></<span>TD</span>></span><span><<span>TD</span>></span><span><<span>input</span><span>type</span>=<span>"text"</span><span>name</span>=<span>"password"</span><span>placeholder</span>=<span>"请输入用户名称"</span>/></span><span></<span>TD</span>></span><span></<span>tr</span>></span><span><<span>tr</span>></span><span><<span>TD</span><span>align</span>=<span>"right"</span>></span>用户邮箱<span></<span>TD</span>></span><span><<span>TD</span>></span><span><<span>input</span><span>type</span>=<span>"text"</span><span>name</span>=<span>"email"</span><span>placeholder</span>=<span>"请输入用户名称"</span>/></span><span></<span>TD</span>></span><span></<span>tr</span>></span><span><<span>tr</span>></span><span><<span>td</span><span>align</span>=<span>"right"</span>></span>性别<span></<span>td</span>></span><span><<span>td</span>></span><span><<span>input</span><span>type</span>=<span>"radio"</span><span>name</span>=<span>"sex"</span><span>value</span>=<span>"1"</span><span>checked</span>=<span>"checked"</span>/></span>男 <span><<span>input</span><span>type</span>=<span>"radio"</span><span>name</span>=<span>"sex"</span><span>value</span>=<span>"2"</span> /></span>女 <span><<span>input</span><span>type</span>=<span>"radio"</span><span>name</span>=<span>"sex"</span><span>value</span>=<span>"3"</span> /></span>保密 <span></<span>td</span>></span><span></<span>tr</span>></span><span><<span>tr</span>></span><span><<span>td</span><span>align</span>=<span>"right"</span>></span>头像<span></<span>td</span>></span><span><<span>td</span>></span><span><<span>input</span><span>type</span>=<span>"file"</span><span>name</span>=<span>"face"</span> /></span><span></<span>td</span>></span><span></<span>tr</span>></span><span><<span>tr</span>></span><span><<span>TD</span><span>colspan</span>=<span>"2"</span>></span><span><<span>input</span><span>type</span>=<span>"submit"</span><span>value</span>=<span>"添加用户"</span>/></span><span></<span>TD</span>></span><span></<span>tr</span>></span><span></<span>FORM</span>></span><span></<span>body</span>></span><span></<span>html</span>></span></code>
這裡是檔案目錄:
在表單提交的doAdminAction.php中,只需要增加 加move_uploaded_file($_FILES["face"]["tmp_name"], <br>
"upload/" . $_FILES["face"]["name"]);
這一行程式碼,即可將客戶端上傳的檔案放在伺服器中的對應的地方。但是這樣的程式碼有一些問題
(1)如果在admin不存在upload的資料夾,檔案上傳不上去。
(2)對於上傳的文件的類型沒有進行檢驗,如果出現病毒文件會比較危險。
(3)如果上傳了與upload資料夾中的文件名稱相同的文件,原來的文件就會被替換掉。
(4)對於檔案上傳可能會出現的一些錯誤沒有進行處理,例如檔案大小超過了2M,(php ini 檔案中預設規定的上傳限制大小為2M)
以下是解決方案:
(1)先判斷upload的資料夾是否存在,如果不存在則建立
<code><span>$path</span>=<span>"upload/"</span>; <span>//</span>如果路径不存在就建立的路径上 <span>if</span>(!file_exists(<span>$path</span>)) { mkdir(<span>$path</span>,<span>0777</span>,<span>true</span>); } </code>
(2)使用strtolower(end(explode(“.”, $filename)));取得檔案的拓展名稱
然後判斷拓展名是否在所需的文件類型中。
(3)使用md5(uniqid(microtime(true),true));得到一個唯一的字串與先前得到的檔案拓展名稱連接在一起,作為上傳檔案的檔案名稱。
(4)現在開始寫doAdminAction的程式碼,第四個問題將在程式碼中講解。
<code><span><span><?php</span><span>require_once</span><span>'../include.php'</span>; <span>//print_r($_FILES["face"]);</span><span>$path</span>=<span>"upload/"</span>; <span>//如果路径不存在就建立的路径上</span><span>if</span>(!file_exists(<span>$path</span>)) { mkdir(<span>$path</span>,<span>0777</span>,<span>true</span>); } <span>//允许的类型</span><span>$allowExt</span>=<span>array</span>(<span>"gif"</span>,<span>"jpeg"</span>,<span>"png"</span>,<span>"jpg"</span>,<span>"wbmp"</span>); <span>$filename</span>=<span>$_FILES</span>[<span>"face"</span>][<span>"name"</span>]; <span>$ext</span>=getExt(<span>$filename</span>); <span>if</span>(!in_array(<span>$ext</span>,<span>$allowExt</span>)){ <span>exit</span>(<span>"非法文件类型"</span>); } <span>//得到了唯一的文件名的文件</span><span>$filename</span>=getUniName().<span>"."</span>.<span>$ext</span>; <span>if</span>(move_uploaded_file(<span>$_FILES</span>[<span>"face"</span>][<span>"tmp_name"</span>], <span>$path</span>.<span>$filename</span>)) { <span>echo</span><span>"文件上传成功"</span>; } <span>else</span> { <span>switch</span>(<span>$_FILES</span>[<span>"face"</span>][<span>'error'</span>]){ <span>case</span><span>1</span>: <span>$mes</span>=<span>"超过了配置文件上传文件的大小"</span>;<span>//UPLOAD_ERR_INI_SIZE</span><span>break</span>; <span>case</span><span>2</span>: <span>$mes</span>=<span>"超过了表单设置上传文件的大小"</span>; <span>//UPLOAD_ERR_FORM_SIZE</span><span>break</span>; <span>case</span><span>3</span>: <span>$mes</span>=<span>"文件部分被上传"</span>;<span>//UPLOAD_ERR_PARTIAL</span><span>break</span>; <span>case</span><span>4</span>: <span>$mes</span>=<span>"没有文件被上传"</span>;<span>//UPLOAD_ERR_NO_FILE</span><span>break</span>; <span>case</span><span>6</span>: <span>$mes</span>=<span>"没有找到临时目录"</span>;<span>//UPLOAD_ERR_NO_TMP_DIR</span><span>break</span>; <span>case</span><span>7</span>: <span>$mes</span>=<span>"文件不可写"</span>;<span>//UPLOAD_ERR_CANT_WRITE;</span><span>break</span>; <span>case</span><span>8</span>: <span>$mes</span>=<span>"由于PHP的扩展程序中断了文件上传"</span>;<span>//UPLOAD_ERR_EXTENSION</span><span>break</span>; } <span>echo</span><span>$mes</span>; } <span>?></span></span></code>
如果發生了出現的錯誤,則這些錯誤會被印出來。至此單一檔案上傳的內容講解完畢,現在將上述的程式碼封裝為函數。
<code><span><?php</span><span><span>function</span><span>uploadFile</span><span>(<span>$path</span>=<span>"upload/"</span>,<span>$allowExt</span>=array<span>(<span>"gif"</span>,<span>"jpeg"</span>,<span>"png"</span>,<span>"jpg"</span>,<span>"wbmp"</span>)</span>,<span>$imgFlag</span>=true)</span> {</span><span>//如果路径不存在就建立的路径上</span><span>if</span>(!file_exists(<span>$path</span>)) { mkdir(<span>$path</span>,<span>0777</span>,<span>true</span>); } <span>//允许的类型</span><span>$filename</span>=<span>$_FILES</span>[<span>"face"</span>][<span>"name"</span>]; <span>$ext</span>=getExt(<span>$filename</span>); <span>if</span>(!in_array(<span>$ext</span>,<span>$allowExt</span>)){ <span>exit</span>(<span>"非法文件类型"</span>); } <span>if</span>(<span>$imgFlag</span>){ <span>//如何验证图片是否是一个真正的图片类型</span><span>//getimagesize($filename):验证文件是否是图片类型 正确返回数组错误返回false</span><span>$info</span>=getimagesize(<span>$tmp_name</span>); <span>//var_dump($info);exit;</span><span>if</span>(!<span>$info</span>){ <span>exit</span>(<span>"不是真正的图片类型"</span>); } } <span>//得到了唯一的文件名的文件</span><span>$filename</span>=getUniName().<span>"."</span>.<span>$ext</span>; <span>if</span>(move_uploaded_file(<span>$_FILES</span>[<span>"face"</span>][<span>"tmp_name"</span>], <span>$path</span>.<span>$filename</span>)) { <span>echo</span><span>"文件上传成功"</span>; } <span>else</span> { <span>switch</span>(<span>$_FILES</span>[<span>"face"</span>][<span>'error'</span>]){ <span>case</span><span>1</span>: <span>$mes</span>=<span>"超过了配置文件上传文件的大小"</span>;<span>//UPLOAD_ERR_INI_SIZE</span><span>break</span>; <span>case</span><span>2</span>: <span>$mes</span>=<span>"超过了表单设置上传文件的大小"</span>; <span>//UPLOAD_ERR_FORM_SIZE</span><span>break</span>; <span>case</span><span>3</span>: <span>$mes</span>=<span>"文件部分被上传"</span>;<span>//UPLOAD_ERR_PARTIAL</span><span>break</span>; <span>case</span><span>4</span>: <span>$mes</span>=<span>"没有文件被上传"</span>;<span>//UPLOAD_ERR_NO_FILE</span><span>break</span>; <span>case</span><span>6</span>: <span>$mes</span>=<span>"没有找到临时目录"</span>;<span>//UPLOAD_ERR_NO_TMP_DIR</span><span>break</span>; <span>case</span><span>7</span>: <span>$mes</span>=<span>"文件不可写"</span>;<span>//UPLOAD_ERR_CANT_WRITE;</span><span>break</span>; <span>case</span><span>8</span>: <span>$mes</span>=<span>"由于PHP的扩展程序中断了文件上传"</span>;<span>//UPLOAD_ERR_EXTENSION</span><span>break</span>; } <span>echo</span><span>$mes</span>; } }</code>
多檔案上傳分為兩種情況
(1)多個單一檔案上傳
<code><span><!doctype html></span><span><<span>html</span>></span><span><<span>head</span>></span><span><<span>meta</span><span>charset</span>=<span>"utf-8"</span>></span><span><<span>title</span>></span><span></<span>title</span>></span><span></<span>head</span>></span><span><<span>body</span>></span><span><!-- 表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作. --></span><span><<span>FORM</span><span>action</span>=<span>"doAction2.php"</span><span>method</span>=<span>"post"</span><span>enctype</span>=<span>"multipart/form-data"</span>></span><span><<span>INPUT</span><span>type</span>=<span>"hidden"</span><span>name</span>=<span>"MAX_FILE_SIZE"</span><span>value</span>=<span>"1048576"</span>/></span> 请选择上传文件:<span><<span>INPUT</span><span>type</span>=<span>"file"</span><span>name</span>=<span>"myFile1"</span>/></span><span><<span>br</span>/></span> 请选择上传文件:<span><<span>INPUT</span><span>type</span>=<span>"file"</span><span>name</span>=<span>"myFile2"</span>/></span><span><<span>br</span>/></span> 请选择上传文件:<span><<span>INPUT</span><span>type</span>=<span>"file"</span><span>name</span>=<span>"myFile3"</span>/></span><span><<span>br</span>/></span><span><<span>input</span><span>type</span>=<span>"submit"</span><span>value</span>=<span>"上传"</span>/></span><span></<span>FORM</span>></span><span></<span>body</span>></span><span></<span>html</span>></span></code>
這種形式相當於上傳了多個單一檔案,在doAction2.php中print_r($_FILES);得到
<code><span>Array</span> ( [myFile1] => <span>Array</span> ( [name] => touxiang.jpg [type] => image/jpeg [tmp_name] => D:\xampp\tmp\php79E3.tmp [error] => <span>0</span> [size] => <span>28747</span> ) [myFile2] => <span>Array</span> ( [name] => 文章.png [type] => image/png [tmp_name] => D:\xampp\tmp\php7A03.tmp [error] => <span>0</span> [size] => <span>11655</span> ) [myFile3] => <span>Array</span> ( [name] => 增加.png [type] => image/png [tmp_name] => D:\xampp\tmp\php7A04.tmp [error] => <span>0</span> [size] => <span>7439</span> ) )</code>
(2)多重檔案上傳
<code><span><!doctype html></span><span><<span>html</span>></span><span><<span>head</span>></span><span><<span>meta</span><span>charset</span>=<span>"utf-8"</span>></span><span><<span>title</span>></span><span></<span>title</span>></span><span></<span>head</span>></span><span><<span>body</span>></span><span><!-- 表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作. --></span><span><<span>FORM</span><span>action</span>=<span>"doAction2.php"</span><span>method</span>=<span>"post"</span><span>enctype</span>=<span>"multipart/form-data"</span>></span><span><<span>INPUT</span><span>type</span>=<span>"hidden"</span><span>name</span>=<span>"MAX_FILE_SIZE"</span><span>value</span>=<span>"1048576"</span>/></span> 请选择上传文件:<span><<span>INPUT</span><span>type</span>=<span>"file"</span><span>name</span>=<span>"myFile[]"</span>/></span><span><<span>br</span>/></span> 请选择上传文件:<span><<span>INPUT</span><span>type</span>=<span>"file"</span><span>name</span>=<span>"myFile[]"</span>/></span><span><<span>br</span>/></span> 请选择上传文件:<span><<span>INPUT</span><span>type</span>=<span>"file"</span><span>name</span>=<span>"myFile[]"</span>/></span><span><<span>br</span>/></span><span><<span>input</span><span>type</span>=<span>"submit"</span><span>value</span>=<span>"上传"</span>/></span><span></<span>FORM</span>></span><span></<span>body</span>></span><span></<span>html</span>></span></code>
同樣print_r( $_files)一下
<code><span>Array</span> ( [myFile] => <span>Array</span> ( [name] => <span>Array</span> ( [<span>0</span>] => touxiang.jpg [<span>1</span>] => 文章.png [<span>2</span>] => 增加.png ) [type] => <span>Array</span> ( [<span>0</span>] => image/jpeg [<span>1</span>] => image/png [<span>2</span>] => image/png ) [tmp_name] => <span>Array</span> ( [<span>0</span>] => D:\xampp\tmp\php1EC.tmp [<span>1</span>] => D:\xampp\tmp\php1ED.tmp [<span>2</span>] => D:\xampp\tmp\php1EE.tmp ) [error] => <span>Array</span> ( [<span>0</span>] => <span>0</span> [<span>1</span>] => <span>0</span> [<span>2</span>] => <span>0</span> ) [size] => <span>Array</span> ( [<span>0</span>] => <span>28747</span> [<span>1</span>] => <span>11655</span> [<span>2</span>] => <span>7439</span> ) ) ) </code>
發現兩種方式得到的陣列有很多的差異。
對於第一種的情況(相當於一個檔案數組)我們可以
<code><span>foreach</span> (<span>$_FILES</span><span>as</span><span>$var</span>) { <span>//对于每一个文件进行了文件上传操作</span><span>$info</span>=uploadFile(<span>$var</span>); <span>echo</span><span>$info</span>; }</code>
對於第二種情況我們可以將所示的三維數組轉換為第一種情況所示的二維數組即可。
<code>foreach(<span>$_FILES</span>[myFile][name] as <span>$key</span>=><span>$var</span> ) { <span>$files</span>[<span>$key</span>][name]=<span>$_FILES</span>[myFile][name][<span>$key</span>]; <span>$files</span>[<span>$key</span>][type]=<span>$_FILES</span>[myFile][type][<span>$key</span>]; <span>$files</span>[<span>$key</span>][tmp_name]=<span>$_FILES</span>[myFile][tmp_name][<span>$key</span>]; <span>$files</span>[<span>$key</span>][<span>error</span>]=<span>$_FILES</span>[myFile][<span>error</span>][<span>$key</span>]; <span>$files</span>[<span>$key</span>][<span>size</span>]=<span>$_FILES</span>[myFile][<span>size</span>][<span>$key</span>]; } print_r(<span>$files</span>);</code>
結果
<code><span>Array</span> ( [<span>0</span>] => <span>Array</span> ( [name] => touxiang.jpg [type] => image/jpeg [tmp_name] => D:\xampp\tmp\php3227.tmp [error] => <span>0</span> [size] => <span>28747</span> ) [<span>1</span>] => <span>Array</span> ( [name] => 文章.png [type] => image/png [tmp_name] => D:\xampp\tmp\php3228.tmp [error] => <span>0</span> [size] => <span>11655</span> ) [<span>2</span>] => <span>Array</span> ( [name] => 增加.png [type] => image/png [tmp_name] => D:\xampp\tmp\php3229.tmp [error] => <span>0</span> [size] => <span>7439</span> ) )</code>
成功了,現在我們開始封裝一個檔案上傳函數,這個函數呢既可以處理單檔案上傳又可以處理多檔案上傳。然後我們只需要寫數組處理的這部分,然後呼叫upload()函數。
<code><span><?php</span><span>require_once</span><span>"../include.php"</span>; <span>//用于转换数组</span><span><span>function</span><span>buildInfo</span><span>()</span> {</span><span>foreach</span>(<span>$_FILES</span><span>as</span><span>$file</span>) { <span>$i</span>=<span>0</span>; <span>if</span>(is_string(<span>$file</span>[<span>'name'</span>])) { <span>$files</span>[<span>$i</span>]=<span>$file</span>; <span>$i</span>++; } <span>else</span> { <span>foreach</span>(<span>$file</span>[name] <span>as</span><span>$key</span>=><span>$var</span>) { <span>$files</span>[<span>$key</span>][name]=<span>$file</span>[name][<span>$key</span>]; <span>$files</span>[<span>$key</span>][type]=<span>$file</span>[type][<span>$key</span>]; <span>$files</span>[<span>$key</span>][tmp_name]=<span>$file</span>[tmp_name][<span>$key</span>]; <span>$files</span>[<span>$key</span>][error]=<span>$file</span>[error][<span>$key</span>]; <span>$files</span>[<span>$key</span>][size]=<span>$file</span>[size][<span>$key</span>]; } } } <span>return</span><span>$files</span>; } <span>//用于上传</span><span><span>function</span><span>uploadFile</span><span>(<span>$path</span>=<span>"upload/"</span>,<span>$allowExt</span>=array<span>(<span>"gif"</span>,<span>"jpeg"</span>,<span>"png"</span>,<span>"jpg"</span>,<span>"wbmp"</span>)</span>)</span> {</span><span>//如果路径不存在就建立的路径上</span><span>if</span>(!file_exists(<span>$path</span>)) { mkdir(<span>$path</span>,<span>0777</span>,<span>true</span>); } <span>$files</span>=buildInfo(); <span>foreach</span>(<span>$files</span><span>as</span><span>$file</span>) { <span>//允许的类型</span><span>$filename</span>=<span>$file</span>[<span>"name"</span>]; <span>$ext</span>=getExt(<span>$filename</span>); <span>if</span>(!in_array(<span>$ext</span>,<span>$allowExt</span>)){ <span>exit</span>(<span>"非法文件类型"</span>); } <span>//校验是否是一个真正的图片类型</span><span>if</span>(<span>$imgFlag</span>){ <span>if</span>(!getimagesize(<span>$file</span>[<span>'tmp_name'</span>])){ <span>exit</span>(<span>"不是真正的图片类型"</span>); } } <span>//得到了唯一的文件名的文件</span><span>$filename</span>=getUniName().<span>"."</span>.<span>$ext</span>; <span>if</span>(move_uploaded_file(<span>$file</span>[<span>"tmp_name"</span>], <span>$path</span>.<span>$filename</span>)) { <span>echo</span><span>"文件上传成功"</span>; } <span>else</span> { <span>switch</span>(<span>$file</span>[<span>'error'</span>]){ <span>case</span><span>1</span>: <span>$mes</span>=<span>"超过了配置文件上传文件的大小"</span>;<span>//UPLOAD_ERR_INI_SIZE</span><span>break</span>; <span>case</span><span>2</span>: <span>$mes</span>=<span>"超过了表单设置上传文件的大小"</span>; <span>//UPLOAD_ERR_FORM_SIZE</span><span>break</span>; <span>case</span><span>3</span>: <span>$mes</span>=<span>"文件部分被上传"</span>;<span>//UPLOAD_ERR_PARTIAL</span><span>break</span>; <span>case</span><span>4</span>: <span>$mes</span>=<span>"没有文件被上传"</span>;<span>//UPLOAD_ERR_NO_FILE</span><span>break</span>; <span>case</span><span>6</span>: <span>$mes</span>=<span>"没有找到临时目录"</span>;<span>//UPLOAD_ERR_NO_TMP_DIR</span><span>break</span>; <span>case</span><span>7</span>: <span>$mes</span>=<span>"文件不可写"</span>;<span>//UPLOAD_ERR_CANT_WRITE;</span><span>break</span>; <span>case</span><span>8</span>: <span>$mes</span>=<span>"由于PHP的扩展程序中断了文件上传"</span>;<span>//UPLOAD_ERR_EXTENSION</span><span>break</span>; } <span>echo</span><span>$mes</span>; } } }</span></code>
這段程式碼中也增加了對於上傳圖片是否為圖片格式的檢驗,以及對於圖片大小的檢驗,因為有些病毒檔案會偽裝為圖片檔案。
以上就介紹了使用php完成一個用戶註冊以及管理的demo(php實現單文件與多文件的上傳),包括了方面的內容,希望對PHP教程有興趣的朋友有所幫助。