1. 程式人生 > 實用技巧 >php基礎-10

php基礎-10

PHP日期函式

PHP date() 函式可把時間戳格式化為可讀性更好的日期和時間。

時間戳是一個字元序列,表示一定的事件發生的日期/時間。

語法

string date ( string $format [, int $timestamp ] )
引數 描述
format 必需。規定時間戳的格式。
timestamp 可選。規定時間戳。預設是當前的日期和時間。

date() 函式的第一個必需引數 format 規定了如何格式化日期/時間。

這裡列出了一些可用的字元:

  • d - 代表月中的天 (01 - 31)
  • m - 代表月 (01 - 12)
  • Y - 代表年 (四位數)

如需瞭解 format 引數中可用的所有字元列表,請查閱我們的 PHP Date 參考手冊,date() 函式

可以在字母之間插入其他字元,比如 "/"、"." 或者 "-",這樣就可以增加附加格式了:

<?php
echo date("Y/m/d") . "<br>";
echo date("Y.m.d") . "<br>";
echo date("Y-m-d");
?>
>>>
2016/10/21
2016.10.21
2016-10-21

PHP 包含檔案


PHP include 和 require 語句

在 PHP 中,您可以在伺服器執行 PHP 檔案之前在該檔案中插入一個檔案的內容。

include 和 require 語句用於在執行流中插入寫在其他檔案中的有用的程式碼。

include 和 require 除了處理錯誤的方式不同之外,在其他方面都是相同的:

  • require 生成一個致命錯誤(E_COMPILE_ERROR),在錯誤發生後腳本會停止執行。
  • include 生成一個警告(E_WARNING),在錯誤發生後腳本會繼續執行。

因此,如果您希望繼續執行,並向用戶輸出結果,即使包含檔案已丟失,那麼請使用 include。否則,在框架、CMS 或者複雜的 PHP 應用程式程式設計中,請始終使用 require 向執行流引用關鍵檔案。這有助於提高應用程式的安全性和完整性,在某個關鍵檔案意外丟失的情況下。

包含檔案省去了大量的工作。這意味著您可以為所有網頁建立標準頁頭、頁尾或者選單檔案。然後,在頁頭需要更新時,您只需更新這個頁頭包含檔案即可。

include 'filename';
或者
require 'filename';

1、假設您有一個標準的頁標頭檔案,名為 "header.php"。如需在同一個頁面中引用這個頁標頭檔案,請使用 include/require:

下面這個是.php檔案

<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
</head>
<body>

<?php include 'header.php'; ?>    <!--請使用 include/require-->
<h1>歡迎來到我的主頁!</h1>
<p>一些文字。</p>

</body>
</html>

輸出結果:

2、假設我們有一個在所有頁面中使用的標準選單檔案。

"menu.php":

echo '<a href="/">主頁</a>
<a href="/html">HTML 教程</a>
<a href="/php">PHP 教程</a>';

網站中的所有頁面均應引用該選單檔案。以下是具體的做法:

下面這個是.php檔案

<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
</head>
<body>

<div class="leftmenu">
<?php include 'menu.php'; ?>
</div>
<h1>歡迎來到我的主頁!</h1>
<p>一些文字。</p>

</body>
</html>

PHP 檔案處理

fopen() 函式用於在 PHP 中開啟檔案。


開啟檔案

fopen() 函式用於在 PHP 中開啟檔案。

此函式的第一個引數含有要開啟的檔案的名稱,第二個引數規定了使用哪種模式來開啟檔案:

<html>
<body>
<?php
$file=fopen("welcome.txt","r");
?>
</body>
</html>

檔案可能通過下列模式來開啟:

模式 描述
r 只讀。在檔案的開頭開始。
r+ 讀/寫。在檔案的開頭開始。
w 只寫。開啟並清空檔案的內容;如果檔案不存在,則建立新檔案。
w+ 讀/寫。開啟並清空檔案的內容;如果檔案不存在,則建立新檔案。
a 追加。開啟並向檔案末尾進行寫操作,如果檔案不存在,則建立新檔案。
a+ 讀/追加。通過向檔案末尾寫內容,來保持檔案內容。
x 只寫。建立新檔案。如果檔案已存在,則返回 FALSE 和一個錯誤。
x+ 讀/寫。建立新檔案。如果檔案已存在,則返回 FALSE 和一個錯誤。

