說明
這篇是針對之前php知識的補充內容
1、 PHP目錄處理函數
處理文件夾的基本思想如下:
1.讀取某個路徑的時候判斷是否是文件夾
2.是文件夾的話,打開指定文件夾,返回文件目錄的資源變量
3.使用readdir讀取一次目錄中的文件,目錄指針向后偏移一次
4.使用readdir讀取到最后,沒有可讀的文件返回false
5.關閉文件目錄
我們來學習一比常用函數:
函數名 | 功能 |
---|---|
opendir | 打開文件夾,返回操作資源 |
readdir | 讀取文件夾資源 |
is_dir | 判斷是否是文件夾 |
closedir | 關閉文件夾操作資源 |
filetype | 顯示是文件夾還是文件,文件顯示file,文件夾顯示dir |
<?php
//設置打開的目錄是D盤
$dir = "d:/";
//判斷是否是文件夾,是文件夾
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
//讀取到最后返回false,停止循環
while (($file = readdir($dh)) !== false) {
echo "文件名為: $file : 文件的類型是: " . filetype($dir . $file) . "<br />";
}
closedir($dh);
}
}
?>
2、 PHP文件權限設置
chmod 主要是修改文件的的權限
<?php
//修改linux 系統/var/wwwroot/某文件權限為755
chmod("/var/wwwroot/index.html", 755);
chmod("/var/wwwroot/index.html", "u+rwx,go+rx");
chmod("/somedir/somefile", 0755);
?>
3、 PHP文件路徑函數
我們經常會遇到處理文件路徑的情況。
例如:
1.文件后綴需要取出來
2.路徑需要取出名字不取目錄
3.只需要取出路徑名中的目錄路徑
4.或者把網址中的各個部份進行解析取得獨立值
5.甚至是自己組成一個url出來
... ....
很多地方都需要用路徑處理類的函數。
我們把常用的路徑處理函數為大家做了標注,大家對着這個路徑處理函數進行處理即可:
函數名 | 功能 |
---|---|
pathinfo | 返回文件的各個組成部份 |
basename | 返回文件名 |
dirname | 文件目錄部份 |
parse_url | 網址拆解成各部份 |
http_build_query | 生成url 中的query字符串 |
http_build_url | 生成一個url |
<?php
$path_parts = pathinfo('d:/www/index.inc.php');
echo '文件目錄名:'.$path_parts['dirname']."<br />";
echo '文件全名:'.$path_parts['basename']."<br />";
echo '文件擴展名:'.$path_parts['extension']."<br />";
echo '不包含擴展的文件名:'.$path_parts['filename']."<br />";
?>
4、 PHP實現文件留言本
我們來看一下文件結構:
index.php ---展示輸入框和留言內容
write.php ---向message.txt寫入數據
message.txt ---存入聊天內容
index.php文件
<?Php
//設置時區
date_default_timezone_set('PRC');
//讀了內容
@$string = file_get_contents('message.txt');
//如果$string 不為空的時候執行,也就是message.txt中有留言數據
if (!empty($string)) {
//每一段留言有一個分格符,但是最后多出了一個&^。因此,我們要將&^刪掉
$string = rtrim($string, '&^');
//以&^切成數組
$arr = explode('&^', $string);
//將留言內容讀取
foreach ($arr as $value) {
//將用戶名和內容分開
list($username, $content, $time) = explode('$#', $value);
echo '用戶名為<font color="gree">' . $username . '</font>內容為<font color="red">' . $content . '</font>時間為' . date('Y-m-d H:i:s', $time);
echo '<hr />';
}
}
?>
<h1>基於文件的留言本演示</h1>
<form action="write.php" method="post">
用戶名:<input type="text" name="username" /><br />
留言內容:<textarea name="content"></textarea><br />
<input type="submit" value="提交" />
</form>
看了剛剛的展示內容,我們知道文件存儲時:
1.段與段之間進行了分割
2.內容與用戶之前用一個特殊的符號進行了分割
下面我們來寫write.php寫入留言至文件的代碼:
<?php
//追加方式打開文件
$fp=fopen('message.txt','a');
//設置時間
$time=time();
//得到用戶名
$username=trim($_POST['username']);
//得到內容
$content=trim($_POST['content']);
//組合寫入的字符串:內容和用戶之間分開,使用$#
//行與行之間分開,使用&^
$string=$username.'$#'.$content.'$#'.$time.'&^';
//寫入文件
fwrite($fp,$string);
//關閉文件
fclose($fp);
header('location:index.php');
?>
5、PHP文件上傳
在我們日常使用中經常會遇到很多種這樣的情況:
QQ空間里面上傳圖片呀
微信朋友圈上傳圖片
發郵件里面上傳郵件資料附件
認證的時候要求上傳照片或身份證
文件上傳需要注意php.ini文件
配置項 | 功能說明 |
---|---|
file_uploads | on為 開啟文件上傳功能,off為關閉 |
post_max_size | 系統允許的POST傳參的最大值 |
upload_max_filesize | 系統允許的上傳文件的最大值 |
memory_limit | 內存使用限制 |
建議尺寸: file_size(文件大小) < upload_max_filesize < post_max_size < memory_limit
另外,需要注意的是腳本執行時間。
max_execution_time,這什參數的單位為秒。
這個參數是設定腳本的最大執行時間。
也可以根據需求做適當的改變。通常不需要來修改,系統默認值即可。超大文件上傳的時候,可能會涉及到這一項參數的修改。
上傳時間太長了,會超時。如果你將此項參數設為0,則是不限制超時時間,不建議使。
完成了php.ini的相關配置,我們就可以開始試着完成第一次文件上傳了。
1. php文件上傳的步驟
系統返回的錯誤碼詳解
錯誤碼 | 說明 |
---|---|
0 | 無誤,可以繼續進行文件上傳的后續操作。 |
1 | 超出上傳文件的最大限制,upload_max_filesize = 2M php.ini中設置,一般默認為2M。可根據項目中的實際需要來修改 |
2 | 超出了指定的文件大小,根據項目的業務需求指定上傳文件的大小限制 |
3 | 只有部分文件被上傳 |
4 | 文件沒有被上傳 |
6 | 找不到臨時文件夾,可能目錄不存在或沒權限 |
7 | 文件寫入失敗,可能磁盤滿了或沒有權限 |
注:錯誤碼中沒有5。
2. 自定義判斷是否超出文件大小范圍
在開發上傳功能時。我們作為開發人員,除了php.ini中規定的上傳的最大值外。 我們通常還會設定一個值,是業務規定的上傳大小限制。
例如:
新浪微博或者QQ空間只准單張頭像圖片2M。而在上傳圖冊的時候又可以超過2M來上傳。
所以說,它的系統是支持更大文件上傳的。
此處的判斷文件大小,我們用於限制實際業務中我們想要規定的上傳的文件大小。
3. 判斷后綴名和mime類型是否符合
在網絡世界里面也有壞人。他們會把圖片插入病毒,在附件中上傳病毒,他們會在網頁中插入病毒或者黃色圖片。
我們需要對於上傳的文件后綴和mime類型都要進行判斷才可以。
MIME(Multipurpose Internet Mail Extensions)是多用途互聯網郵件擴展類型。是設定某種擴展名的文件用一種應用程序來打開的方式類型,當該擴展名文件被訪問的時候,瀏覽器會自動使用指定應用程序來打開。多用於指定一些客戶端自定義的文件名,以及一些媒體文件打開方式。
在判斷后綴和MIME類型的時候,我們會用到PHP的一個函數in_array(),該函數傳入兩個參數。
第一個參數是要判斷的值;
第二個參數是范圍數組。
我們用這個函數來判斷文件的后綴名和mime類型是否在允許的范圍內。
4. 生成文件名
我們的文件上傳成功了,不會讓它保存原名。因為,有些人在原名中有敏感關鍵詞會違反我國的相關法律和法規。我們可以采用date()、mt_rand()或者unique()生成隨機的文件名。
5. 判斷是否是上傳文件
文件上傳成功時,系統會將上傳的臨時文件上傳到系統的臨時目錄中。產生一個臨時文件。同時會產生臨時文件名。我們需要做的事情是將臨時文件移動到系統的指定目錄中。
而移動前不能瞎移動,或者移動錯了都是不科學的。移動前我們需要使用相關函數判斷上傳的文件是不是臨時文件。
is_uploaded_file()傳入一個參數($_FILES中的緩存文件名),判斷傳入的名稱是不是上傳文件。
6. 移動臨時文件到指定位置
臨時文件是真實的臨時文件,我們需要將其移動到我們的網站目錄下面了。
讓我們網站目錄的數據,其他人可以訪問到。
我們使用:move_uploaded_file()。
這個函數是將上傳文件移動到指定位置,並命名。
傳入兩個參數:
第一個參數是指定移動的上傳文件;
第二個參數是指定的文件夾和名稱拼接的字符串。
7. php文件上傳表單注意事項
**代碼如下:
1.index.html**
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>無標題文檔</title>
</head>
<body>
<h1>上傳文件</h1>
<form action="chuli.php" method="post" enctype="multipart/form-data">
請選擇文件:<input type="file" name="file" /><input type="submit" value="上傳" />
</form>
</body>
</html>
注意事項:
1.form 表單中的參數method 必須為post。若為get是無法進行文件上傳的
2.enctype須為multipart/form-data
2.chuli.php
<?php
//取文件信息
$arr = $_FILES["file"];
//var_dump($arr);
//加限制條件
//1.文件類型
//2.文件大小
//3.保存的文件名不重復
if(($arr["type"]=="image/jpeg" || $arr["type"]=="image/png" ) && $arr["size"]<10241000 )
{
//臨時文件的路徑
$arr["tmp_name"];
//上傳的文件存放的位置
//避免文件重復:
//1.加時間戳.time()加用戶名.$uid或者加.date('YmdHis')
//2.類似網盤,使用文件夾來防止重復
$filename = "./images/".date('YmdHis').$arr["name"];
//保存之前判斷該文件是否存在
if(file_exists($filename))
{
echo "該文件已存在";
}
else
{
//中文名的文件出現問題,所以需要轉換編碼格式
$filename = iconv("UTF-8","gb2312",$filename);
//移動臨時文件到上傳的文件存放的位置(核心代碼)
//括號里:1.臨時文件的路徑, 2.存放的路徑
move_uploaded_file($arr["tmp_name"],$filename);
echo "文件上傳成功";
}
}
else
{
echo "上傳的文件大小或類型不符";
}
?>
6、 PHP錯誤處理
在php.ini配置文件中。我們可以控制php的錯誤顯示狀態。php.ini中有一個專門的配置項:
display_errors
這個選項設置是否將錯誤信息輸出到網頁,或者對用戶隱藏而不顯示。
這個值的狀態為on 或者 off,也可以設值為1 或者0。
display_error的值設為0或者off則不在頁面中顯示錯誤,如果設為1或者on則顯示錯誤信息。
問題:如果沒有修改服務器php.ini的狀態權限怎么辦?
可以使用ini_set。
<?php
ini_set('display_errors' , 0 );
?>
上面的代碼也相當於修改了php.ini中display_errors的值。不過,僅僅在當前php代碼中生效。
問題:想取得php.ini的配置項狀態怎么辦?
可以使用ini_get(參數項) 得到參數的值。
<?php
echo '服務器中display_errors的狀態為' . ini_get('display_errors');
?>
注:修改完php.ini文件,需要重啟服務器
1. php錯誤處理之錯誤報告級別
【掌握級別的錯誤類型】 我們將最常用的錯誤分為了三種:
錯誤類型 | 說明 |
---|---|
E_ERROR | 錯誤,文件直接中斷 |
E_WARNING | 警告,問題比較嚴重。但是還會繼續向下運行 |
E_NOTICE | 提示,有些小問題不會影響到程序。常發生在項目未定義 |
E_PARSE | 編譯時語法解析錯誤。解析錯誤僅僅由分析器產生。 |
E_ALL | 所有的錯誤 |
E_STRICT | 啟用PHP對代碼的修改建議,以確保代碼具有最佳的互操作性和向前兼容性。 |
E_DEPRECATED | 啟用后將會對在未來版本中可能無法正常工作的代碼給出警告。 |
在上面的幾種類型中:
error最嚴重,必須要解決。不然程序無法繼續向下執行
warning也很重要。通也必須要解決。如果明確的,故意的可以不用處理。
notice 你可以不用管。但是在有些公司,項目標准特別高。在高標准要求的項目中也必須要解決。因為,notice會影響到PHP的執行效率。通常發生在函數未定義等。
parse錯誤,是指語法錯寫錯了,必須要解決,代表全部類型的所有錯誤。
1、 在php.ini中error_reporting參數。如若error_reporting參數設置為0。整個PHP引擎發錯誤均不會顯示、輸出、記錄。在下一章將要講到的日志記錄中,也不會記錄。
如果我們想顯示所有錯誤可以寫上:
error_reporting = E_ALL
想要顯示所有錯誤但排除提示,可以將這個參數寫為:
error_reporting = E_ALL & ~ E_NOTICE
顯示所有錯誤,但排除提示、兼容性和未來兼容性。可寫為:
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
2、在有些情況下我們無權限操作php.ini文件,又想要控制error_reporting怎么辦呢?
在運行的xxxx.php文件中開始處,我們可以使用error_reporting()函數達到目標。
<?php
//關閉了所有的錯誤顯示
error_reporting(0);
//顯示所有錯誤
//error_reporting(E_ALL);
//顯示所有錯誤,但不顯示提示
//error_reporting(E_ALL & ~ E_NOTICE);
?>
2. php錯誤處理之錯誤記錄日志
在一些公司里面,有專門的日志收集系統。日志收集系統會在背后默默的幫你收集錯誤、警告、提示。也有些公司沒有專門的日志收集系統,通過文件來服務器當中的運行日志。
其中:PHP的錯誤,警告這些是必須要收信的。那么問題來了——不讓用戶看到,設置好錯誤報告級別好,如何將錯誤收集到日志系統中呢?
這里有需要使用到php.ini的相關配置項。這兩個配置項為:
參數 | 配置項 | 說明 |
---|---|---|
log_errors | on/off | 是否開啟日志記錄 |
log_errors_max_len | 整型,默認1024 | 單行錯誤最大記錄長度 |
error_log | syslog或者指定路徑 | 錯誤日志記錄在什么地方 |
說明:
1.在表格中的log_errors和log_errors_max_len非常好理解。
2.而error_log 指定將錯誤存在什么路徑上。配置項中的syslog可能有點不太好理解。syslog是指系統來記錄。windows系統在電腦的日志收集器里面。linux默認在: /etc/syslog.conf
[擴展] 了解知識點。若Linux系統啟動或修改了日志收集。可能存儲在第三方專用的日志收集服務器中。
此外,PHP還為我們專門准備了一個自定義的錯誤日志函數:
bool error_log ( string $錯誤消息 [, int $錯誤消息類型 = 0 [, string $存儲目標]] )
這個函數可以把錯誤信息發送到web服務器的錯誤日志,或者到一個文件里。
常用的錯誤消息類型
錯誤消息類型 | 說明 |
---|---|
0 | 發送至默認的error_log指定位置 |
1 | 發送到指定的郵件位置 |
3 | 發送至指定的文件位置 |
<?php
//無法連接到數據庫服務器,直接記錄到php.ini 中的error_log指定位置
error_log("無法連接到數據庫服務器服務器");
//可以發送郵件,但是php.ini必須配置過郵件系統
error_log('可以用郵件報告錯誤,讓運維人員半夜起床干活',1 ,'pig@php.cn');
//記錄在指定的位置
error_log("我是一個錯誤喲", 3, "d:/test/my-errors.log");
?>
總結
以上就是今天要講的內容,本文僅僅簡單對之前PHP知識的一些補充,后面可能會用到。