花魁直播高品质美女在线视频互动社区 - 花魁直播官方版

 歡迎來(lái)到素材無(wú)憂(yōu)網(wǎng),按 + 收藏我們
登錄 注冊(cè) 退出 找回密碼

織夢(mèng)dedecms文件上傳功能分析教程

時(shí)間: 2018-12-06 11:51 閱讀: 作者:素材無(wú)憂(yōu)網(wǎng)

織夢(mèng)dedecms系統(tǒng)里面的上傳功能比較多,例如有友情連接里的logo上傳、模塊管理里面的上傳模塊和模塊打包、發(fā)布新圖集里面的上傳圖片集、發(fā)布新軟件里的上傳本地文件、附件管理里面的上傳新文件、文件式管理器里面的文件上傳、織夢(mèng)會(huì)員中心里面的軟件上傳和縮略圖等等,在織夢(mèng)里面的文件上傳功能到處都有應(yīng)用。

  我們分析三個(gè)有代表性的,一個(gè)是logo上傳,這個(gè)是一般的應(yīng)用,但相對(duì)復(fù)雜一點(diǎn);另一個(gè)是附件管理時(shí)面的上傳新文件,這二個(gè)一個(gè)共同特點(diǎn)是上傳的文件都要保存到數(shù)據(jù)庫(kù)里面,第三個(gè)是文件式管理器里面的文件上傳功能,這個(gè)與我們之前的教程“php文件(單文件和多文件)上傳詳解教程”講的一樣,都是簡(jiǎn)單的上傳文件,沒(méi)有用到數(shù)據(jù)庫(kù)知識(shí),我們就以這三個(gè)為例子,其它的上傳跟這三個(gè)可以說(shuō)大同小異。

  要分析這三個(gè)文件讓傳功能,需要對(duì)織夢(mèng)dedecms文件上傳處理方式,織夢(mèng)與我們?cè)趐hp文件(單文件和多文件)上傳詳解教程里看到的文件上傳是很不一樣的,畢竟,織夢(mèng)系統(tǒng)是一比較成熟的cms系統(tǒng),織夢(mèng)處理文件上傳,不像我們看的教程一樣寫(xiě)一個(gè)文件就可以了,因?yàn)?,織?mèng)系統(tǒng)里面用到的文件上傳很多,不光是織夢(mèng)系統(tǒng),其它系統(tǒng)一定會(huì)用到文件上傳,只要是網(wǎng)站就會(huì)用到文件上傳功能。

  織夢(mèng)是如何處理文件上傳的呢?要了解這個(gè)我們就要分析一下文件上傳的共同點(diǎn),然后,把這公共部分放在一個(gè)文件,然后,其它上傳文件就直接引用這個(gè)文件就可以了,這樣其它每個(gè)上傳功能如logo上傳,圖片集上傳,軟件上傳等各自寫(xiě)適合自己的代碼,然后,再引用公共部分即可。這種思想正是函數(shù)產(chǎn)生的思想,什么是函數(shù)簡(jiǎn)單而言之,就是把公共功能寫(xiě)成一段代碼,其它,需要這個(gè)功能時(shí)直接調(diào)用,而本篇講的文件調(diào)用也正是如此。

  織夢(mèng)dedecms文件上傳公共部分在根目錄(http://www.dedebase.com這就是根目錄,如果你在本地的話根目錄就是http://localhost)/include/uploadsafe.inc.php,對(duì)就在uploadsafe.inc.php文件里面,這個(gè)引用文件功能是:“轉(zhuǎn)換上傳的文件相關(guān)的變量及安全處理、并引用前臺(tái)通用的上傳函數(shù)。”。

  織夢(mèng)是如何把這個(gè)文件配置到要引用它的文件里的呢?首頁(yè),要在/include/common.inc.php里面,寫(xiě)一句如下代碼:

if($_FILES)
{
    require_once(DEDEINC.'/uploadsafe.inc.php');
}

  這段代碼的意思就是,當(dāng)要上傳文件時(shí),就引用文件uploadsafe.inc.php,如果我們打開(kāi)例如logo上傳文件friendlink.add.php你會(huì)發(fā)現(xiàn),沒(méi)有這個(gè)uploadsafe.inc.php文件,是的,織夢(mèng)還配置了一個(gè)在根目錄/dede/里面的config.php文件,這個(gè)是后臺(tái)根目錄/dede/所有php文件共有的,如果你隨便打開(kāi)個(gè)文件,你會(huì)發(fā)現(xiàn)都引用了這個(gè)文件,這個(gè)config.php不僅僅包括了上傳文件,還包括了數(shù)據(jù)庫(kù)連接等很多織夢(mèng)程序所必備的內(nèi)容。為什么這樣包涵來(lái)包涵去?還是為了開(kāi)發(fā)方便,試想如果我們把這些文件里的東西都寫(xiě)進(jìn)friendlink.add.php里面,那文件得多大啊,更重要的是重復(fù)寫(xiě)相同的內(nèi)容,不利于開(kāi)發(fā)。

  我們就拿logo上傳為例子這些文件是這樣相互包括的:friendlink.add.php 引入config.php,config.php引入common.inc.php,common.inc.php引入uploadsafe.inc.php。這樣無(wú)論friendlink.add.php如何改變都不影響后面的文件,有利于開(kāi)發(fā)。

  現(xiàn)在我們就要分析一uploadsafe.inc.php是如何轉(zhuǎn)換上傳的文件變量即$_FILES及安全設(shè)置的。

  打開(kāi)uploadsafe.inc.php文件,找到foreach($_FILES as $_key=>$_value)這句,這句前面是設(shè)置強(qiáng)制哪些文件類(lèi)型可以上傳,并設(shè)置了一個(gè)數(shù)組$keyarr = array('name', 'type', 'tmp_name', 'size');數(shù)組$keyarr值正是$_FILES的鍵,這是為后面進(jìn)行數(shù)組遍歷作準(zhǔn)備。還對(duì)是不是通過(guò)編輯器上傳作了判斷。

  在foreach($_FILES as $_key=>$_value)后面是重點(diǎn)了,通過(guò)foreach($_FILES as $_key=>$_value)我們可以得到$_key,這個(gè)$_key正是我們表單里面的類(lèi)型為file的name屬性值,這一點(diǎn)非常重要。這句foreach($_FILES as $_key=>$_value)代碼就是為了得到這個(gè)$_key。為了進(jìn)一步說(shuō)明這個(gè)$_key我們把$_FILES數(shù)組存儲(chǔ)的內(nèi)容分析一下,這里以單個(gè)文件上傳為例子,多個(gè)文件一樣。$_FILES存儲(chǔ)的內(nèi)容如下。

  Array
(
    [upmyfile] => Array
        (
            [name] => 1440x900wolf.jpg
            [type] => image/jpeg
            [tmp_name] => D:\APMServ5.2.6\tmp\uploadtemp\php6B1.tmp
            [error] => 0
            [size] => 160666
        )

)

  這句代碼foreach($_FILES as $_key=>$_value),正是為了獲得這個(gè)$_key就是$_FILES里面的upmyfile。接下來(lái)我們就要得到name,type,tmp_name,error,size了,我們完全可以再遍歷一下$_value,因?yàn)?_value又是一個(gè)數(shù)組,包括這些內(nèi)容,但是大家想一下,這只是單文件上傳,如果是一個(gè)多文件上傳,是不是比較重雜?是的,織夢(mèng)想到了一好辦法就是先定義一個(gè)$Keyarr數(shù)組,直接從這個(gè)數(shù)組里面獲取name,type,tmp_name,error,size,既簡(jiǎn)單,又方快速。

  代碼foreach($keyarr as $k)這句正是為了獲取name,type,tmp_name,error,size內(nèi)容。

  接下來(lái)這句代碼$$_key = $_FILES[$_key]['tmp_name'];是這個(gè)uploadsafe.inc.php里面的重中之重,這個(gè)代碼的等價(jià)于$upmyfile = D:\APMServ5.2.6\tmp\uploadtemp\php6B1.tmp;以后,我們?cè)谝胾ploadsafe.inc.php這個(gè)文件的文件里看到類(lèi)似$upmyfile就等于是$_FILES[$_key]['tmp_name']即上傳文件臨時(shí)文件名,同理

  ${$_key.'_name'} = $_FILES[$_key]['name'] 等價(jià)于 $upmyfile_name = $_FILES[$_key]['name'] = 1440x900wolf.jpg。

  ${$_key.'_type'} = $_FILES[$_key]['type'] 等價(jià)于 $upmyfile_type = $_FILES[$_key]['type'] = image/jpeg。

  ${$_key.'_size'} = $_FILES[$_key]['size'] 等價(jià)于 $upmyfile_size = $_FILES[$_key]['size'] = 160666。

  之所以通過(guò)以上方式處理,就是為了在引用uploadsafe.inc.php文件的文件里面,不出現(xiàn)類(lèi)似$_FILES[$_key]['size']這樣長(zhǎng)的代碼。

  后面的代碼就是對(duì)文件上傳的文件名是不是空,是不是我們?cè)试S的文件后綴,文件名是不是少個(gè)點(diǎn)進(jìn)行判斷;對(duì)文件大小是不是0,如果是我們通過(guò)系統(tǒng)函數(shù)filesize()獲取,如果更加詳細(xì)的判斷還要判斷一下,用戶(hù)上傳的內(nèi)容是不是超出了我們?cè)O(shè)置的大小,是不是超出了服務(wù)器設(shè)置的大小,但織夢(mèng)沒(méi)有判斷在上一個(gè)教程“php文件(單文件和多文件)上傳詳解教程”我們已經(jīng)作了詳細(xì)判斷。

  最后,對(duì)上傳的文件類(lèi)型進(jìn)行判斷,強(qiáng)制使用我們?cè)O(shè)置的文件類(lèi)型。

  總結(jié):uploadsafe.inc.php用到的系統(tǒng)函數(shù)有是否存在函數(shù)etmpty(),通過(guò)正則來(lái)判斷是否匹配preg_match(),檢查數(shù)組中是否存在某個(gè)值in_array(),將字符串轉(zhuǎn)化為小寫(xiě)strtolower(),去除字符串首尾處的空白字符(或者其他字符)trim(),preg_replace — 執(zhí)行一個(gè)正則表達(dá)式的搜索和替換等函數(shù),現(xiàn)在我們對(duì)uploadsafe.inc.php這個(gè)文件已經(jīng)分析完了。

  一、logo文件上傳如下圖所示。
