亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

PHP開(kāi)發(fā)基礎(chǔ)教程之PHP對(duì)文件的操作

一、文件系統(tǒng)

1.我們會(huì)點(diǎn)鼠標(biāo)右鍵刪除文件、會(huì)control+c(或右鍵)復(fù)制、粘貼文件,會(huì)新建一些文件,檢測(cè)這個(gè)文件是不是只讀文件。

2.在電腦里面進(jìn)行的這些操作,在代碼里面如果能操作就好了。

3.因?yàn)?,如果有了這些操作。我們能做很多事情了:

  • ?可不可以寫(xiě)入修改配置文件?

  • 是不是可以做PHP安裝的時(shí)候檢測(cè)文件的權(quán)限

  • 是不是可以做生成Html文件等等很多不同的操作

  • ..... 其他太多太多的地方用到了文件操作。

4.學(xué)習(xí)文件處理本質(zhì)上面就是學(xué)習(xí)文件處理的函數(shù)。再結(jié)合之前寫(xiě)的代碼,完善自己的業(yè)務(wù)處理能力。


二、讀取文件

1.readfile讀取文件

那如何讀取一個(gè)文件呢?我們先學(xué)一個(gè)函數(shù)。

int readfile ( string $文件名)

功能:傳入一個(gè)文件路徑,輸出一個(gè)文件。

下面的這一段代碼中,只要傳入文件名或者指定的文件路徑就把文件讀取出來(lái)了。

<?php
    //linux類(lèi)的讀了方式
    readfile("/home/paul/test.txt");
    //windows類(lèi)的讀取方式
    readfile("c:\boot.ini");
?>

注意:上面的代碼中windows的斜線是斜線,可能會(huì)轉(zhuǎn)義掉一些字符。因此,我們寫(xiě)的時(shí)候?qū)懮蟽蓚€(gè)斜線。

2.file_get_contents打開(kāi)文件

上面的是單純打文件就直接輸出了,有沒(méi)有打開(kāi)文件后,能夠賦值給一個(gè)變量的操作方式呢。

PHP當(dāng)然會(huì)提供這種方式。這個(gè)方式就是PHP打開(kāi)文件并返回內(nèi)容的方式之一,我們來(lái)看看函數(shù):

string file_get_contents ( string filename)

功能:傳入一個(gè)文件或文件路徑,打開(kāi)這個(gè)文件返回文件的內(nèi)容。文件的內(nèi)容是一個(gè)字符串。

<?php
    $filename = 'NoAlike.txt';
    $filestring = file_get_contents($filename);
    echo $filestring;
?>

上面的代碼,就打開(kāi)了一個(gè)文件,并且將文件當(dāng)中的內(nèi)容進(jìn)行了輸出。

我們來(lái)針對(duì)之前的知識(shí)把代碼進(jìn)行一下擴(kuò)展。用一用之前的知識(shí)點(diǎn)。

<?php
    //假設(shè)我們有一個(gè)多行的文件叫NoAlike.txt,沒(méi)有的話你可以新建一個(gè)這個(gè)文件
     $filename = 'NoAlike.txt';
    //打開(kāi)這個(gè)文件,將文件內(nèi)容賦值給$filestring
    $filestring = file_get_contents($filename);
    //因?yàn)槊恳恍杏幸粋€(gè)回車(chē)即\n,我用\n來(lái)把這個(gè)字符串切割成數(shù)組
    $filearray = explode("\n", $filestring);
    //把切割成的數(shù)組,下標(biāo)賦值給$key,值賦值給$val,每次循環(huán)將$key加1。
    while (list($key, $val) = each($filearray)) {
        ++$key;
        $val = trim($val);
        //用的單引號(hào),單引號(hào)不解釋變量進(jìn)行了拼接而已
        print 'Line' . $key .':'.  $val.'<br />';
    }
?>

上面,我們就把之前所學(xué)的知識(shí)進(jìn)行了組合。

3.fopen、fread、fclose操作讀取文件

上面file_get_contents打開(kāi)文件的方式簡(jiǎn)單、粗暴。下面的

  • ?resource fopen ( string $文件名, string 模式)

  • string fread ( resource $操作資源, int 讀取長(zhǎng)度)

  • ?bool fclose ( resource $操作資源 )

通過(guò)上面的函數(shù)我們來(lái)講解資源類(lèi)型的通常操作方式:

  • ?打開(kāi)資源

  • 使用相關(guān)函數(shù)進(jìn)行操作

  • ?關(guān)閉資源

fopen函數(shù)?fopen函數(shù)的功能是打開(kāi)文件,參數(shù)主要有兩個(gè):

l?文件打開(kāi)的路徑

l?打開(kāi)文件的模式