註釋:如果 fopen() 函式無法開啟指定檔案,則返回 0 (false)。

例項

如果 fopen() 函式不能開啟指定的檔案,下面的例項會生成一段訊息:

<html>
<body>
<?php
$file=fopen("welcome.txt","r") or exit("Unable to open file!");
?>
</body>
</html>
>>>Warning: fopen(welcome.txt): failed to open stream: No such file or directory in E:\php_enviroment\PHPTutorial\WWW\1.php on line 4
Unable to open file!

關閉檔案

fclose() 函式用於關閉開啟的檔案:

<?php
$file = fopen("test.txt","r");
//執行一些程式碼
fclose($file);
?>

檢測檔案末尾(EOF)

feof() 函式檢測是否已到達檔案末尾(EOF)。

在迴圈遍歷未知長度的資料時,feof() 函式很有用。

注意:在 w 、a 和 x 模式下,您無法讀取開啟的檔案!

if (feof($file)) echo "檔案結尾"; 、// 如果出錯或者檔案指標到了檔案末尾(EOF)則返回 TRUE,否則返回 FALSE。

逐行讀取檔案

fgets() 函式用於從檔案中逐行讀取檔案。

註釋:在呼叫該函式之後,檔案指標會移動到下一行。

例項

下面的例項逐行讀取檔案,直到檔案末尾為止:

<?php
$file = fopen("welcome.txt", "r") or exit("無法開啟檔案!");
// 讀取檔案每一行,直到檔案結尾
while(!feof($file)) 
{
  echo fgets($file). "<br>";
}
fclose($file); // 讀取後必須關閉
?>

welcome.txt

fafeqafqaf
dawdfafaff
`1`2`21333
fqafafqwfq

輸出:

逐字元讀取檔案

fgetc() 函式用於從檔案中逐字元地讀取檔案。

註釋:在呼叫該函式之後,檔案指標會移動到下一個字元。

例項

下面的例項逐字元地讀取檔案,直到檔案末尾為止:

<?php
$file=fopen("welcome.txt","r") or exit("無法開啟檔案!");
while (!feof($file))
{
  echo fgetc($file);
}
fclose($file);
?>
>>>
fafeqafqaf dawdfafaff `1`2`21333 fqafafqwfq

如果開啟一個檔案,檔名為中文,如果系統程式設計和當前文件編碼不一致,會導致檔案找不到無法開啟,解決方法是用 iconv 函式編碼轉換成一致,如下:

$fpath=iconv('UTF-8','GB2312',"題庫.csv");
$file=fopen($fpath,"r") or exit("無法開啟檔案!");
//此處省略相關操作
fclose($file);    

用相對路徑打不開子目錄中的檔案時,可用絕對路徑開啟,如下:

$file=fopen(dirname(__FILE__).'\\files\\tk.csv',"r") or exit("無法開啟檔案!");   
//此處省略相關操作
fclose($file);

檔案上傳

開發中需要上傳圖片、音樂、視訊等等,這種上傳傳遞是二進位制資料。

客戶端上傳檔案

檔案域

<input type="file" name="image">

表單的enctype屬性

​ 預設情況下,表單傳遞是字元流,不能傳遞二進位制流,通過設定表單的enctype屬性傳遞複合資料。

enctype屬性的值有:

  1. multipart/form-data:複合的表單資料(字串/字元,二進位制都可以傳),需要二進位制資料時,比如檔案內容,請使用 "multipart/form-data", 檔案上傳必須設定此值
  2. text/plain:用於向伺服器傳遞無格式的文字資料,主要使用者電子郵件
  3. application/x-www-form-urlencoded:【預設】,表示傳遞的是帶格式的文字資料。
  4. from標籤的 type="file" 屬性規定了應該把輸入作為檔案來處理。舉例來說,當在瀏覽器中預覽時,會看到輸入框旁邊有一個瀏覽按鈕。