織夢(mèng)dedecms文件上傳功能分析教程

  現(xiàn)在我們分析以上傳logo文件,logo上傳處理文件是friendlink.add.php,對(duì)應(yīng)的模板文件是friendlink.add.htm模板文件我們就不用多說(shuō)了,都是一些html代碼,我們只要找到模板中這二句(簡(jiǎn)化后):

  網(wǎng)站Logo: <input name="logo" type="text" id="logo"/>
   
  上傳Logo: <input name="logoimg" type="file" id="logoimg" />

  我們打開(kāi)friendlink.add.php文件,程序首先用if(is_uploaded_file($logoimg))判斷一下上傳的文件是不是通過(guò)http post上傳的?如果是說(shuō)明是通過(guò)本地上傳的logo,也就是上面的<input name="logoimg" type="file" id="logoimg" />這個(gè)選擇框上傳的,如果不是則是通過(guò)<input name="logo" type="text" id="logo"/>,直接在這個(gè)文件框?qū)懮系膌ogo地址。

  若if(is_uploaded_file($logoimg))成立則程序向下執(zhí)行,注意這句代碼里面的$logoimg指什么?正常的文件框的話,當(dāng)然是通過(guò)$_POLST獲得的,例如上面二行中的網(wǎng)站Logo:就是通過(guò)$_POST獲取值,而上傳logo即$logoimg則不是通過(guò)$_POST獲得,而是通過(guò)$_FILES獲得的,也就是我們?cè)趗ploadsafe.inc.php里面分析的$upmyfile = D:\APMServ5.2.6\tmp\uploadtemp\php6B1.tmp,只不過(guò)現(xiàn)在的$upmyfile變成了$logoimg即,$logoimg = D:\APMServ5.2.6\tmp\uploadtemp\php6B1.tmp。

  如果你看明白了這點(diǎn),那么,下面的$logoimg_name、$logoimg_type、$logoimg_size分別對(duì)應(yīng)上傳文件的文件名、上傳文件的類(lèi)型、上傳文件的大小了。那下面的代碼就比較容易了,這是難點(diǎn)也是重點(diǎn)。

  代碼$names = split("\.", $logoimg_name);意思是把上傳的文件名通過(guò)正則匹配,模式是通過(guò)點(diǎn)分成二部分,存放在數(shù)組$name中。

  我給織夢(mèng)挑一個(gè)不算錯(cuò)誤:函數(shù)preg_split()比split()快,而explode()在這三個(gè)中運(yùn)行速度最快,前二個(gè)需要正則表達(dá)式,最后這個(gè)explode()則使用字符串分割。他們?nèi)齻€(gè)都返回?cái)?shù)組,所以,這里應(yīng)當(dāng)換上explode()最好了,我們做個(gè)測(cè)試一下,看看返回結(jié)果。

   $name = "1440x900wolf.jpg";
 $a = split("\.", $name);
 $b = split("\.", $name);
 $c = explode(".",$name);

 print_r($a);

 echo "<br />";

 print_r($b);

 echo "<br />";

 print_r($c);

  這段代碼返回的結(jié)果是:

Array ( [0] => 1440x900wolf [1] => jpg )
Array ( [0] => 1440x900wolf [1] => jpg )
Array ( [0] => 1440x900wolf [1] => jpg )

  這充分說(shuō)明了返回的結(jié)果是一樣的,所以,建議大家能用explode()就用這個(gè)。

  回到friendlink.add.php文件里,$shortname = ".".$names[count($names)-1];這句里面的$names[count($names)-1]獲取文件類(lèi)型名,例如上面的例子jpg。整句就得到了.jpg。

  下面這個(gè)判斷語(yǔ)句用來(lái)判斷,我們上傳的文件名是不是我們?cè)试S的,是不是jpg,gif,png,若不是則直接改后綴名為.gif。
    if(!preg_match("#(jpg|gif|png)$#", $shortname))
        {
            $shortname = '.gif';
        }

  下面這句,是對(duì)文件名進(jìn)行重新命名,這樣是為了防止,不同的用戶(hù)上傳相同的名子后,前面的會(huì)被后面的覆蓋掉。

  $filename = MyDate("ymdHis", time()).mt_rand(1000,9999).$shortname;

  下面這句是設(shè)置文件上傳路徑,其中$cfg_medias_dir附件上傳路徑,在common.inc.php已經(jīng)定義。

  $imgurl = $cfg_medias_dir."/flink";

  下面這句判斷是不是目錄,不是則建立,其中$cfg_basedir是根目錄,$cfg_dir_purview是權(quán)限,在common.inc.php已經(jīng)定義。

          if(!is_dir($cfg_basedir.$imgurl))
        {
            MkdirAll($cfg_basedir.$imgurl, $cfg_dir_purview);
            CloseFtp();
        }

  下面這句是要把臨時(shí)文件轉(zhuǎn)移到對(duì)應(yīng)路徑和文件名。

  $imgurl = $imgurl."/".$filename;

  移動(dòng)文件:下面這個(gè)函數(shù)是重點(diǎn),我們上面所做的工作完全就是為這個(gè)文件轉(zhuǎn)移函數(shù)服務(wù)的。

   move_uploaded_file($logoimg,$cfg_basedir.$imgurl)
 
  刪除臨時(shí)文件@unlink($logoimg);@這個(gè)抑制符意思是不顯示錯(cuò)誤。

      //強(qiáng)制檢測(cè)用戶(hù)友情鏈接分類(lèi)是否數(shù)據(jù)結(jié)構(gòu)不符
    if(empty($typeid) || preg_match("#[^0-9]#", $typeid))
    {
        $typeid = 0;
        $dsql->ExecuteNoneQuery("ALTER TABLE `dede_flinktype` CHANGE `ID` `id` MEDIUMINT( 8 ) UNSIGNED DEFAULT NULL AUTO_INCREMENT; ");
    }
 
  這句看似不重要,實(shí)際上這句非常重要,如果這個(gè)$typeid錯(cuò)誤,直接導(dǎo)致,logo出問(wèn)題。

  現(xiàn)在就要把友情鏈接添加到數(shù)據(jù)庫(kù)了,請(qǐng)注意我們上傳的logo是把路徑保存到數(shù)據(jù)庫(kù)里面的,而不是把圖片保存到數(shù)據(jù)庫(kù)里面,有沒(méi)有把圖片保存到數(shù)據(jù)庫(kù)里面的?有,以前聽(tīng)老師講課時(shí),講到過(guò),但是極少,一般都是保存圖片路徑的,這樣程序只需要查詢(xún)一下數(shù)據(jù)庫(kù)就知道圖片在哪里了,目前,本人從沒(méi)有見(jiàn)過(guò)圖片保存到數(shù)據(jù)庫(kù)里的。

  目前為止,我們已經(jīng)把logo上傳分析完了。


  二、附件管理——>上傳文件如下圖所示。

