PHP 檔案寫入和讀取(必看篇)
文章提綱:
一.實現檔案讀取和寫入的基本思路
二.使用fopen方法開啟檔案
三.檔案讀取和檔案寫入操作
四.使用fclose方法關閉檔案
五.檔案指標的移動
六.Windows和UNIX下的回車和換行
一.實現檔案讀取和寫入的基本思路:
1.通過fopen方法開啟檔案:$fp =fopen(/*引數,引數*/),fp為Resource型別
2.進行檔案讀取或者檔案寫入操作(這裡使用的函式以1中返回的$fp作為引數)
3. 呼叫fclose($fp)關閉關閉檔案
二:使用fopen方法開啟檔案
fopen(檔案路徑[string],開啟模式[string])
<1>fopen的第一個引數為檔案路徑
寫檔案路徑的方式:1絕對路徑,2相對路徑
1絕對路徑:
在windows下工作的小夥伴們應該很熟悉,windows下的路徑分隔符是“\”而不是“/”,但我們在寫入路徑時不能以欽定的“\”為分隔符
那如果我們以“\”分隔符寫入路徑會怎樣呢? ?1 2 3 |
<?php
$fp
=
fopen
(
"C:\wamp64\www\text.txt"
,
'w'
);
?>
|
所以我們要把分隔符“\”換成“/”:
1 2 3 |
<?php
$fp
=
fopen
(
"C:/wamp64/www/text.txt"
,
'w'
);
?>
|
執行時無報錯,說明引數是有效的。
【注意】fopen函式不能理解“\”分隔符,如果你想要使用“\”,那麼要使用轉義,如寫成:"C:\\wamp64\\www\\text.txt"這種寫法也是可以的,函式也能理解,不會報錯。但即使這樣,也不推薦使用“\”,因為在OS(mac)下只能識別“/”不能識別“\”
本小節的結論:推薦堅持使用“/”作為分隔符
2.相對路徑:
上一小節介紹的是絕對路徑的寫法,但這樣卻帶來了另外一個問題:伺服器的目錄結構可能會有較大的改變,這時原來寫的絕對路徑就要全部重寫了,比如在我的電腦上的目標檔案路徑是C:/wamp64/www/text.txt,如果我把www資料夾改名為penghuwan呢?原來寫入的路徑引數就失效了。所以我們引入了相對路徑的寫法:
1 2 3 4 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'w'
);
?>
|
• $_SERVER是PHP的超級全域性變數(在程式碼任何地方都可訪問,型別是陣列),通過$_SERVER['DOCUMENT_ROOT']可取到伺服器的預設根目錄
伺服器的預設根目錄可通過php.ini修改(這個可自行百度)
• $_SERVER['DOCUMENT_ROOT']在這裡等同於C:/wamp64/www
本小節的結論:推薦使用相對路徑
<2>fopen的第二個引數為開啟模式
設定開啟模式後,我們就相當於為接下來的讀寫操作設定了許可權:
最基本的幾個模式:
“r”:只能讀取檔案,不能寫入檔案(寫入操作被忽略)
“w”:只能寫入檔案,不能讀取檔案(讀取操作被忽略)
“a”:只追加檔案,與“w”類似,區別是“w”刪除原有的內容,“a”不刪除原有內容,只追加內容
1 2 3 4 5 6 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'w'
);
fwrite(
$fp
,
'在寫模式下寫入'
);
fclose(
$fp
);
?>
|
1 2 3 4 5 6 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'r'
);
fwrite(
$fp
,
'在讀模式下寫入'
);
fclose(
$fp
);
?>
|
很全面,但我覺得這張表對新手有些不太友好,讓人看後不知多雲。 r是隻讀,w是隻寫(原來有的內容全刪除),a是追加(不刪除原有內容),這都好理解。
但r+,w+,和a+的區別和聯絡講的實在太模糊了呀。 這裡我就想詳細地講一下r+,w+,和a+三者的區別和聯絡: 首先r+,w+,和a+都是可讀可寫的,讀取時的方式是一樣的,關鍵在於寫入方式的不同: r+: 從檔案[頭部][覆蓋]原有內容 ([不刪除]原有內容); a+:從檔案[尾部][追加]內容 ([不刪除]原有內容); w+:[完全刪除]原有內容,然後[再新增]新的內容 下面我依次演示上述的結論,首先我們沒有寫入的時候文字是”I am initialized value”(意為我是初始值) • 採用r+模式寫入文字“r+ mode”1 2 3 4 5 6 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'r+'
);
fwrite(
$fp
,
'r+ mode'
);
fclose(
$fp
);
?>
|
1 2 3 4 5 6 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'a+'
);
fwrite(
$fp
,
'a+ mode'
);
fclose(
$fp
);
?>
|
•採用w+模式寫入文字“w+ mode”
基於”I am initialized value”的初始文字我們執行以下程式碼:1 2 3 4 5 6 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'w+'
);
fwrite(
$fp
,
'w+ mode'
);
fclose(
$fp
);
?>
|
1 2 3 4 5 6 7 8 9 10 11 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'r'
);
//開啟檔案
if
(
file_exists
(
"$DOCUMENT_ROOT/text.txt"
)){
//當檔案存在時,才讀取內容
while
(!
feof
(
$fp
)){
//判斷檔案指標是否到達末尾
$c
=
fgetc
(
$fp
);
//每執行一次fgetc(),檔案指標就向後移動一位
echo
$c
;
//輸出獲取到的位元組
}
}
fclose(
$fp
);
//關閉檔案
?>
|
1 2 3 4 5 6 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'r'
);
echo
fgetc
(
$fp
);
//只做一次輸出
close(
$fp
);
?>
|
1 2 3 4 5 6 7 8 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'r'
);
echo
fgetc
(
$fp
);
//連續做三次輸出
echo
fgetc
(
$fp
);
echo
fgetc
(
$fp
);
fclose(
$fp
);
?>
|
2.一次讀取多個位元組 ——通過fread()方法:
1 2 3 4 5 6 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'r'
);
echo
fread
(
$fp
, 3);
//一次輸出三個位元組即一個漢字字元(UTF-8)
fclose(
$fp
);
?>
|
改成:
1 |
echo
fread
(
$fp
, 6);
|
1 2 3 4 5 6 7 8 9 10 11 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
]
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'r'
);
//開啟檔案
if
(
file_exists
(
"$DOCUMENT_ROOT/text.txt"
)){
//當檔案存在時,才讀取內容
while
(!
feof
(
$fp
)){
//判斷檔案指標是否到達末尾
$line
=
fgets
(
$fp
);
//返回一行文字,並將檔案指標移動到下一行頭部
echo
$line
.
"<br/>"
;
//輸出獲取到的一行文字
}
}
fclose(
$fp
);
//關閉檔案
?>
|
fgets()其實還有第二個引數,這個引數規定了每一行能讀取的最大位元組數(注意是位元組數不是字元數): 【注意】在UTF-8編碼下漢字3位元組,字母1位元組 下面我修改上面的一行,程式碼,使獲取的每一行最大字元數為3(也即位元組數為9)
1 |
$line
=
fgets
(
$fp
,10);
|
1 2 3 4 5 6 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'r'
);
fpassthru
(
$fp
);
fclose(
$fp
);
?>
|
1 2 3 4 5 6 7 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
$file_array
= file(
"$DOCUMENT_ROOT/text.txt"
);
//取到檔案陣列
foreach
(
$file_array
as
$value
) {
//輸出陣列元素
echo
$value
.
"<br/>"
;
}
?>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php
$DOCUMENT_ROOT
=
$_SERVER
[
'DOCUMENT_ROOT'
];
function
print_file_pointer(
$fp
){
//定義一個列印檔案指標位置的函式
echo
" <br/>//此時檔案指標的位置:"
;
echo
ftell
(
$fp
).
"<br/>"
;
}
$fp
=
fopen
(
"$DOCUMENT_ROOT/text.txt"
,
'r'
);
echo
fgetc
(
$fp
);
//通過fgetc連續輸出三個位元組
echo
fgetc
(
$fp
);
echo
fgetc
(
$fp
);
print_file_pointer(
$fp
);
//列印此刻檔案指標的位置
echo
fread
(
$fp
,6);
//通過fread一次輸出6位元組
print_file_pointer(
$fp
);
//列印此刻檔案指標的位置
echo
fgets
(
$fp
);
//通過fgets輸出一整行
print_file_pointer(
$fp
);
//列印此刻檔案指標的位置
fpassthru
(
$fp
);
//一次性輸出全部內容
print_file_pointer(
$fp
);
//列印此刻檔案指標的位置
fseek
(
$fp
, 33);
//使檔案指標移動到33位元組位置
|