單詞

multipart:複合
form-data:表單陣列
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<?php 
if(!empty($_POST)){
	echo "<pre>";
	print_r($_FILES);
}
?>
<form method="post" action="" enctype="multipart/form-data">
	<input type="file" name="face">
	<input type="submit" name="button" value="上傳">
</form>
</body>
</html>

伺服器接受檔案

超全域性變數$_FILES是一個二維陣列,用來儲存客戶端上傳到伺服器的檔案資訊,第一個行引數是表單的 input 標籤的name屬性值, 列引數有5個如下:
1、$_FILES[][‘name’]:上傳的檔名
2、$_FILES[][‘type]:上傳的型別,這個型別是MIME型別(image/jpeg、image/gif、image/png)
3、$_FILES[][‘size’]:檔案的大小,以位元組為單位
4、$_FILES[][‘tmp_name’]:檔案上傳時的臨時檔案
5、$_FILES[][‘error’]:錯誤編碼(值有0、1、2、3、4、6、7)0表示正確

$_FILES[][‘error’]詳解:沒有5

錯誤描述
0 正確
1 檔案大小超過了php.ini中允許的最大值 upload_max_filesize = 2M
2 檔案大小超過了表單允許的最大值
3 只有部分檔案上傳
4 沒有檔案上傳
6 找不到臨時檔案
7 檔案寫入失敗

hidden屬性值:隱藏作用。隱藏域,在頁面上不顯示,但是可以將引數傳遞給下一頁,也可以被本頁的javascript函式獲取。

隱含域主要用於提交表單的時候傳遞動態引數。

注意:MAX_FILE_SIZE必須在檔案域的上面。

只要掌握的錯誤號:0和4

將上傳檔案移動到指定位置

函式:

move_uploaded_file(臨時地址,目標地址)

程式碼

<body>
<?php
if(!empty($_POST)) {
	if($_FILES['face']['error']==0){  //上傳正確
        //檔案上傳
		move_uploaded_file($_FILES['face']['tmp_name'],'./'.$_FILES['face']['name']); // tmp_name臨時檔案的引數,上面講了,第一個引數是name屬性值,在第14行
        // 目標地址:'./'.$_FILES['face']['name'],'./'表示在當前目錄下。即將臨時檔案上傳至當前目錄下 
	}else{
		echo '上傳有誤';
		echo '錯誤碼:'.$_FILES['face']['error'];
	}
}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上傳">
</form>
</body>

小結:上傳的同名的檔案要給覆蓋

與檔案上傳有關的配置

post_max_size = 8M:表單允許的最大值

upload_max_filesize = 2M:允許上傳的檔案大小

upload_tmp_dir =F:\wamp\tmp:指定臨時檔案地址,如果不指定,作業系統會指定。自己可以修改指定

file_uploads = On:是否允許檔案上傳

max_file_uploads = 20:允許同時上傳20個檔案

優化檔案上傳

更改檔名

方法一:通過時間戳做檔名

UNIX 時間戳(timestamp)是 PHP 中關於時間日期一個很重要的概念,它表示從 1970年1月1日 00:00:00 到當前時間的秒數之和。

PHP提供了內建函式 time() 來取得伺服器當前時間的時間戳。

例子:

<?php
echo time();
?>

上面的例子執行後得到的是一串類似這樣的數字:1279115455

我們可以通過 date()等函式將它格式化為我們需要的時間日期格式。

有效的時間戳典型範圍是格林威治時間 1901年12月13日 20:45:54 到 2038年1月19日 03:14:07(此範圍符合 32 位有符號整數的最小值和最大值)。不過從 5.1.0 起,已經克服了年的範圍只能是 1901 到 2038 之間的問題。

提示

  1. time() 得到的總是當前的時間戳,所以是不固定的值
  2. 如果時間戳為負數,則為從1970年1月1日 00:00:00往前推

時間差

時間戳雖然看起來好像不太直觀,但我們在對時間做計算時卻很方便。例如我們要計算時間差,或者對兩個時間做比較等,直接比較數字即可而不必分別去考慮年月日時分秒的換算。而且在效率上時間戳作為整型資料也會快得多。