織夢(mèng)dedecms文件上傳功能分析教程
  與logo文件上傳功能相比,這個(gè)文件上傳功能需要標(biāo)題,附加參數(shù),還有一個(gè)最大的不同就是,這個(gè)功能可以批量上傳文件,而且不僅僅是圖片,還有flash,音頻/視頻等。多文件上傳,與單文件上傳沒(méi)有多大區(qū)別,只不過(guò)在單文件上

傳的基礎(chǔ)上曾加個(gè)循環(huán)而已。

  重點(diǎn)看這三句代碼

  $filesize = ${"upfile".$i."_size"};
  $upfile_type = ${"upfile".$i."_type"};
  $upfile_name = ${"upfile".$i."_name"};

  這不正是我們?cè)趗poadsafe.inc.php里面重點(diǎn)分析的嗎,在上傳logo功能里我們也作了分析,這里不再作過(guò)多分析。從代碼for($i=0; $i<=40; $i++)開(kāi)里,當(dāng)條件if(isset(${"upfile".$i}) && is_uploaded_file(${"upfile".$i}))成立,即已經(jīng)上傳了文件并且是通過(guò)http post上傳的,那么,程序就判斷上傳文件類(lèi)型在不在我們前面定義的二個(gè)數(shù)組$sparr_image,$sparr_flash里面,如果在則設(shè)置存儲(chǔ)路徑$savePath,若不存在就建立路徑,若是非flash類(lèi)型則打上水印,接下來(lái)沒(méi)有問(wèn)題,就把數(shù)據(jù)插入到數(shù)據(jù)庫(kù)表dede_uploads,在這個(gè)處理程序中用到了取得圖像大小的函數(shù)getImagesize(),這個(gè)函數(shù),不僅可以獲得圖像的大小,還有高、寬、字節(jié)大小、mime類(lèi)型,為什么要用這個(gè)函數(shù)?