返回類(lèi)型是一個(gè)資源類(lèi)型,我們第一次遇到了之前基礎(chǔ)類(lèi)型的時(shí)候講到的資源類(lèi)型。
資源類(lèi)型需要其他的函數(shù)來(lái)操作這個(gè)資源。所有的資源有打開(kāi)就要有關(guān)閉。

fread函數(shù)?函數(shù)的功能的功能是讀取打開(kāi)的文件資源。讀取指定長(zhǎng)度的文件資源,讀取一部份向后移動(dòng)一部份。至到文件結(jié)尾。

fclose函數(shù)?fclose函數(shù)的功能是關(guān)閉資源。資源有打開(kāi)就有關(guān)閉。

了解完函數(shù),后兩個(gè)函數(shù)比較簡(jiǎn)單。而fopen函數(shù)的模式到底是什么,fopen的模式有下面幾個(gè),我們來(lái)講一下fopen的模式:


38.png


接下來(lái),我們只來(lái)學(xué)習(xí)r模式,下節(jié)課我們?cè)趯?xiě)入的時(shí)候再來(lái)講講其他幾個(gè)模式。


三、我們先會(huì)讀取文件了,才能很好的掌握寫(xiě)入文件。

1.打開(kāi)文件

<?php
    //你可以創(chuàng)建一個(gè)NoAlike.txt,以只讀模式打開(kāi)
    $fp = fopen('NoAlike.txt', "r");
 
 
    //var_dump()操作一下$fp看看效果,輸出的是不是只有類(lèi)型提示的是resource
    var_dump($fp);
?>

2.讀取文件

<?php
    $fp = fopen('NoAlike.txt', "r");
 
    //打開(kāi)一個(gè)文件類(lèi)型后,讀取長(zhǎng)度
    $contents = fread($fp, 1024);
?>

3.關(guān)閉文件

<?php
    $fp = fopen($filename, 'r');
    $contents = fread($fp, 1024);
    fclose($fp);
    echo $contents;
?>

其他注意事項(xiàng):

39.png


使用示例:

<?php
$fp = fopen($filename, 'ab');
$contents = fwrite($fp, '可愛(ài)的很\n喲');
fclose($fp);
echo $contents;
?>

說(shuō)明:
實(shí)驗(yàn)無(wú)法讓肉眼看到這個(gè)實(shí)驗(yàn)效果。大家記住有這個(gè)特點(diǎn)即可。

Windows 下提供了一個(gè)文本轉(zhuǎn)換標(biāo)記('t')可以透明地將 n 轉(zhuǎn)換為 rn。
與此對(duì)應(yīng)還可以使用 'b' 來(lái)強(qiáng)制使用二進(jìn)制模式,這樣就不會(huì)轉(zhuǎn)換數(shù)據(jù)。要使用這些標(biāo)記,要么用 'b' 或者用 't' 作為 mode 參數(shù)的最后一個(gè)字符。


四、創(chuàng)建和修改文件內(nèi)容

1.file_put_contents寫(xiě)入文件

我們先來(lái)學(xué)習(xí)第一種寫(xiě)入文件的方式:

int file_put_contents ( string $文件路徑, string $寫(xiě)入數(shù)據(jù)])

功能:向指定的文件當(dāng)中寫(xiě)入一個(gè)字符串,如果文件不存在則創(chuàng)建文件。返回的是寫(xiě)入的字節(jié)長(zhǎng)度

<?php
    $data = "我是一個(gè)兵,來(lái)自老百姓";
 
    $numbytes = file_put_contents('binggege.txt', $data);
 
    if($numbytes){
 
        echo '寫(xiě)入成功,我們讀取看看結(jié)果試試:';
 
        echo file_get_contents('binggege.txt');
 
    }else{
        echo '寫(xiě)入失敗或者沒(méi)有權(quán)限,注意檢查';
    }
?>

我們發(fā)現(xiàn)寫(xiě)入文件也挺簡(jiǎn)單的。按照這個(gè)函數(shù)的格式,指定文件,寫(xiě)入字符串?dāng)?shù)據(jù)就可以了。

2.fwrite配合fopen進(jìn)行寫(xiě)入操作

int fwrite ( resource $文件資源變量, string $寫(xiě)入的字符串 [, int 長(zhǎng)度])

注:fwrite的別名函數(shù)是fputs

我們上節(jié)課試了r模式,只道是讀取的時(shí)候使用,接下來(lái)我們用fwrite加上fopen中的w,寫(xiě)入模式來(lái)進(jìn)行文件寫(xiě)入。

我們來(lái)看一下特點(diǎn):

寫(xiě)入方式打開(kāi),將文件指針指向文件頭并將文件大小截為零。如果文件不存在則嘗試創(chuàng)建。

注意:在下面的實(shí)驗(yàn)中,你可以試試新建個(gè)test.txt文件向里面寫(xiě)入內(nèi)容。然后,可以試試把test.txt刪除??纯从惺裁刺崾尽?/strong>