要求使用者在登陸網站一定時間後失效而需要重新登入的例子:

<?php
$expiration = $time()+2*3600;	//得到當前時間延遲2小時候的時間戳
//失效驗證程式碼略
?>

那麼只需要使用者在活動期間將當前時間戳與 $expiration 進行比較,如果大於 $expiration 則要求使用者重新登入。

頁面執行時間

計算當前頁面執行時間的例子:

<?php
//do something
sleep(3);
//do something
$running_time = time() - $_SERVER['REQUEST_TIME'];
echo '頁面執行時間:',$running_time,' 秒';
?>

執行例子輸出如下:

頁面執行時間:3 秒

$_SERVER[‘REQUEST_TIME’]是 PHP 內建的當前頁面開始執行時的時間戳,在當前頁面執行結束時將

time() - $_SERVER[‘REQUEST_TIME’]得到的就是當前頁面執行的時間(秒):

由於該例子沒有其他更多內容,因此是用 sleep(3) 函式讓頁面執行延遲 3 秒鐘。


//  更改檔名,用當前的時間加個位的隨機數來作為檔名(有可能同一時間剛好有兩個客戶端通過時間戳命名上傳檔案,那兩個檔名字相同會被覆蓋)
<?php
$path='face.stu.jpg';
//echo strrchr($path,'.');	//從最後一個點開始擷取,一直擷取到最後, 到這一步會輸出:.jpg
echo time().rand(100,999).strrchr($path,'.');   // 輸出:1594613333385.jpg(重新整理一次,時間變,資料變,名稱就變了)

方法二:通過uniqid()實現

$path='face.stu.jpg';
echo uniqid().strrchr($path,'.'),'<br>';   //uniqid()會輸出唯一的ID
echo uniqid('goods_').strrchr($path,'.'),'<br>';   //帶有字首
echo uniqid('goods_',true).strrchr($path,'.'),'<br>';  //唯一ID+隨機數

驗證檔案格式

方法一:判斷檔案的副檔名(不能識別檔案偽裝)

操作思路:將檔案的字尾和允許的字尾對比

// strrchr():搜尋 "Shanghai" 在字串中的位置,並返回從該位置到字串結尾的所有字元:
<?php
echo strrchr("I love Shanghai!","Shang");
?>
>>>Shanghai!
<body>
<?php
if(!empty($_POST)) {
	$allow=array('.jpg','.png','.gif');	//允許的副檔名構成的陣列
	$ext=strrchr($_FILES['face']['name'],'.');  //獲取上傳檔案的副檔名
	if(in_array($ext,$allow)) // in_array(),返回值是bool值,字串ext是否在陣列allow中
		echo '允許上傳';
	else
		echo '檔案不合法';
}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上傳">
</form>
</body>

注意:比較副檔名不能防止檔案偽裝。

方法二:通過$_FIELS[]['type']型別(不能識別檔案偽裝)

<body>
<?php
if(!empty($_POST)) {
	$allow=array('image/jpeg','image/png','image/gif');	//允許的類別
	$mime=$_FILES['face']['type'];  //獲取上傳檔案的型別
	if(in_array($mime,$allow))
		echo '允許上傳';
	else
		echo '檔案不合法';
}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上傳">
</form>
</body>

注意:比較$_FIELS[]['type']不能防止檔案偽裝。

方法三:php_fileinfo擴充套件(可以防止檔案偽裝)

​ 在php.ini中開啟fileinfo擴充套件

extension=php_fileinfo.dll

注意:開啟fileinfo擴充套件以後,就可以使用finfo_*的函數了

<body>
<?php
if(!empty($_POST)) {
	//第一步:建立finfo資源
	$info=finfo_open(FILEINFO_MIME_TYPE);
	//var_dump($info);		//resource(2) of type (file_info) 
	//第二步:將finfo資源和上傳的檔案(臨時檔案)做比較
	$mime=finfo_file($info,$_FILES['face']['tmp_name']);
	//第三步,比較是否合法
	$allow=array('image/jpeg','image/png','image/gif');	//允許的類別
	echo in_array($mime,$allow)?'合法':'不合法';
}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上傳">
</form>
</body>

