前端学PHP之文件操作
前面的話
在程序運(yùn)行時(shí),程序本身和數(shù)據(jù)一般都存在內(nèi)存中,當(dāng)程序運(yùn)行結(jié)束后,存放在內(nèi)存中的數(shù)據(jù)被釋放。如果需要長期保存程序運(yùn)行所需的原始數(shù)據(jù),或程序運(yùn)行產(chǎn)生的結(jié)果,就需要把數(shù)據(jù)存儲(chǔ)在文件或數(shù)據(jù)庫。一般地,小型數(shù)據(jù)存儲(chǔ)在文件中,海量數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫中。本文主要介紹php中目錄和文件的基本操作
?
文件類型
文件一般指存儲(chǔ)在外部介質(zhì)上具有名字(文件名)的一組相關(guān)數(shù)據(jù)集合。用文件可長期保存數(shù)據(jù),并實(shí)現(xiàn)數(shù)據(jù)共享
PHP是以UNIX的文件系統(tǒng)為模型的。因此在Windows系統(tǒng)中我們只能獲得”file”、”dir”或者“unknown”三種文件類型。而在UNIX系統(tǒng)中,我們可以獲得block、char、dir、fifo、file、link和unknown七種類型
可以使用函數(shù)filetype()獲取文件的具體類型,可能的值有fifo,char,dir,block,link,file 和 unknown
string filetype ( string filename )如果出錯(cuò)則返回 FALSE。如果調(diào)用失敗或者文件類型未知的話 filetype() 還會(huì)產(chǎn)生一個(gè) E_NOTICE 消息
在服務(wù)器中新建一個(gè)目錄test,并在目錄中新建一個(gè)文件a.txt
<?php echo filetype('test/a.txt'); // file echo filetype('test/'); // dir echo filetype('test/b.txt'); // Warning: filetype(): Lstat failed for test/b.txt ?>在這7種文件類型中,window系統(tǒng)常用的是'file'和'dir'這兩種,它們配套的類型檢測(cè)函數(shù)分別是is_dir( )和is_file( )
is_dir( )
判斷給定文件名是否是一個(gè)目錄。如果文件名存在并且是一個(gè)目錄則返回 true,否則返回 false
bool is_dir(_name)is_file( )
判斷給定文件名是否為一個(gè)正常的文件,如果文件存在且為正常的文件則返回 true?
bool is_file(_name) <?php var_dump (is_file('test/a.txt')); //boolean true var_dump (is_dir('test/')); //boolean true ?>?
文件屬性
一般地,在文件或目錄右鍵菜單中,選擇屬性,即可查看文件的屬性
下表中列出了php中關(guān)于文件屬性的常用函數(shù)
<?php var_dump (file_exists('test/a.txt')); //boolean true var_dump (filesize('test/a.txt')); // int 0 var_dump (is_readable('test/a.txt')); //boolean true var_dump (is_writeable('test/a.txt')); //boolean true var_dump (is_executable('test/a.txt')); //boolean false var_dump (date("Y-m-d H:i:s",(filectime('test/a.txt'))));//string '2016-11-22 06:47:54' (length=19) var_dump (date("Y-m-d H:i:s",(filemtime('test/a.txt'))));//string '2016-11-22 06:47:54' (length=19) var_dump (date("Y-m-d H:i:s",(fileatime('test/a.txt'))));//string '2016-11-22 06:47:54' (length=19) ?>?
目錄路徑
windows下的目錄路徑使用是正斜杠(\),而unix下的目錄路徑使用是反斜杠(/)
$unixPath="/var/www/html/index.php"; //在UNIX系統(tǒng)中的絕對(duì)路徑,必須使用"/"分隔 $winPath="C:\\Appserv\\www\\index.php"; //在Windows系統(tǒng)的絕對(duì)路徑,默認(rèn)使用"\"分隔 $winPath2="C:/Appserv/www/index.php"; //在Windows系統(tǒng)中也可使用“/”分隔因?yàn)樵赪indows系統(tǒng)中也可使用(/)分隔。所以,在PHP中,不論是什么操作系統(tǒng),全部都使用反斜杠(/)代表路徑分隔符號(hào)?
在PHP中,還提供了一個(gè)常量DIRECTORY_SEPARATOR,以此來代表目錄分隔符,但寫起來較麻煩
<?php echo "c:".DIRECTORY_SEPARATOR."a".DIRECTORY_SEPARATOR."b".DIRECTORY_SEPARATOR."c"; //c:\a\b\c ?>在windows下多個(gè)路徑的分隔符使用分號(hào)(;)分隔,而unix下使用冒號(hào)(:)分隔
在PHP中,提供了一個(gè)常量PATH_SEPARATOR,用來在跨平臺(tái)的情況下,表示多個(gè)路徑之間的分隔符
<?php echo "aaa/ccc/ddd".PATH_SEPARATOR."/www/yyyy";//aaa/ccc/ddd;/www/yyyy ?>換行
在window下,換行是\r\n,而在unix下,換行是\n。通常在寫程序中,換行就以u(píng)nix為準(zhǔn),寫作\n
同樣地,PHP提供了一個(gè)常量PHP_EOL,用來在跨平臺(tái)的情況下,表示換行
.和..
在PHP中,.表示當(dāng)前目錄,..表示上一級(jí)目錄
<?php var_dump (file_exists('test/a.txt'));//boolean true var_dump (file_exists('./test/a.txt'));//boolean true var_dump (file_exists('../www/test/a.txt'));//boolean true ?>根路徑
有兩種根路徑需要進(jìn)行區(qū)分,一種是客戶端根路徑,一種是服務(wù)器根路徑
以我自己在d盤安裝的wamp為例,客戶端根路徑指'd:\wamp\www\',而服務(wù)器根路徑為為'd:\'
<?php echo '<img src="/a.jpg">';//客戶端根路徑,相當(dāng)于d:\wamp\www\a.jpg mkdir('/hello');//服務(wù)器根路徑,相當(dāng)于d:\hello ?>路徑解析函數(shù)
【basename()】
basename()函數(shù)用于返回路徑中的文件名部分
<?php echo "1) ".basename("/etc/sudoers.d", ".d");//1) sudoers echo "2) ".basename("/etc/passwd").PHP_EOL;//2) passwd echo "3) ".basename("/etc/").PHP_EOL;//3) etc echo "4) ".basename(".").PHP_EOL;//4) . echo "5) ".basename("/");//5) ?>【dirname()】
dirname()函數(shù)用于返回路徑中的目錄部分
<?php echo "1) " . dirname("/etc/passwd") . PHP_EOL; // 1) /etc echo "2) " . dirname("/etc/") . PHP_EOL; // 2) \ echo "3) " . dirname("."); // 3) . ?>【pathinfo()】
pathinfo()函數(shù)用于返回文件路徑的信息
<?php $path_parts = pathinfo('/www/htdocs/inc/lib.inc.php'); echo $path_parts['dirname'], "\n";// '/www/htdocs/inc' 目錄名 echo $path_parts['basename'], "\n";// 'lib.inc.php' 文件名 echo $path_parts['extension'], "\n";// 'php' 文件后綴 echo $path_parts['filename'], "\n"; // 'lib.inc' 文件名不帶后綴 ?>【realpath()】
realpath()函數(shù)用于返回規(guī)范化的絕對(duì)路徑名
在Windows上,realpath()會(huì)將unix風(fēng)格的路徑改成Windows風(fēng)格的
<?php echo realpath('/wamp');// 'D:\wamp' ?>?
目錄遍歷
glob()
glob()函數(shù)用于尋找與模式匹配的文件路徑
array glob ( string $pattern [, int $flags = 0 ] )在www目錄下新建a.txt和b.txt文件
<?php foreach (glob("*.txt") as $filename) {//a.txt size 1050 b.txt size 73echo "$filename size " . filesize($filename) . "\n"; } ?>opendir()
opendir()函數(shù)用于打開目錄句柄。如果成功則返回目錄句柄的resource,失敗則返回 FALSE
resource opendir ( string $path [, resource $context ] ) <?php var_dump(opendir('test'))//resource(3, stream) ?>closedir()
closedir()函數(shù)用于關(guān)閉目錄句柄
void closedir ([ resource $dir_handle ] )參數(shù)dir_handle表示目錄句柄的 resource,之前由 opendir()所打開的。如果目錄句柄沒有指定,那么會(huì)假定為是opendir()所打開的最后一個(gè)句柄
<?php $dir = opendir('test'); closedir($dir); ?>readdir()
readdir()函數(shù)用于從目錄句柄中讀取條目,返回目錄中下一個(gè)文件的文件名。文件名以在文件系統(tǒng)中的排序返回,失敗時(shí)返回 FALSE
string readdir ([ resource $dir_handle ] )在www目錄下新建目錄test,并在目錄test下新建a.txt和b.txt文件
<?php $dir = opendir('test'); echo readdir($dir)."<br>";//. echo readdir($dir)."<br>";//.. echo readdir($dir)."<br>";//a.txt echo readdir($dir)."<br>";//b.txt echo readdir($dir)."<br>";// closedir($dir); ?>在遍歷目錄時(shí),每個(gè)目錄的前兩個(gè)返回值都是.和..,.代表當(dāng)前目錄,..代表上一級(jí)目錄
所以,一般地,列出當(dāng)前目錄的所有文件并去掉 . 和 ..,常采用下面的代碼
<?php if ($handle = opendir('test')) {while (false !== ($file = readdir($handle))) {if ($file != "." && $file != "..") {echo "$file\n";}}closedir($handle); } ?>接下來,在test目錄下,新建一個(gè)目錄in,并在in目錄中新建文件c.txt。然后,目錄和文件區(qū)分顯示
[注意]通過is_dir()函數(shù)判斷目錄時(shí),需要加入路徑
<?php if ($handle = opendir('test')) {while (false !== ($file = readdir($handle))) {if ($file != "." && $file != "..") {$file = "test/".$file;if(is_dir($file)){echo "目錄:".$file."<br>";}else{echo "文件:".$file."<br>";}}}closedir($handle); } /* 文件:test/a.txt 文件:test/b.txt 目錄:test/in*/ ?>rewinddir()
rewinddir()函數(shù)用于倒回目錄句柄,將參數(shù)dir_handle指定的目錄流重置到目錄的開頭
void rewinddir ( resource $dir_handle )如果不使用rewinddir()函數(shù),則文件只能遍歷一次
<?php if ($handle = opendir('test')) {while (false !== ($file = readdir($handle))) {if ($file != "." && $file != "..") {$file = "test/".$file;if(is_dir($file)){echo "目錄:".$file."<br>";}else{echo "文件:".$file."<br>";}}}while (false !== ($file = readdir($handle))) {if ($file != "." && $file != "..") {$file = "test/".$file;if(is_dir($file)){echo "目錄:".$file."<br>";}else{echo "文件:".$file."<br>";}}}closedir($handle); }/* 文件:test/a.txt 文件:test/b.txt 目錄:test/in*/ ?>使用rewinddir()函數(shù),可以把目錄句柄返回到第一個(gè)文件,從而實(shí)現(xiàn)重新遍歷
<?php if ($handle = opendir('test')) {while (false !== ($file = readdir($handle))) {if ($file != "." && $file != "..") {$file = "test/".$file;if(is_dir($file)){echo "目錄:".$file."<br>";}else{echo "文件:".$file."<br>";}}}rewinddir($handle);while (false !== ($file = readdir($handle))) {if ($file != "." && $file != "..") {$file = "test/".$file;if(is_dir($file)){echo "目錄:".$file."<br>";}else{echo "文件:".$file."<br>";}}}closedir($handle); }/* 文件:test/a.txt 文件:test/b.txt 目錄:test/in 文件:test/a.txt 文件:test/b.txt 目錄:test/in*/ ?>?
目錄統(tǒng)計(jì)
disk_total_space()
disk_total_space()函數(shù)返回一個(gè)目錄的磁盤總大小
float disk_total_space ( string $directory ) <?php $ds = disk_total_space("C:"); echo $ds."<br>";//126652637184 $ds = disk_total_space("D:"); echo $ds;//1000202240000 ?>disk_free_space()
disk_free_space()函數(shù)返回目錄中的可用空間
float disk_free_space ( string $directory ) <?php $ds = disk_free_space("C:"); echo $ds."<br>";//86087041024 $ds = disk_free_space("D:"); echo $ds;//481647472640 ?>下面來統(tǒng)計(jì)在www文件夾下新建的test目錄的個(gè)數(shù)
<?php$dirn = 0; //目錄數(shù)$filen = 0; //文件數(shù)//統(tǒng)計(jì)一個(gè)目錄下的文件和目錄的個(gè)數(shù)function getdirnum($file) {global $dirn;global $filen; $dir = opendir($file);while (false !== ($filename = readdir($dir))) {if($filename!="." && $filename !="..") {$filename = $file."/".$filename; //更新路徑if(is_dir($filename)) {$dirn++;getdirnum($filename); //遞歸,就可以查看所有子目錄} else {$filen++; }}}closedir($dir);}getdirnum("test");echo "目錄數(shù)為:{$dirn}<br>";//目錄數(shù)為:1echo "文件數(shù)為:{$filen}<br>";//文件數(shù)為:3 ?>下面來統(tǒng)計(jì)在www文件夾下新建的test目錄的大小
<?php//統(tǒng)計(jì)目錄大小function dirsize($file) {$size = 0;$dir = opendir($file);while(false !== ($filename = readdir($dir))) {if($filename!="." && $filename !="..") {$filename = $file."/".$filename;if(is_dir($filename)) {$size += dirsize($filename);//使用遞歸} else {$size += filesize($filename);}}}closedir($dir);return $size;} echo "test目錄大小為:".dirsize("test")."<br>";//test目錄大小為:302 ?>目錄增刪
mkdir()
mkdir()函數(shù)用于新建目錄
bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = false [, resource $context ]]] )rmdir()
rmdir()函數(shù)用于刪除目錄
bool rmdir ( string $dirname [, resource $context ] )[注意]該目錄必須是空的,而且要有相應(yīng)的權(quán)限。失敗時(shí)會(huì)產(chǎn)生一個(gè) E_WARNING 級(jí)別的錯(cuò)誤
unlink()
unlink()函數(shù)用于刪除文件
bool unlink ( string $filename [, resource $context ] )下面來清空test目錄
<?phpfunction deldir($dirname) {//如果是文件,直接刪除即可if(is_file($dirname)) {unlink($dirname);}$dir = opendir($dirname);while(FALSE !== ($filename = readdir($dir))) {if($filename !="." && $filename!="..") {$filename = $dirname."/".$filename;if(is_dir($filename)) {deldir($filename);//遞歸}else {unlink($filename);//刪除文件 }}}closedir($dir);if($dirname != 'test'){rmdir($dirname);//刪除目錄 }}deldir("test"); ?>?
目錄復(fù)制
copy()
copy()函數(shù)用于拷貝文件
bool copy ( string $source , string $dest [, resource $context ] )[注意]copy()函數(shù)不能用于復(fù)制目錄
<?php $file = 'a.txt'; $newfile = 'a.bak'; copy($file, $newfile); ?>rename()
rename()函數(shù)用于重命名一個(gè)文件或目錄
bool rename ( string $oldname , string $newname [, resource $context ] )[注意]rename()函數(shù)具有移動(dòng)文件或目錄的功能?
下面把www目錄下的test目錄剪貼,命名為t,并移動(dòng)到d盤目錄下
<?php rename("test", "d:/t"); ?>使用rename()只能實(shí)現(xiàn)剪切的操作,使用copy()只能復(fù)制文件。如果要復(fù)制目錄,則需要使用循環(huán)和遍歷
<?php/*** $dirsrc 原目錄* $dirto 目標(biāo)目錄*/function copydir($dirsrc, $dirto) {//如果目錄不存在,則新建一個(gè)目錄if(!file_exists($dirto)) {mkdir($dirto);}$dir = opendir($dirsrc);while(FALSE !== ($filename = readdir($dir))) {if($filename != "." && $filename !="..") {$srcfile = $dirsrc."/".$filename; //原文件$tofile = $dirto."/".$filename; //目標(biāo)文件if(is_dir($srcfile)) {copydir($srcfile, $tofile); //遞歸處理所有子目錄}else{copy($srcfile, $tofile);//復(fù)制文件 }}}}copydir("test", "d:/t"); ?>?
文件操作
touch()
touch()函數(shù)用來設(shè)定文件的訪問和修改時(shí)間。如果文件不存在,則會(huì)被創(chuàng)建。成功時(shí)返回 TRUE, 或者在失敗時(shí)返回 FALSE
bool touch ( string $filename [, int $time = time() [, int $atime ]] )參數(shù)filename表示要設(shè)定的文件名,time表示要設(shè)定的時(shí)間。如果沒有提供參數(shù) time 則會(huì)使用當(dāng)前系統(tǒng)的時(shí)間;atime表示如果給出了這個(gè)參數(shù),則給定文件的訪問時(shí)間會(huì)被設(shè)為atime,否則會(huì)設(shè)置為time。如果沒有給出這兩個(gè)參數(shù),則使用當(dāng)前系統(tǒng)時(shí)間
<?phptouch('abc.txt') ?>copy()
copy()函數(shù)用于拷貝文件
bool copy ( string $source , string $dest [, resource $context ] )[注意]copy()函數(shù)不能用于復(fù)制目錄
<?php $file = 'a.txt'; $newfile = 'a.bak'; copy($file, $newfile); ?>rename()
rename()函數(shù)用于重命名一個(gè)文件或目錄
bool rename ( string $oldname , string $newname [, resource $context ] )[注意]rename()函數(shù)具有移動(dòng)文件或目錄的功能
<?php rename("abc.txt", "d:/cba.txt"); ?>unlink()
unlink()函數(shù)用于刪除文件
bool unlink ( string $filename [, resource $context ] ) <?php unlink("d:/cba.txt"); ?>?
文件內(nèi)容
fopen()
fopen()函數(shù)用于打開文件或者URL,fopen()將 filename 指定的名字資源綁定到一個(gè)流上
[注意]如果文件不存在,將新建并打開文件
fopen('test.png',w);fopen() 中 mode 的可能值列表
mode 說明 'r' 只讀方式打開,將文件指針指向文件頭。 'r+' 讀寫方式打開,將文件指針指向文件頭。 'w' 寫入方式打開,將文件指針指向文件頭并將文件大小截為零。如果文件不存在則嘗試創(chuàng)建之。 'w+' 讀寫方式打開,將文件指針指向文件頭并將文件大小截為零。如果文件不存在則嘗試創(chuàng)建之。 'a' 寫入方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創(chuàng)建之。 'a+' 讀寫方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創(chuàng)建之。 <?php//使用絕對(duì)路徑打開file.txt文件,選擇只讀模式,并返回資源$handle$handle = fopen("/home/rasmus/file.txt", "r");//訪問文檔根目錄下的文件,也以只讀模式打開$handle = fopen(“{$_SERVER['DOCUMENT_ROOT']}/data/info.txt", "r");//在 Windows 平臺(tái)上,轉(zhuǎn)義文件路徑中的每個(gè)反斜線,或者用斜線,以二進(jìn)制和只寫模式組合$handle = fopen("c:\\data\\file.gif", "wb");//使用相對(duì)路徑打開file.txt文件,選擇只讀模式,并返回資源$handle$handle = fopen("../data/info.txt", "r");//打開遠(yuǎn)程文件, 使用HTTP協(xié)議只能以只讀的模式打開$handle = fopen("http://www.example.com/", "r");//使用FTP協(xié)議打開遠(yuǎn)程文件,如果FTP服務(wù)器可寫,則可以以寫的模式打開$handle = fopen("ftp://user:password@example.com/somefile.txt", "w"); ?>fclose()
fclose()函數(shù)用于關(guān)閉一個(gè)已打開的文件指針
bool fclose ( resource $handle ) <?php $handle = fopen('test/a.txt', 'r'); fclose($handle); ?>fwrite()
fwrite()函數(shù)用于寫入文件(可安全用于二進(jìn)制文件),返回寫入的字符數(shù),出現(xiàn)錯(cuò)誤時(shí)則返回 FALSE
int fwrite ( resource $handle , string $string [, int $length ] )當(dāng)打開方式為只讀模式時(shí),無法向文件寫入字符
<?php $fp = fopen('test/a.txt', 'r'); echo fwrite($fp, '1');//0 echo "<br>"; echo fwrite($fp, '23');//0 echo "<br>"; fclose($fp); ?>當(dāng)打開方式為寫模式時(shí),可以向文件寫入字符
<?php $fp = fopen('test/a.txt', 'w'); echo fwrite($fp, '1');//1 echo "<br>"; echo fwrite($fp, '23');//2 echo "<br>"; fclose($fp); /* 文件內(nèi)容為123*/ ?>當(dāng)打開方式為追加模式時(shí),將向文件的尾部追加新的字符
<?php $fp = fopen('test/a.txt', 'a'); echo fwrite($fp, '1');//1 echo "<br>"; echo fwrite($fp, '23');//2 echo "<br>"; fclose($fp); /* 刷新兩次時(shí),文件內(nèi)容為123123*/ ?>fgetc()
fgetc()函數(shù)用于從文件指針中讀取字符
[注意]使用fgetc()函數(shù)時(shí),需要在fopen()函數(shù)中使用讀模式
string fgetc ( resource $handle ) <?php $fp = fopen('test/a.txt', 'r'); echo fgetc($fp);//1 echo fgetc($fp);//2 echo fgetc($fp);//3 fclose($fp); ?>feof()
feof()函數(shù)用于測(cè)試文件指針是否到了文件結(jié)束的位置
bool feof ( resource $handle ) <?php $fp = fopen('test/a.txt', 'r'); while(!feof($fp)){echo fgetc($fp);//123123 } fclose($fp); ?>fgets()
fgets()函數(shù)用于從文件指針中讀取一行
string fgets ( resource $handle [, int $length ] )將test目錄下的a.txt文件內(nèi)容修改為
aa bbb <?php $fp = fopen('test/a.txt', 'r'); echo fgets($fp);//'aa' echo fgets($fp);//'bbb' echo fgets($fp);//'' fclose($fp); ?>fread()
fread()函數(shù)用于讀取文件(可安全用于二進(jìn)制文件)。fread()從文件指針handle讀取最多l(xiāng)ength個(gè)字節(jié)。該函數(shù)在讀取了length個(gè)字節(jié)或到達(dá)了文件末尾(EOF)時(shí)將停止讀取文件
string fread ( resource $handle , int $length ) <?php $fp = fopen('test/a.txt', 'r'); echo fread($fp,3);//'aa ' fclose($fp);$fp = fopen('test/a.txt', 'r'); echo fread($fp,filesize('test/a.txt'));//'aa bbb' fclose($fp); ?>fseek()
fseek()函數(shù)用于在文件指針中定位,成功則返回 0;否則返回 -1
int fseek ( resource $handle , int $offset [, int $whence = SEEK_SET ] )將test目錄下的a.txt文件內(nèi)容修改為'12345'
<?php $fp = fopen('test/a.txt', 'r'); echo fgetc($fp);//'1' fseek($fp,4); echo fgetc($fp);//'5' fclose($fp); ?> <?php $fp = fopen('test/a.txt', 'r'); echo fread($fp,2)."<br>";//12 fseek($fp,4); echo fread($fp,2)."<br>";//5 fseek($fp,-3,SEEK_END); echo fread($fp,2)."<br>";//34 fclose($fp); ?>ftell()
ftell()函數(shù)用于返回文件指針讀/寫的位置
int ftell ( resource $handle ) <?php $fp = fopen('test/a.txt', 'r'); echo ftell($fp);//0 fgetc($fp); echo ftell($fp);//1 fseek($fp,4); echo ftell($fp);//4 fclose($fp); ?>rewind()
rewind()函數(shù)用于倒回文件指針的位置,將handle的文件位置指針設(shè)為文件流的開頭
bool rewind ( resource $handle ) <?php $fp = fopen('test/a.txt', 'r'); fseek($fp,2); echo ftell($fp);//2 rewind($fp); echo ftell($fp);//0 ?>file_get_contents()
file_get_contents()函數(shù)用于將整個(gè)文件讀入一個(gè)字符串
string file_get_contents ( string $filename [, bool $use_include_path = false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] ) <?php $homepage = file_get_contents('test/a.txt'); echo $homepage;//'12345' ?>頁面變?yōu)榘俣仁醉?/p> <?php $homepage = file_get_contents('http://www.baidu.com/'); echo $homepage; ?>
file_put_contents()
file_put_contents()函數(shù)用于將一個(gè)字符串寫入文件
int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )使用該函數(shù)和依次調(diào)用 fopen(),fwrite() 以及 fclose() 功能一樣
[注意]默認(rèn)為寫模式,若設(shè)置第三個(gè)參數(shù)為FILE_APPEND,則變?yōu)樽芳幽J?/p> <?php file_put_contents('test/a.txt','abc'); ?>
readfile()
readfile()函數(shù)用于讀取文件并寫入到輸出緩沖
int readfile ( string $filename [, bool $use_include_path = false [, resource $context ]] ) <?php readfile('http://www.baidu.com/');//頁面中顯示百度首頁 ?> <?php readfile('test/a.txt');//頁面中顯示abc ?>file()
file()函數(shù)用于把整個(gè)文件讀入一個(gè)數(shù)組中,每一行作為一個(gè)數(shù)組的元素
array file ( string $filename [, int $flags = 0 [, resource $context ]] )將a.txt的文件內(nèi)容改為每一行一個(gè)數(shù)字,分別是1、2、3、4、5、6、7、8、9
<?php $arr = file('test/a.txt',0); echo $arr[0]."<br>";//1 echo count($arr);//9 ?>ftruncate()
ftruncate()函數(shù)用于將文件截?cái)嗟浇o定的長度
bool ftruncate ( resource $handle , int $size )[注意]使用ftruncate()函數(shù)時(shí),需要使用追加模式。經(jīng)測(cè)試,使用讀模式時(shí)無效,使用寫模式時(shí),文件內(nèi)容被清空
<?php $fp = fopen("test/a.txt","a"); ftruncate($fp,100); ?>?【新建文件】
php中并沒有專門的新建一個(gè)空文件的函數(shù),但是可以利用fopen()和touch()方法實(shí)現(xiàn)
$file = fopen('a.png',w); fclose($file); touchu('a.png');?
文件鎖定
文件操作是在網(wǎng)絡(luò)環(huán)境下完成的,可能有多個(gè)客戶端用戶在同一時(shí)刻對(duì)服務(wù)器上的同一個(gè)文件訪問。當(dāng)這種并發(fā)訪問發(fā)生時(shí),很可能會(huì)破壞文件中的數(shù)據(jù)。例如,一個(gè)用戶正向文件中寫入數(shù)據(jù),還沒有寫完時(shí),其他用戶在這一時(shí)刻也向這個(gè)文件寫入數(shù)據(jù),就會(huì)造成數(shù)據(jù)寫入混亂。還有,當(dāng)用戶沒有將數(shù)據(jù)寫完時(shí),其他用戶就去獲取這個(gè)文件中的內(nèi)容,也會(huì)得到殘缺的數(shù)據(jù)
在PHP中提供了flock()函數(shù),可以對(duì)文件使用鎖定機(jī)制(鎖定或釋放文件)。當(dāng)一個(gè)進(jìn)程在訪問文件時(shí)加上鎖,其他進(jìn)程想對(duì)該文件進(jìn)行訪問,則必須等到鎖定被釋放以后。這樣就可以避免在并發(fā)訪問同一個(gè)文件時(shí)破壞數(shù)據(jù)
語法: bool flock ( int handle, int operation [, int &wouldblock] )PHP支持以咨詢方式(也就是說所有訪問程序必須使用同一方式鎖定,否則它不會(huì)工作)鎖定全部文件的一種輕便方法
handle 必須是一個(gè)已經(jīng)打開的文件指針
operation 可以是以下值之一:
要取得共享鎖定(讀取程序),將 operation 設(shè)為 LOCK_SH
要取得獨(dú)占鎖定(寫入程序),將 operation 設(shè)為 LOCK_EX
要釋放鎖定(無論共享或獨(dú)占),將 operation 設(shè)為 LOCK_UN
如果不希望flock()在鎖定時(shí)堵塞,則給 operation 加上 LOCK_NB
如果成功則返回 TRUE,失敗則返回 FALSE
下面是一個(gè)網(wǎng)絡(luò)留言本的示例,一方面應(yīng)用鎖機(jī)制,另一方面綜合地使用PHP中文件操作的內(nèi)容
<?phpheader("Content-Type:text/html;charset=utf8");//功能類似于數(shù)據(jù)庫的文件$filename = "message.txt";//檢查函數(shù)function test_input($data) {$data = trim($data);$data = stripslashes($data);$data = htmlspecialchars($data);return $data;}//如果用戶提交了,就按一定格式寫入文件if(isset($_POST['dosubmit'])) {$name = test_input($_POST['username']);$content = test_input($_POST['content']);//字段的分隔使用||,行的分隔使用[n]$mess = "$name||$content||".time()."[n]";//調(diào)用寫信息函數(shù)writemessage($filename, $mess);}//如果文件存在,則讀文件內(nèi)容if(file_exists($filename)) {readmessage($filename);}//寫函數(shù)function writemessage($filename, $mess) {global $name,$content;//以追加模式打開文件$fp = fopen($filename, "a");//如果鎖定成功if(flock($fp, LOCK_EX+LOCK_NB)) {//將數(shù)據(jù)寫入文件if($name && $content){fwrite($fp, $mess);}//釋放鎖定flock($fp, LOCK_UN+LOCK_NB);}else{echo "寫入鎖定失敗!";}//關(guān)閉文件fclose($fp);}//讀函數(shù)function readmessage($filename) {//以只讀模式打開文件$fp = fopen($filename, "r");//讀鎖定flock($fp, LOCK_SH+LOCK_NB); $mess = "";//將數(shù)據(jù)遍歷到$mess中while(!feof($fp)) {$mess.=fread($fp, 1024);}//釋放鎖定flock($fp, LOCK_UN+LOCK_NB);if(!empty($mess)){$mess = rtrim($mess, "[n]");//通過[n]將每行留言分割并存入數(shù)組中$arrmess = explode("[n]", $mess);foreach($arrmess as $m) {//將每行數(shù)據(jù)使用'||'分割list($username,$content,$t) = explode("||", $m);date_default_timezone_set('PRC');echo "<b>{$username}</b>說:<u>{$content}</u>(".date('Y-m-d H:i:s',$t).")<hr><br>";} }//關(guān)閉文件fclose($fp);} ?> <form action="message.php" method="post">用戶:<input type="text" name="username" value="" /><br>內(nèi)容:<textarea name="content" cols="22" rows="3"></textarea><br><input type="submit" name="dosubmit" value="留言" /><br> </form>?
文件上傳
要想通過PHP成功地管理上傳文件,需要通過以下三方面信息:
1、設(shè)置PHP配置文件中的指令:用于精細(xì)地調(diào)節(jié)PHP的文件上傳功能
2、$_FILES多維數(shù)組:用于存儲(chǔ)各種與上傳文件有關(guān)的信息,其他數(shù)據(jù)還使用$_POST去接收
$_FILES["myfile"]["name"]中的值是:客戶端文件系統(tǒng)的文件的名稱
$_FILES["myfile"]["type"]中的值是:客戶端傳遞的文件的類型
$_FILES["myfile"]["size"]中的值是:文件的字節(jié)的大小
$_FILES["myfile"]["tmp_name"]中的值是:文件被上傳后在服務(wù)器存儲(chǔ)的臨時(shí)全路徑
$_FILES["myfile"]["error"]中的值是:文件上傳的錯(cuò)誤代碼(php 4.2以后增加的功能)
伴隨文件上傳時(shí)產(chǎn)生的錯(cuò)誤信息代碼具體如下:
值為0(UPLOAD_ERR_OK):表示沒有發(fā)生任何錯(cuò)誤
值為1(UPLOAD_ERR_INI_SIZE):表示上傳文件的大小超出了約定值。文件大小的最大值是在PHP配置文件中指定的,該指令是:upload_max_filesize
值為2(UPLOAD_ERR_FORM_SIZE):表示上傳文件大小超出了HTML表單隱藏域?qū)傩缘腗AX_FILE_SIZE元素所指定的最大值
值為3(UPLOAD_ERR_PARTIAL):表示文件只被部分上傳
值為4(UPLOAD_ERR_NO_FILE):表示沒有上傳任何文件
值為6(UPLOAD_ERR_NO_TMP_DIR):表示找不到臨時(shí)文件夾(PHP4.3.10和PHP5.0.3)
值為7(UPLOAD_ERR_CANT_WRITE):表示文件寫入失敗(PHP 5.1.0)
3、PHP的文件上傳處理函數(shù):用于上傳文件的后續(xù)處理
只要把臨時(shí)目錄下的上傳的文件,復(fù)制到指定目錄下指定的名字就可以完成上傳
PHP提供了專門用于文件上傳所使用的is_uploaded_file()和move_uploaded_file()函數(shù)
【is_uploaded_file()】
is_uploaded_file()判斷文件是否是通過 HTTP POST 上傳的
bool is_uploaded_file ( string $filename )如果filename所給出的文件是通過 HTTP POST 上傳的則返回?TRUE。這可以用來確保惡意的用戶無法欺騙腳本去訪問本不能訪問的文件
[注意]為了能使is_uploaded_file()?函數(shù)正常工作,必須使用$_FILES['userfile']['tmp_name'],而在從客戶端上傳的文件名$_FILES['userfile']['name']不能正常運(yùn)作
【move_uploaded_file()】
move_uploaded_file()方法用于將上傳的文件移動(dòng)到新位置
bool move_uploaded_file ( string $filename , string $destination )本函數(shù)檢查并確保由?filename?指定的文件是合法的上傳文件(即通過 PHP 的 HTTP POST 上傳機(jī)制所上傳的)。如果文件合法,則將其移動(dòng)為由?destination?指定的文件
該函數(shù)成功時(shí)返回TRUE;如果filename不是合法的上傳文件,不會(huì)出現(xiàn)任何操作,move_uploaded_file()將返回?FALSE;如果?filename?是合法的上傳文件,但出于某些原因無法移動(dòng),不會(huì)出現(xiàn)任何操作,move_uploaded_file()將返回?FALSE。此外還會(huì)發(fā)出一條警告
<?php header("Content-Type:text/plain;charset=utf-8"); //判斷錯(cuò)誤 if($_FILES['file1']['error'] > 0) {switch($_FILES['file1']['error']) {case 1:case 2:echo "上傳文件太大";break;case 3:echo "文件只被部分上傳";break;case 4:echo "沒有上傳任何文件";break;default:echo "末知錯(cuò)誤";}exit; }//判斷類型$arr = explode(".", basename($_FILES['file1']['name']));$hz = array_pop($arr);$allowtype =array("gif", "png", "jpg", "jpeg");if(!in_array($hz, $allowtype)) {echo "上傳的類型不合法";exit;} //判斷大小$maxsize= 1000000;if($_FILES['file1']['size'] > $maxsize) {echo "上傳的文件超過了{(lán)$maxsize}字節(jié)!";exit;}//隨機(jī)文件名$tmp_name = $_FILES['file1']['tmp_name'];$src_name = "./uploads/".date("YmdHis").rand(100, 999).".".$hz;if(move_uploaded_file($tmp_name, "$src_name")){echo '上傳成功';}else{echo '上傳失敗';} ?>?
文件下載
簡單的文件下載只需要使用HTML的鏈接標(biāo)記<a>,并將屬性href的URL值指定為下載的文件即可
<a href="http://baidu.com/test/book.rar">下載</a>如果通過上面的代碼實(shí)現(xiàn)文件下載,只能處理一些瀏覽器不能默認(rèn)識(shí)別的MIME類型文件,如訪問book.rar時(shí),瀏覽器沒有直接打開,而是彈出一個(gè)下載提示框,提示用戶下載還是打開。如果需要下載'.html'、圖片文件等瀏覽器識(shí)別的MIME類型文件時(shí),瀏覽器將直接打開該文件
常見數(shù)據(jù)格式(MIME)如下
為了提高文件的安全性,不希望在<a>標(biāo)簽中給出文件的鏈接,則必須向?yàn)g覽器發(fā)送必要的頭信息,以通知瀏覽器將要進(jìn)行下載文件的處理
【header()】
PHP使用header()函數(shù)發(fā)送網(wǎng)頁的HTTP頭部信息
void header ( string $string [, bool $replace = true [, int $http_response_code ]] )[注意]header()?必須在任何實(shí)際輸出之前調(diào)用
<?php//該行不是必須的
header('Content-type: image/png');
//將文件設(shè)置為附件格式(瀏覽器只會(huì)下載而不會(huì)打開附件格式),設(shè)置下載時(shí)顯示的文件名
header('Content-Disposition: attachment; filename="downloaded.png"');
//讀取文件并寫入到輸出緩沖
readfile('./uploads/20170315085246943.png'); ?>
?
總結(jié)
以上是生活随笔為你收集整理的前端学PHP之文件操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 同步、异步;阻塞、非阻塞
- 下一篇: linux 操作系统chgrp 的命令用