<?php
    $filename = 'test.txt';
    $fp= fopen($filename, "w");
    $len = fwrite($fp, '我是一只來(lái)自南方的狼,一直在尋找心中的花姑娘');
    fclose($fp);
    print $len .'字節(jié)被寫(xiě)入了\n";
?>

總結(jié):
1.不論有沒(méi)有新建都會(huì)打開(kāi)文件重新寫(xiě)入
2.原有的文件內(nèi)容會(huì)被覆蓋掉
3.文件不存在會(huì)創(chuàng)建

那我們來(lái)對(duì)比一下以下幾個(gè)模式的不同:

40.png

我們來(lái)通過(guò)實(shí)驗(yàn)證明一下:

<?php
    $filename = 'test.txt';
    $fp= fopen($filename, "r+");
    $len = fwrite($fp, '我是一只來(lái)自南方的狼,一直在尋找心中的花姑娘');
    fclose($fp);
    print $len .'字節(jié)被寫(xiě)入了\n';
?>

實(shí)驗(yàn)時(shí)可以把r后面的+號(hào)去掉。

我們通過(guò)實(shí)驗(yàn),確實(shí)發(fā)現(xiàn)使用r模式,在文件存的時(shí)候可以進(jìn)行寫(xiě)入數(shù)據(jù),只用r的話,寫(xiě)入是不成功的。

3.a模式和w模式的不同

同樣是下面的這段代碼,我們改為a模式。

<?php
    $filename = 'test.txt';
    $fp= fopen($filename, "a");
    $len = fwrite($fp,'讀大學(xué)迷茫了,PHP學(xué)院PHP給你希望');
    echo  $len .'字節(jié)被寫(xiě)入了\n';
?>

打開(kāi)網(wǎng)頁(yè)執(zhí)行這段代碼,你會(huì)發(fā)現(xiàn):每刷新一次,文件中就會(huì)多一段
讀大學(xué)迷茫了,PHP學(xué)院PHP給你希望。

總結(jié):

41.png

4.x模式和w模式的不同

這段代碼我們?cè)賹?shí)驗(yàn)一次,改為x模式:

<?php
    $filename = 'test.txt';
    $fp= fopen($filename, "x");
    $len = fwrite($fp,'讀大學(xué)迷茫了,PHP學(xué)院PHP給你希望');
    echo  $len .'字節(jié)被寫(xiě)入了\n';
?>

我們會(huì)發(fā)現(xiàn):

文件存在的時(shí)候會(huì)報(bào)錯(cuò)

如果把$filename 改成其他的文件名,就可以了。但是,再次刷新的時(shí)候又報(bào)錯(cuò)了

x+ 是增強(qiáng)的x模式。讀取時(shí)也可以使用。




五、創(chuàng)建臨時(shí)文件

我們之前創(chuàng)建的文件都是永久文件。

而創(chuàng)建臨時(shí)文件在我們平時(shí)的項(xiàng)目開(kāi)發(fā)中也非常有用。創(chuàng)建臨時(shí)文件的幾個(gè)好處:

1.文完后即刪除

2.不需要去維護(hù)這個(gè)文件的刪除狀態(tài)

例如:我需要把A的文件內(nèi)容轉(zhuǎn)存B里面,把B的文件內(nèi)容轉(zhuǎn)存到C里面。

就跟現(xiàn)實(shí)生活中一樣,我可以先用一個(gè)臨時(shí)的瓶子把B的水裝起來(lái),然后把A的數(shù)據(jù)寫(xiě)入到B里面。把臨時(shí)瓶子的水追加到C里面。

我們來(lái)學(xué)習(xí)一下這個(gè)函數(shù):

resource tmpfile ( )

功能:創(chuàng)建一個(gè)臨時(shí)文件,返回資源類(lèi)型。關(guān)閉文件即被刪除。

<?php
    //創(chuàng)建了一個(gè)臨時(shí)文件
    $handle = tmpfile();
 
    //向里面寫(xiě)入了數(shù)據(jù)
    $numbytes = fwrite($handle, '寫(xiě)入臨時(shí)文件');
 
    //關(guān)閉臨時(shí)文件,文件即被刪除
    fclose($handle);
 
    echo  '向臨時(shí)文件中寫(xiě)入了'.$numbytes . '個(gè)字節(jié)';
?>



六、移動(dòng)、拷貝和刪除文件

1.重命名

bool rename($舊名,$新名);

這個(gè)函數(shù)返回一個(gè)bool值,將舊的名字改為新的名字。

<?php
    //舊文件名
    $filename = 'test.txt';
 
    //新文件名
    $filename2 = $filename . '.old';
 
    //復(fù)制文件
    rename($filename, $filename2);
?>