小結:驗證檔案格式有三種方法

1、可以驗證副檔名(不可以防止檔案偽裝)

2、通過$_FILES[]['type']驗證(不可以防止檔案偽裝)

3、通過file_info擴充套件(可以防止檔案偽裝)

優化檔案上傳例題

步驟

第一步:驗證是否有誤

第二步:驗證格式

第三步:驗證大小

第四步:驗證是否是http上傳

第五步:上傳實現

<body>
<?php
/**
*驗證錯誤
*如果有錯,就返回錯誤,如果沒錯,就返回null
*/
function check($file) {
	//1:驗證是否有誤
	if($file['error']!=0){
		switch($file['error']) {
			case 1:
				return '檔案大小超過了php.ini中允許的最大值,最大值是:'.ini_get('upload_max_filesize');
			case 2:
				return '檔案大小超過了表單允許的最大值';
			case 3:
				return '只有部分檔案上傳';
			case 4:
				return '沒有檔案上傳';
			case 6:
				return '找不到臨時檔案';
			case 7:
				return '檔案寫入失敗';
			default:
				return '未知錯誤';
		}
	}
	//2、驗證格式
	$info=finfo_open(FILEINFO_MIME_TYPE);
	$mime=finfo_file($info,$file['tmp_name']);
	$allow=array('image/jpeg','image/png','image/gif');	//允許的類別
	if(!in_array($mime,$allow)){
		return '只能上傳'.implode(',',$allow).'格式';
	}
	//3、驗證大小
	$size=123456789;
	if($file['size']>$size){
		return '檔案大小不能超過'.number_format($size/1024,1).'K';
	}
	//4、驗證是否是http上傳
	if(!is_uploaded_file($file['tmp_name']))
		return '檔案不是HTTP POST上傳的<br>';
	return null;  //沒有錯誤
}

//表單提交
if(!empty($_POST)) {
	//上傳檔案過程中有錯誤就顯示錯誤
	if($error=check($_FILES['face'])){
		echo $error;
	}else{
		//檔案上傳,上傳的檔案儲存到當天的資料夾中
        // date('Y-m-d H:i:s', 1231346);將時間戳變格式,如果沒有第二個引數,預設是將當前的時間戳改變格式
		$foldername=date('Y-m-d H:i:s');		//資料夾名稱,通過date()函式將當前的時間戳的格式變成年-月-日 小時:分鐘:秒的形式
        // date('Y-m-d H:i:s')發現時間輸出不對,需要修改當前版本的php的php.ini檔案裡的date.timezone = PRC(改成Peoples Republic China時區,預設不寫是東一區即英國的格林尼治)
        // 成功顯示2020-07-13 16:08:54
		$folderpath="./uploads/{$foldername}";	//資料夾路徑(事先在WWW資料夾下新建這個uploads資料夾)
		if(!is_dir($folderpath))
			mkdir($folderpath);
		$filename=uniqid('',true).strrchr($_FILES['face']['name'],'.');	//檔名(用當前的時間戳來命名,以便清楚的知道所有檔案的上傳日期,便於區分,當有大量檔案存在,可能夾雜著病毒檔案)
		$filepath="$folderpath/$filename";	//檔案路徑/檔名
		if(move_uploaded_file($_FILES['face']['tmp_name'],$filepath)) // 檔案移動函式:
			echo "上傳成功,路徑是:{$foldername}/{$filename}";
		else
			echo '上傳失敗<br>';
	}
}
?>
<form method="post" action="" enctype='multipart/form-data'>
	<input type="file" name="face">
	<input type="submit" name="button" value="上傳">
</form>
</body>

執行結果

小結:

1、將時間戳轉換格式

echo date('Y-m-d H:i:s',1231346),'<br>';		//將時間戳轉成年-月-日 小時:分鐘:秒
echo date('Y-m-d H:i:s'),'<br>';	//將當前的時間轉成年-月-日 小時:分鐘:秒

2、設定時區(php.ini)

PRC:中華人民共和國

3、PHP的執行可以不需要Apache的參與