因?yàn)椋覀兒竺娴谋4鏀?shù)據(jù)到數(shù)據(jù)庫(kù)表時(shí),要保存高和寬。

  三、文件式管理器 ——>上傳文件分析如下圖所示。

織夢(mèng)dedecms文件上傳功能分析教程

  文件file_manage_control.php就是對(duì)上傳的文件進(jìn)行處理的程序,這個(gè)更簡(jiǎn)單,既不用把上傳的文件路徑插入到數(shù)據(jù)庫(kù),也不用作過(guò)多的判斷,代碼非常簡(jiǎn)單。它與logo相比多了多個(gè)文件上傳,與附件管理文上傳,少了不需要保存路徑,連上傳的文件名都不用改,直接用if(!file_exists($cfg_basedir.$activepath."/".$upfile_name))來(lái)判斷是不是上傳的文件名與已經(jīng)有的文件名重名,結(jié)束。

  總結(jié):我們總結(jié)一下,如果讓我們自己開(kāi)發(fā)一個(gè)上傳文件功能,如何開(kāi)發(fā)?

  開(kāi)發(fā)上傳文件程序步驟:

   1.設(shè)置限制文件類(lèi)型,一般用數(shù)組來(lái)設(shè)定。
 
   2.判斷文件大小,判斷錯(cuò)誤友好提示信息。

   3.處理$_FILES文件里面的內(nèi)容,像織夢(mèng)那樣專(zhuān)門(mén)做個(gè)程序文件upoadsafe.inc.php。

   4.用函數(shù)is_uploaded_file()判斷上傳的臨時(shí)文件是不是存在,存放則移動(dòng)文件,用到的函數(shù)是move_uploaded_file()。

   5.若要保存到數(shù)據(jù)庫(kù),則插入數(shù)據(jù)庫(kù)表。

   6.多個(gè)文件處理,這個(gè)要用到j(luò)s,或jquery。使上傳效果更酷。

版權(quán)聲明: 本站資源均來(lái)自互聯(lián)網(wǎng)或會(huì)員發(fā)布,如果侵犯了您的權(quán)益請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)刪除!謝謝!

轉(zhuǎn)載請(qǐng)注明: 織夢(mèng)dedecms文件上傳功能分析教程

標(biāo)簽:  
模板推薦