我們打開(kāi)目錄,我們可以看看效果,你會(huì)發(fā)現(xiàn)把指定的文件,復(fù)制了一份到了目標(biāo)路徑。

2.復(fù)制文件

復(fù)制文件,就相當(dāng)于是克隆技術(shù),將一個(gè)原來(lái)的東西再克隆成一個(gè)新的東西。兩個(gè)長(zhǎng)得一模一樣。

bool copy(源文件,目標(biāo)文件)

功能:將指定路徑的源文件,復(fù)制一份到目標(biāo)文件的位置。

我們來(lái)通過(guò)實(shí)驗(yàn)和代碼來(lái)玩玩:

<?php
    //舊文件名
    $filename = 'copy.txt';
 
    //新文件名
    $filename2 = $filename . '_new';
 
    //修改名字。
    copy($filename, $filename2);
?>

總結(jié):
你會(huì)通過(guò)上面的例子,發(fā)現(xiàn)多出來(lái)了一個(gè)文件。

3.刪除文件

刪除文件就是將指定路徑的一個(gè)文件刪除,不過(guò)這個(gè)刪除是直接刪除。使用的是windows電腦,你在回收站看不到這個(gè)文件。

你只會(huì)發(fā)現(xiàn),這個(gè)文件消失了。

bool unlink(指定路徑的文件)

<?php
    $filename = 'test.txt';
 
    if (unlink($filename)) {
        echo  "刪除文件成功 $filename!\n";
    } else {
        echo "刪除 $filename 失敗!\n";
    }
?>

七、檢測(cè)文件屬性函數(shù)

有些同學(xué)特別好奇,檢測(cè)文件屬性用在什么地方。檢測(cè)文件屬性能用到的地方太多了。

我們來(lái)舉例子:

1.我們?cè)谧鲕浖惭b的時(shí)候,大家會(huì)發(fā)現(xiàn)如果文件存在了,就跳轉(zhuǎn)到了其他的地方。

2.如果在安裝的過(guò)程當(dāng)中,某些文件沒(méi)有寫(xiě)入權(quán)限,就不讓進(jìn)行安裝。

我們來(lái)舉一個(gè)國(guó)內(nèi)非常出名的軟件,discuz的安裝過(guò)程截圖給大家看看:

?42.png

上面的例子,就是典型的文件檢測(cè)的用法。

我們來(lái)學(xué)習(xí)一下下面的一批函數(shù)。然后,我們來(lái)通過(guò)一個(gè)例子進(jìn)行學(xué)習(xí)。

bool file_exists ( $指定文件名或者文件路徑)
功能:文件是否存在。

bool is_readable ( $指定文件名或者文件路徑)
功能:文件是否可讀

bool is_writeable ( $指定文件名或者文件路徑)
功能:文件是否可寫(xiě)

bool is_executable ( $指定文件名或者文件路徑)
功能:文件是否可執(zhí)行

bool is_file ( $指定文件名或者文件路徑)
功能:是否是文件

bool is_dir ( $指定文件名或者文件路徑)
功能:是否是目錄

void clearstatcache ( void )
功能:清楚文件的狀態(tài)緩存

上面的功能一看就清楚了。那實(shí)驗(yàn),我們就來(lái)寫(xiě)這個(gè)最開(kāi)始我們舉的這個(gè)例子。

我們來(lái)講第一個(gè)例子,文件鎖。如果已經(jīng)安裝了,存在安裝鎖就提示已安裝,否則就繼續(xù)安裝。

我們假設(shè)安裝界面的網(wǎng)址是:install.php,安裝的鎖文件是install.lock。我們就可以檢測(cè)install.lock文件是否存在。

<?php
if(file_exists('install.lock')){
    echo '已安裝,請(qǐng)不要再次進(jìn)行安裝';
    exit;
}
?>

我們接下來(lái)做一個(gè)文件安裝檢測(cè)的實(shí)驗(yàn)來(lái)檢測(cè)文件或目錄是否有寫(xiě)入或者讀取權(quán)限。如果沒(méi)有則不能進(jìn)行安裝。

處理這件事情的思路如下:

1.定義一批需要檢測(cè)權(quán)限的數(shù)組

2.可以檢測(cè)是文件夾還是文件

3.做一個(gè)標(biāo)置位變量,如果標(biāo)置位變量一旦為false則不顯示下一步的安裝

<?php
 
//可以定義一批文件是否存在
$files = [
    'config.php',
    'img/',
    'uploads/',
];
 
//定義標(biāo)志位變量
$flag = true;
foreach($files as  $v){
    echo $v;
 
    //判斷是文件還是文件夾
 
    if(is_file($v)){
        echo '是一個(gè)文件    ';
    }else if(is_dir($v)){
        echo '是一個(gè)文件夾    ';
    }
 
    if(is_readable($v)){
        echo ' 可讀';
    }else{
         echo '<font color="red">不可讀</font>';
    }
 
    if(is_writeable($v)){
        echo '可寫(xiě)';
    }else{
        echo '<font color="red">不可寫(xiě)</font>';
    }
 
    echo '<br />';
}
 
