本人菜鳥(niǎo)一枚,以下內(nèi)容如有不當(dāng)之處,勞煩指正。
本人由于想寫(xiě)個(gè)discuz插件,這個(gè)插件功能上涉及到上傳文件這一功能,故以菜鳥(niǎo)的眼光來(lái)學(xué)習(xí)了下php上傳文件。
首先,w3cshool查了下案例,覺(jué)得他說(shuō)的非常詳細(xì),連我這個(gè)菜鳥(niǎo)都略懂了一二。
貼上地址:http://www.w3school.com.cn/php/php_file_upload.asp
照著這個(gè)講解,寫(xiě)了下他這個(gè)demo,貼上代碼:
html:
<form action="demo.php" method="post" enctype="multipart/form-data"> <label for="file">Filename:</label> <input type="file" name="file" id="file"> <br/> <input type="submit" name="submit" value="Submit"/></form>
這個(gè)表單頁(yè),作為php菜鳥(niǎo)的我說(shuō)下我在這個(gè)里面學(xué)到的新東西:
1.form的屬性enctype,百度翻譯了下這個(gè)單詞,才知道,這個(gè)是encode type 的縮寫(xiě),就是指定往服務(wù)器傳遞信息的編碼格式;
2.input的type屬性file,這個(gè)專用文件上傳的;
php:
//echo phpinfo();//var_dump($_FILES);die;if((($_FILES["file"]["type"]=="image/gif")||($_FILES["file"]["type"]=="image/jpeg")||($_FILES["file"]["type"]=="image/pjpeg")) && ($_FILES["file"]["size"]<100*1024*1024)){ if($_FILES["file"]["error"]>0){ echo "Error: ".$_FILES["file"]["error"]."<br/>"; }else{ echo "Upload: ".$_FILES["file"]["name"]."<br/>"; echo "Type: ".$_FILES["file"]["type"]."<br />"; echo "Size: ".($_FILES["file"]["size"]/1024)."Kb<br />"; echo "Stored in ".$_FILES["file"]["tmp_name"]; } if(file_exists("upload/".$_FILES["name"]["name"])){ echo $_FILES["file"]["name"]."already exists."; }else{ move_uploaded_file($_FILES["file"]["tmp_name"],"upload/".$_FILES["file"]["name"]); echo "Stored in: "."upload/".$_FILES["file"]["name"]; }}else{ echo "Invalid file";}
關(guān)于調(diào)試這個(gè)demo的時(shí)候,我遇到一個(gè)問(wèn)題:就是運(yùn)行這個(gè)demo的時(shí)候php報(bào)出warning,表示上傳不成功。
這個(gè)時(shí)候我就想打印出$_FILES這個(gè)變量來(lái)看看,結(jié)果打印出來(lái)發(fā)現(xiàn)error=1;才知道上傳的文件超過(guò)了php.ini的上傳文件大小,導(dǎo)致上傳失敗。
這里說(shuō)下俺新了解的知識(shí)點(diǎn):
PHP編程語(yǔ)言中的常見(jiàn)的$_FILES 系統(tǒng)函數(shù)用法有: $_FILES['myFile']['name'] 顯示客戶端文件的原名稱。 $_FILES['myFile']['type'] 文件的 MIME 類(lèi)型,例如"image/gif"。 $_FILES['myFile']['size'] 已上傳文件的大小,單位為字節(jié)。 $_FILES['myFile']['tmp_name'] 儲(chǔ)存的臨時(shí)文件名,一般是系統(tǒng)默認(rèn)。 $_FILES['myFile']['error'] 該文件上傳相關(guān)的錯(cuò)誤代碼。以下為不同代碼代表的意思: 0; 文件上傳成功。 1; 超過(guò)了文件大小php.ini中即系統(tǒng)設(shè)定的大小。 2; 超過(guò)了文件大小 MAX_FILE_SIZE 選項(xiàng)指定的值。 3; 文件只有部分被上傳。 4; 沒(méi)有文件被上傳。 5; 上傳文件大小為0。到這里,應(yīng)該就知道了我剛剛運(yùn)行demo的錯(cuò)誤是啥導(dǎo)致的,那既然發(fā)現(xiàn)是php.ini里面限制超出了,那接下來(lái)我就修改了下php.ini的配置。總結(jié)下我修改這個(gè)php.ini上傳限制的感受:首先,要修改php上傳文件大小限制,那要改php.ini里面的兩個(gè)參數(shù),一個(gè)是upload_max_filesize,還有個(gè)就是post_max_size,修改下這兩個(gè)參數(shù)的大小就可以了!其次,就是找準(zhǔn)php.ini的位置,我由于本地電腦搭建的是集成環(huán)境,所以php.ini在apache文件夾下面,如果是自己搭建的環(huán)境,那就在php文件夾下面,如果找不到,echo下phpinfo(),可以看到php.ini文件的位置。那到此為止,跟我差不多的新手們就能運(yùn)行w3cshool上面的demo了,完成上傳實(shí)例了。關(guān)于上傳文件,我看了下discuz其他插件作者開(kāi)發(fā)的插件,有點(diǎn)小收獲,貼上來(lái)跟大家分享下:
$fileTypes = array('mp3','wav'); //定義允許上傳的文件類(lèi)型 $result = null; $uploadDir = './mail'; //上傳路徑 if(!submitcheck($_POST['formhash4'])){ //檢測(cè)是否是上傳文件 if($_POST['upname']==''){ //判斷上傳文件的命名是否為空 $result=lang('plugin/saya_mails', 'noname'); }else{ $myfile = $_FILES['myfile']; //獲取上傳的文件信息 $myfileType = substr($myfile['name'], strrpos($myfile['name'], ".") + 1); //兩種獲取上傳文件的后綴名 // $myfileTyle = substr(strrchr($myfile['name'],'.'),1); if ($myfile['size'] > 1024*1024*1024) { //判斷上傳文件大小是否超過(guò)限制 $result = lang('plugin/saya_mails', 'big'); } else if (!in_array($myfileType, $fileTypes)) { //判斷是否是允許上傳的類(lèi)型 $result = lang('plugin/saya_mails', 'type'); } elseif (is_uploaded_file($myfile['tmp_name'])) { //判斷是否是通過(guò)HTTP post上傳的文件 $toFile = './source/plugin/saya_mails/mail/' . $myfile['name']; //目標(biāo)存儲(chǔ)地址 if (@move_uploaded_file($myfile['tmp_name'], $toFile)) { //將文件拷貝到目標(biāo)存儲(chǔ)地址 //這個(gè)地方加@是屏蔽錯(cuò)誤信息和警告// if (copy($myfile['tmp_name'],$toFile)) { $end=0; $result = lang('plugin/saya_mails', 'success'); } else { $result = lang('plugin/saya_mails', 'unknow'); } } else { $result = lang('plugin/saya_mails', 'big'); } } }
對(duì)比了下,w3cshool上面的上傳實(shí)例,覺(jué)得這個(gè)作者寫(xiě)的更完善一點(diǎn)
大體流程就是:
1.判斷是否是上傳文件,他用的這個(gè)方法是discuz自帶的,我們一般用,就是form傳遞過(guò)來(lái)的隱藏參數(shù)的值存不存在來(lái)進(jìn)行判斷;
2.判斷上傳文件的命名是否為空,這一步大家可以跳過(guò),這個(gè)是他自己寫(xiě)了個(gè)input而已;
3.判斷上傳大小是否超出;
4.獲取文件后綴名,判斷是否是允許的上傳文件類(lèi)型;
5.判斷文件是否是通過(guò)http post上傳的;
6.移動(dòng)保存文件;
關(guān)于以上流程,個(gè)人總結(jié)了下自己獲得的新的知識(shí)點(diǎn):
1.關(guān)于獲取文件的后綴名,原插件作者是通過(guò)函數(shù)strrpos()來(lái)返回"."所在的位置,然后通過(guò)截取函數(shù)substr()來(lái)獲得上傳文件的后綴。
這里,strrpos()函數(shù),我自己的理解應(yīng)該是string return position的縮寫(xiě),當(dāng)然我還沒(méi)查證過(guò)!這個(gè)函數(shù)是返回字符串里要查找的字符串最后出現(xiàn)的位置,并返回這個(gè)位置。也就是從后往前查,第一次出現(xiàn)的位置。參考地址:http://www.w3school.com.cn/php/func_string_strrpos.asp
這里原作者用這個(gè)方法來(lái)判斷,肯定是可以的,我百度了下,發(fā)現(xiàn)也可以用strrchr()和substr()函數(shù)合作來(lái)實(shí)現(xiàn)這個(gè)方法,我把我想的方法注釋在了上面源代碼里面了,其實(shí)差不多,strrchr()函數(shù)就是返回最后一次出現(xiàn)的要查找的字符串到結(jié)尾的字符串,參考地址:http://www.w3school.com.cn/php/func_string_strrchr.asp
通過(guò)以上兩種方法來(lái)判斷上傳文件的類(lèi)型是否達(dá)標(biāo),而不是通過(guò)$_FILES["file"]["type"]來(lái)判斷,這樣更好判斷點(diǎn),對(duì)于新手,因?yàn)橹灰愦蛴∠?_FILES這個(gè)參數(shù)你就知道了,type屬性沒(méi)這么判斷來(lái)的清晰明了。
2.通過(guò)is_uploaded_file()來(lái)判斷文件是否是通過(guò)http上傳的
3.move_uploaded_file()前面的@是用來(lái)屏蔽錯(cuò)誤信息和警告的
到此為止是小弟的一些個(gè)人理解,不足忘指正!
PHP編程鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。
|
新聞熱點(diǎn)
疑難解答
圖片精選