if($flag){
    echo '<a href="step1">下一步</a>';
 
}else{
     echo '不能進(jìn)行安裝';
}
?>

通過(guò)上面的例子,我們就做到了。實(shí)現(xiàn)PHP某個(gè)軟件安裝過(guò)程當(dāng)中的安裝檢測(cè)。

也就是我們上面思路的實(shí)現(xiàn)。


八、文件常用函數(shù)和常量

1.文件操作的常量

下面這一個(gè)常量是最常用的。是文件目錄的分割符的常量。

我們來(lái)看看格式:

43.png

windows 的路徑格式為 d:xxxxxx 注意:windows支持 d:/xxx/xxx
linux 的路徑格式為 /home/xxx/xxx 注意:如果homexxxxxx 在linux上是錯(cuò)誤的
所以當(dāng)你開(kāi)啟轉(zhuǎn)義之類(lèi)的話,轉(zhuǎn)義字符 用一起的話 d:xxxxxx 是一樣的。判斷時(shí)候有兩個(gè) 有的話 再轉(zhuǎn)成一個(gè) 再把 替換成 /當(dāng)路徑分割,這樣在linux上或者windos上的路徑就能保持統(tǒng)一了。

我們會(huì)使用到一個(gè)常量:
DIRECTORY_SEPARATOR

我們來(lái)寫(xiě)一個(gè)小的實(shí)例,定義當(dāng)前文件所在的路徑:

由于FILE是PHP的預(yù)定義常量,所以沒(méi)辦法改變,如果需要讓FILE也自適應(yīng)操作系統(tǒng)。
那么就是不要用FILE,可以用自定義的常量,并且把FILE處理一下,如下:

<?php
$_current_file = str_replace(array('/', '\'), DIRECTORY_SEPARATOR, __FILE__);
define('__CUR_FILE__', $_current_file);
echo __CUR_FILE__;
?>

2.文件指針操作函數(shù)

rewind ( resource handle)

功能:指針回到開(kāi)始處

fseek ( resource handle, int offset [, int from_where])
功能:文件指針向后移動(dòng)指定字符

我們?cè)谥暗淖x取當(dāng)中我們發(fā)現(xiàn)fread讀取指定長(zhǎng)度的數(shù)據(jù)。讀取指定長(zhǎng)度的內(nèi)容,下次再讀取的時(shí)候從原位置開(kāi)始再接著向后讀取。

?44.png

如上圖,我們可以想象:

1.文件剛打開(kāi)的時(shí)候讀取到的是紅色的圖標(biāo)

2.文件假色從A讀取到了C

3.我們?cè)赿emo.txt文件中寫(xiě)入一批文件:

  • Abcdeefghijklk

  • ?Opqrst

  • Uvwxyz

  • ?12345678

我們可開(kāi)始來(lái)實(shí)驗(yàn)一次。

<?php
$fp = fopen('output.txt', 'r+');
//讀取10個(gè)字符
echo fread($fp,10);
 
//指針設(shè)置回到開(kāi)始處
rewind($handle);
//再讀取10次看看輸出的是什么
echo fread($fp,10);
 
//文件指針向后移動(dòng)10個(gè)字符
echo fseek($fp,10);
 
//再看看文件中輸出的是什么
echo fread($fp,10);
 
fclose($handle);
?>

上面的例子,你會(huì)發(fā)現(xiàn)fseek指定多長(zhǎng)就移動(dòng)多少個(gè)字節(jié)。而rewind每次都是回到文件的開(kāi)始處。

那如何移動(dòng)到最末尾呢?我們可以統(tǒng)計(jì)字節(jié)數(shù)。在fseek的時(shí)候直接移到回后。

下面我們來(lái)講filesize統(tǒng)計(jì)字節(jié)數(shù)。

3.filesize 檢測(cè)文件的大小

<?php
$filename = 'demo.txt';
echo $filename . '文件大小為: ' . filesize($filename) . ' bytes';
?>

4.其它操作文件的函數(shù)

其實(shí)還有一些其他操作文件的函數(shù),讀取文件

45.png

我們通過(guò)一個(gè)實(shí)例來(lái)把上面幾個(gè)函數(shù)都用到。

我們?cè)赿emo.txt文件中寫(xiě)入一批文件:

abcdeefghijklk
opqrst
uvwxyz
12345678

<?php
//以增加的r模式打開(kāi)
$fp = fopen('demo.txt','r+');
//你分發(fā)現(xiàn)每次只讀一個(gè)字符
echo  fgetc($fp);
 
//我要全部讀取可以,讀取一次將結(jié)果賦值一次給$string
while($string = fgetc($fp)){
    echo $string;
}
?>

fgets每次打開(kāi)一行:

<?php
//以增加的r模式打開(kāi)
$fp = fopen('demo.txt','r+');
//你分發(fā)現(xiàn)每次只讀一個(gè)字符
echo  fgets($fp);
echo  fgets($fp);
echo  fgets($fp);
echo  fgets($fp);
?>

上面的代碼,你會(huì)發(fā)現(xiàn)每次讀取一次打開(kāi)一行。讀取最后返回的是false。

我們接下來(lái)看文件截取函數(shù):

<?php
//打開(kāi)我們上面的demo.txt文件
$file = fopen("demo.txt", "a+");
//你可以數(shù)數(shù)20個(gè)字有多長(zhǎng),看看是不是達(dá)到效果了
echo ftruncate($file,20);
fclose($file);
?>

上例中我們發(fā)現(xiàn),截取多長(zhǎng)就能顯示多長(zhǎng)的內(nèi)容。

5.文件的時(shí)間函數(shù)

46.png

<?php
$filename = 'demo.txt';
if (file_exists($filename)) {
    echo "$filename文件的上次訪問(wèn)時(shí)間是: " . date("Y-m-d H:i:s", fileatime($filename));
    echo "$filename文件的創(chuàng)建時(shí)間是: " . date("Y-m-d H:i:s", filectime($filename));
     echo "$filename文件的修改時(shí)間是: " . date("Y-m-d H:i:s", filemtime($filename));
}
?>



九、文件鎖機(jī)制

文件鎖機(jī)制一般在單一打開(kāi)文件的時(shí)候根本看不到效果。這一塊的學(xué)習(xí)有一點(diǎn)點(diǎn)抽象。

大家不要去思考怎么實(shí)現(xiàn)的呀?

為什么看不到效果呀?
答:因?yàn)殡娔X的操作太快了,基本上是毫秒級(jí)的。所以這個(gè)實(shí)驗(yàn)其實(shí)是看不到效果的。

這一章了解文件鎖的基本概念即可,熟悉文件鎖函數(shù)和鎖機(jī)制。

文件鎖的用途:

若一個(gè)人在寫(xiě)入一個(gè)文件,另外一個(gè)人同時(shí)也打個(gè)了這個(gè)文件進(jìn)行寫(xiě)入文件。
這情況下,如果遇到一定的碰撞概率的話,不知道到底誰(shuí)的操作為準(zhǔn)。
因此,這個(gè)時(shí)候我們引入鎖機(jī)制。
若用戶(hù)A在寫(xiě)入或者讀取這個(gè)文件的時(shí)候,將文件加上共享所。我可以讀,其他人也可以讀。
但是,我如果這與的時(shí)候。我使用獨(dú)占鎖。這個(gè)文件歸我了,你們都別動(dòng),除非我將文件鎖進(jìn)行釋放。

注意:不論加上了文件鎖后要注意釋放。

我們來(lái)看看這個(gè)函數(shù):

bool flock ( resource $handle , int $operation)

功能:輕便的咨詢(xún)文件鎖定

我們來(lái)看看鎖類(lèi)型:

47.png

我們接下來(lái)把demo.txt加上一個(gè)獨(dú)占鎖,進(jìn)行寫(xiě)入操作。

<?php
$fp = fopen("demo.txt", "r+");
 // 進(jìn)行排它型鎖定
if (flock($fp, LOCK_EX)) {
    fwrite($fp, "文件這個(gè)時(shí)候被我獨(dú)占了喲\n");
   // 釋放鎖定
    flock($fp, LOCK_UN);    
} else {
    echo "鎖失敗,可能有人在操作,這個(gè)時(shí)候不能將文件上鎖";
}
fclose($fp);
?>

說(shuō)明:

上例中我為了寫(xiě)入文件,把文件加上了獨(dú)占鎖。

如果我操作完成,寫(xiě)入完成后,解除掉了獨(dú)占鎖。

如果是在讀取文件的時(shí)候,大家可加按照同樣的處理思路加上共享鎖。


十、目錄處理函數(shù)

之前我們處理的全都是文件,那目錄和文件夾怎么處理呢?

我們就來(lái)學(xué)習(xí)目錄或者稱(chēng)為文件夾的處理相關(guān)函數(shù)。

處理文件夾的基本思想如下:

讀取某個(gè)路徑的時(shí)候判斷是否是文件夾

是文件夾的話,打開(kāi)指定文件夾,返回文件目錄的資源變量

使用readdir讀取一次目錄中的文件,目錄指針向后偏移一次

使用readdir讀取到最后,沒(méi)有可讀的文件返回false

關(guān)閉文件目錄

我們來(lái)學(xué)習(xí)一比常用函數(shù):

48.png

<?php
//設(shè)置打開(kāi)的目錄是D盤(pán)
$dir = "d:/";
//判斷是否是文件夾,是文件夾
if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
       //讀取一次向后移動(dòng)一次文件夾指針
       echo readdir($dh).'<br />';
       echo readdir($dh).'<br />';
       echo readdir($dh).'<br />';
       echo readdir($dh).'<br />';
       //讀取到最后返回false
       //關(guān)閉文件夾資源
        closedir($dh);
    }
}
?>

即然是讀取一次向后移動(dòng)一次,我們是不是可以

<?php
//設(shè)置打開(kāi)的目錄是D盤(pán)
$dir = "d:/";
 
//判斷是否是文件夾,是文件夾
if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
       //讀取到最后返回false,停止循環(huán)
       while (($file = readdir($dh)) !== false) {
            echo "文件名為: $file : 文件的類(lèi)型是: " . filetype($dir . $file) . "<br />";
        }
        closedir($dh);
    }
}
?>

?


十一、文件權(quán)限設(shè)置

文件權(quán)限設(shè)置的函數(shù)在系統(tǒng)管理級(jí)別的軟件中很常用。例如:某個(gè)文件不準(zhǔn)許guest組(來(lái)賓用戶(hù))查看呀。

在企業(yè)管理中,某些用戶(hù)或者某些用戶(hù)文件只準(zhǔn)讀取不準(zhǔn)修改。這都是非常常用的功能。

注:

本章為了解章節(jié)。如果沒(méi)有學(xué)習(xí)過(guò)linux會(huì)有些吃力,可以跳過(guò)本章,了解有這個(gè)東西即可。

在實(shí)際生產(chǎn)環(huán)節(jié)中用處較少。

主要針對(duì)在linux下有過(guò)全面知識(shí)體系的同學(xué)可以重點(diǎn)學(xué)習(xí)。

windows下面有些功能無(wú)法實(shí)現(xiàn)。

49.png

上面的函數(shù)用法與linux的權(quán)限操作的用法一樣。
對(duì)于學(xué)過(guò)linux的同學(xué)來(lái)說(shuō)學(xué)起來(lái)比較簡(jiǎn)單。沒(méi)有學(xué)過(guò)的會(huì)有些吃力。

我只講一個(gè)例子,看看如何來(lái)修改權(quán)限:

chmod 主要是修改文件的的權(quán)限

<?php
//修改linux  系統(tǒng)/var/wwwroot/某文件權(quán)限為755
chmod("/var/wwwroot/index.html", 755);  
chmod("/var/wwwroot/index.html", "u+rwx,go+rx");
chmod("/somedir/somefile", 0755);
?>



十二、文件路徑函數(shù)

1.情景重現(xiàn)

我們經(jīng)常會(huì)遇到處理文件路徑的情況。

例如:

文件后綴需要取出來(lái)

路徑需要取出名字不取目錄

只需要取出路徑名中的目錄路徑

或者把網(wǎng)址中的各個(gè)部份進(jìn)行解析取得獨(dú)立值

甚至是自己組成一個(gè)url出來(lái)
... ....

很多地方都需要用路徑處理類(lèi)的函數(shù)。

我們把常用的路徑處理函數(shù)為大家做了標(biāo)注,大家對(duì)著這個(gè)路徑處理函數(shù)進(jìn)行處理即可:

50.png

2.Pathinfo

array pathinfo ( string $路徑)
功能:傳入文件路徑返回文件的各個(gè)組成部份

我們用具體的示例來(lái)用一下:

<?php
$path_parts = pathinfo('d:/www/index.inc.php');
 
echo '文件目錄名:'.$path_parts['dirname']."<br />";
echo '文件全名:'.$path_parts['basename']."<br />";
echo '文件擴(kuò)展名:'.$path_parts['extension']."<br />";
echo '不包含擴(kuò)展的文件名:'.$path_parts['filename']."<br />";
?>

結(jié)果如下:

文件目錄名:d:/www
文件全名:lib.inc.php
文件擴(kuò)展名:php
不包含擴(kuò)展的文件名:lib.inc

3.Basename

string basename ( string $路徑[, string $suffix ])
功能:傳入路徑返回文件名

第一個(gè)參數(shù)傳入路徑。
第二個(gè)參數(shù),指定我文件名到了指定字符停止。

<?php 
echo "1: ".basename("d:/www/index.d", ".d").PHP_EOL;
echo "2: ".basename("d:/www/index.php").PHP_EOL;
echo "3: ".basename("d:/www/passwd").PHP_EOL; 
?>
4.Dirname
dirname(string $路徑) 功能:返回文件路徑的文件目錄部份
<?php
dirname(__FILE__);
?>

結(jié)論:你可以執(zhí)行看看是不是返回了文件的目錄部份。

5.parse_url

mixed parse_url ( string $路徑 )
功能:將網(wǎng)址拆解成各個(gè)部份

<?php
$url = 'http://username:password@hostname:9090/path?arg=value#anchor';
var_dump(parse_url($url));
?>

結(jié)果如下:

array(8) {
["scheme"]=> string(4) "http"
["host"]=> string(8) "hostname"
["port"]=> int(9090)
["user"]=> string(8) "username"
["pass"]=> string(8) "password"
["path"]=> string(5) "/path"
["query"]=> string(9) "arg=value"
["fragment"]=> string(6) "anchor"
}

6.http_build_query

string http_build_query ( mixed $需要處理的數(shù)據(jù))
功能:生成url 中的query字符串

<?php
//定義一個(gè)關(guān)聯(lián)數(shù)組
$data = [
        'username'=>'liwenkai',
        'area'=>'hubei'
         ];
//生成query內(nèi)容
echo http_build_query($data);
?>

結(jié)果如下:

username=liwenkai&area=hubei

http_build_url()?
功能: 生成一個(gè)url

?

注:
PHP_EOL 常量
在 windows平臺(tái)相當(dāng)于 echo "rn";
在unixlinux平臺(tái)相當(dāng)于 echo "n";
在mac平臺(tái)相當(dāng)于 echo "r";




十三、文本留言本

我們講完了這么多關(guān)于文件處理的系統(tǒng),可是我們連一個(gè)最基本的小東西都寫(xiě)不出來(lái)。

從這一節(jié)開(kāi)始,大家會(huì)發(fā)現(xiàn)大家能夠?qū)懺絹?lái)越多的東西了。

接下來(lái)我們我們來(lái)看看演示效果:

在下面一個(gè)界面中寫(xiě)入留言?xún)?nèi)容的表單界面:

存在留言后的展示界面:

51.png

我們來(lái)看一下文件結(jié)構(gòu):

index.php ---展示輸入框和留言?xún)?nèi)容
write.php ---向message.txt寫(xiě)入數(shù)據(jù)
message.txt ---存入聊天內(nèi)容

index.php文件

<?Php
//設(shè)置時(shí)區(qū)
date_default_timezone_set('PRC');
 
//讀了內(nèi)容
@$string = file_get_contents('message.txt');
 
//如果$string 不為空的時(shí)候執(zhí)行,也就是message.txt中有留言數(shù)據(jù)
if (!empty($string)) {
 
    //每一段留言有一個(gè)分格符,但是最后多出了一個(gè)&^。因此,我們要將&^刪掉
    $string = rtrim($string, '&^');
 
    //以&^切成數(shù)組
    $arr = explode('&^', $string);
 
    //將留言?xún)?nèi)容讀取
    foreach ($arr as $value) {
 
        //將用戶(hù)名和內(nèi)容分開(kāi)
        list($username, $content, $time) = explode('$#', $value);
 
        echo '用戶(hù)名為<font color="gree">' . $username . '</font>內(nèi)容為<font color="red">' . $content . '</font>時(shí)間為' . date('Y-m-d H:i:s', $time);
        echo '<hr />';
    }
 
}
 
?>
 
 
<h1>基于文件的留言本演示</h1>
<form action="write.php" method="post">
    用戶(hù)名:<input type="text" name="username" /><br />
 
    留言?xún)?nèi)容:<textarea  name="content"></textarea><br />
 
    <input type="submit" value="提交" />
 
</form>

看了剛剛的展示內(nèi)容,我們知道文件存儲(chǔ)時(shí):

段與段之間進(jìn)行了分割

內(nèi)容與用戶(hù)之前用一個(gè)特殊的符號(hào)進(jìn)行了分割

下面我們來(lái)寫(xiě)write.php寫(xiě)入留言至文件的代碼:

<?php
//追加方式打開(kāi)文件
$fp=fopen('message.txt','a');
 
//設(shè)置時(shí)間
$time=time();
 
//得到用戶(hù)名
$username=trim($_POST['username']);
//得到內(nèi)容
$content=trim($_POST['content']);
 
 
//組合寫(xiě)入的字符串:內(nèi)容和用戶(hù)之間分開(kāi),使用$#
//行與行之間分開(kāi),使用&^
$string=$username.'$#'.$content.'$#'.$time.'&^';
 
//寫(xiě)入文件
fwrite($fp,$string);
 
//關(guān)閉文件
fclose($fp);
 
 
header('location:index.php');
 
?>
繼續(xù)學(xué)習(xí)
||
<?php //linux類(lèi)的讀了方式 readfile("/home/paul/test.txt"); //windows類(lèi)的讀取方式 readfile("c:\\boot.ini"); ?>
提交重置代碼