欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

PHP 高級

系統(tǒng) 2337 0
PHP Date()
PHP 的 date() 函數(shù)用于格式化時(shí)間或日期。
PHP Date() 函數(shù)
PHP Date() 函數(shù)可把時(shí)間戳格式化為可讀性更好的日期和時(shí)間。

語法
    
date(format,timestamp)

  



PHP 日期 - 什么是時(shí)間戳(Timestamp)?
時(shí)間戳是自 1970 年 1 月 1 日(00:00:00 GMT)以來的秒數(shù)。它也被稱為 Unix 時(shí)間戳(Unix Timestamp)。
PHP 日期 - 格式化日期
date() 函數(shù)的第一個(gè)參數(shù)規(guī)定了如何格式化日期/時(shí)間。它使用字母來表示日期和時(shí)間的格式。這里列出了一些可用的字母:

d - 月中的天 (01-31)
m - 當(dāng)前月,以數(shù)字計(jì) (01-12)
Y - 當(dāng)前的年(四位數(shù))
您可以在我們的 PHP Date 參考手冊中,找到格式參數(shù)中可以使用的所有字母。

可以在字母之間插入其他字符,比如 "/"、"." 或者 "-",這樣就可以增加附加格式了:
    
<?php
echo date("Y/m/d");
echo "<br />";
echo date("Y.m.d");
echo "<br />";
echo date("Y-m-d");
?>

  

以上代碼的輸出類似這樣:

2006/07/11
2006.07.11
2006-07-11
PHP 日期 - 添加時(shí)間戳
date() 函數(shù)的第二個(gè)參數(shù)規(guī)定了一個(gè)時(shí)間戳。此參數(shù)是可選的。如果您沒有提供時(shí)間戳,當(dāng)前的時(shí)間將被使用。

在我們的例子中,我們將使用 mktime() 函數(shù)為明天創(chuàng)建一個(gè)時(shí)間戳。

mktime() 函數(shù)可為指定的日期返回 Unix 時(shí)間戳。

語法
    
mktime(hour,minute,second,month,day,year,is_dst)

  

如需獲得某一天的時(shí)間戳,我們只要設(shè)置 mktime() 函數(shù)的 day 參數(shù)就可以了:
    
<?php
$tomorrow = mktime(0,0,0,date("m"),date("d")+1,date("Y"));
echo "Tomorrow is ".date("Y/m/d", $tomorrow);
?>

  

以上代碼的輸出類似這樣:

明天是 2011/01/07
PHP 日期 - 參考手冊
如需更多有關(guān) PHP 日期函數(shù)的信息,請?jiān)L問 W3School 為您提供的 PHP Date 參考手冊。

PHP 引用文件
服務(wù)器端引用 (SSI) 用于創(chuàng)建可在多個(gè)頁面重復(fù)使用的函數(shù)、頁眉、頁腳或元素。
服務(wù)器端引用(Server Side Includes)
通過 include() 或 require() 函數(shù),您可以在服務(wù)器執(zhí)行 PHP 文件之前在該文件中插入一個(gè)文件的內(nèi)容。除了它們處理錯(cuò)誤的方式不同之外,這兩個(gè)函數(shù)在其他方面都是相同的。include() 函數(shù)會生成一個(gè)警告(但是腳本會繼續(xù)執(zhí)行),而 require() 函數(shù)會生成一個(gè)致命錯(cuò)誤(fatal error)(在錯(cuò)誤發(fā)生后腳本會停止執(zhí)行)。

這兩個(gè)函數(shù)用于創(chuàng)建可在多個(gè)頁面重復(fù)使用的函數(shù)、頁眉、頁腳或元素。

這會為開發(fā)者節(jié)省大量的時(shí)間。這意味著您可以創(chuàng)建供所有網(wǎng)頁引用的標(biāo)準(zhǔn)頁眉或菜單文件。當(dāng)頁眉需要更新時(shí),您只更新一個(gè)包含文件就可以了,或者當(dāng)您向網(wǎng)站添加一張新頁面時(shí),僅僅需要修改一下菜單文件(而不是更新所有網(wǎng)頁中的鏈接)。
include() 函數(shù)
include() 函數(shù)可獲得指定文件中的所有文本,并把文本拷貝到使用 include 函數(shù)的文件中。

例子 1
假設(shè)您擁有一個(gè)標(biāo)準(zhǔn)的頁眉文件,名為 "header.php"。如需在頁面中引用這個(gè)頁眉文件,請使用 include() 函數(shù),就像這樣:
    
<html>
<body>

<?php include("header.php"); ?>

<h1>Welcome to my home page</h1>

<p>Some text</p>

</body>
</html>

  

例子 2
現(xiàn)在,假設(shè)我們有一個(gè)在所有頁面上使用的標(biāo)準(zhǔn)菜單文件。請看下面這個(gè) "menu.php":
    
<html>
<body>

<a >Home</a> |
<a >About Us</a> | 
<a >Contact Us</a>三個(gè)文件,"default.php"、"about.php" 以及 "contact.php" 都引用了 "menu.php" 文件。這是 "default.php" 中的代碼:

<?php include("menu.php"); ?>

<h1>Welcome to my home page</h1>

<p>Some text</p>

</body>
</html>

  

如果您在瀏覽器中查看 "default.php" 的源代碼,應(yīng)該類似這樣:
    
<html>
<body>

<a href="default.php">Home</a> |
<a href="about.php">About Us</a> | 
<a href="contact.php">Contact Us</a>

<h1>Welcome to my home page</h1>
<p>Some text</p>

</body>
</html>

  

同時(shí),當(dāng)然,我們也將用相同的方法處理 "about.php" 和 "contact.php"。通過使用引用文件,在您需要重命名鏈接、更改鏈接順序或向站點(diǎn)添加另一張網(wǎng)頁時(shí),只要簡單地更新 "menu.php" 文件中的文本即可。
require() 函數(shù)
require() 函數(shù)與 include() 相同,不同的是它對錯(cuò)誤的處理方式。

include() 函數(shù)會生成一個(gè)警告(但是腳本會繼續(xù)執(zhí)行),而 require() 函數(shù)會生成一個(gè)致命錯(cuò)誤(fatal error)(在錯(cuò)誤發(fā)生后腳本會停止執(zhí)行)。

如果在您通過 include() 引用文件時(shí)發(fā)生了錯(cuò)誤,會得到類似下面這樣的錯(cuò)誤消息:

PHP 代碼:
    
<html>
<body>

<?php
include("wrongFile.php");
echo "Hello World!";
?>

</body>
</html>

  

錯(cuò)誤消息:
Warning: include(wrongFile.php) [function.include]:
failed to open stream:
No such file or directory in C:\home\website\test.php on line 5

Warning: include() [function.include]:
Failed opening 'wrongFile.php' for inclusion
(include_path='.;C:\php5\pear')
in C:\home\website\test.php on line 5

Hello World!請注意,echo 語句依然被執(zhí)行了!這是因?yàn)榫娌粫兄鼓_本的執(zhí)行。

現(xiàn)在,讓我們使用 require() 函數(shù)運(yùn)行相同的例子。

PHP 代碼:
    
<html>
<body>

<?php
require("wrongFile.php");
echo "Hello World!";
?>

</body>
</html>

  

錯(cuò)誤消息:
Warning: require(wrongFile.php) [function.require]:
failed to open stream:
No such file or directory in C:\home\website\test.php on line 5

Fatal error: require() [function.require]:
Failed opening required 'wrongFile.php'
(include_path='.;C:\php5\pear')
in C:\home\website\test.php on line 5由于在致命錯(cuò)誤發(fā)生后終止了腳本的執(zhí)行,因此 echo 語句不會執(zhí)行。

正因?yàn)樵谖募淮嬖诨虮恢孛竽_本不會繼續(xù)執(zhí)行,因此我們推薦使用 require() 而不是 include()。

PHP 文件處理
fopen() 函數(shù)用于在 PHP 中打開文件。
打開文件
fopen() 函數(shù)用于在 PHP 中打開文件。

此函數(shù)的第一個(gè)參數(shù)含有要打開的文件的名稱,第二個(gè)參數(shù)規(guī)定了使用哪種模式來打開文件:
    
<html>
<body>

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

</body>
</html>

  

文件可能通過下列模式來打開:
PHP 高級

例子
如果 fopen() 不能打開指定的文件,下面的例子會生成一段消息:
    
<html>
<body>

<?php
$file=fopen("welcome.txt","r") or exit("Unable to open file!");
?>

</body>
</html>

  

關(guān)閉文件
fclose() 函數(shù)用于關(guān)閉打開的文件。
    
<?php
$file = fopen("test.txt","r");

//some code to be executed

fclose($file);
?>

  

檢測 End-of-file
feof() 函數(shù)檢測是否已達(dá)到文件的末端 (EOF)。

在循環(huán)遍歷未知長度的數(shù)據(jù)時(shí),feof() 函數(shù)很有用。

注釋:在 w 、a 以及 x 模式,您無法讀取打開的文件!

if (feof($file)) echo "End of file";逐行讀取文件
fgets() 函數(shù)用于從文件中逐行讀取文件。

注釋:在調(diào)用該函數(shù)之后,文件指針會移動到下一行。

例子
下面的例子逐行讀取文件,直到文件末端為止:
    
<?php
$file = fopen("welcome.txt", "r") or exit("Unable to open file!");
//Output a line of the file until the end is reached
while(!feof($file))
  {
  echo fgets($file). "<br />";
  }
fclose($file);
?>

  

逐字符讀取文件
fgetc() 函數(shù)用于從文件逐字符地讀取文件。

注釋:在調(diào)用該函數(shù)之后,文件指針會移動到下一個(gè)字符。

例子
下面的例子逐字符地讀取文件,直到文件末端為止:
    
<?php
$file=fopen("welcome.txt","r") or exit("Unable to open file!");
while (!feof($file)) 
  { 
  echo fgetc($file); 
  }
fclose($file);
?>

  

PHP Filesystem 參考手冊
如需完整的 PHP 文件系統(tǒng)參考手冊,請?jiān)L問 W3School 提供的 PHP Filesystem 參考手冊。

PHP 文件上傳
創(chuàng)建一個(gè) 文件上傳 表單
允許用戶從表單上傳文件是非常有用的。

請看下面這個(gè)供上傳文件的 HTML 表單:
    
<html>
<body>

<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" /> 
<br />
<input type="submit" name="submit" value="Submit" />
</form>

</body>
</html>

  

請留意如下有關(guān)此表單的信息:

<form> 標(biāo)簽的 enctype 屬性規(guī)定了在提交表單時(shí)要使用哪種內(nèi)容類型。在表單需要二進(jìn)制數(shù)據(jù)時(shí),比如文件內(nèi)容,請使用 "multipart/form-data"。

<input> 標(biāo)簽的 type="file" 屬性規(guī)定了應(yīng)該把輸入作為文件來處理。舉例來說,當(dāng)在瀏覽器中預(yù)覽時(shí),會看到輸入框旁邊有一個(gè)瀏覽按鈕。

注釋:允許用戶上傳文件是一個(gè)巨大的安全風(fēng)險(xiǎn)。請僅僅允許可信的用戶執(zhí)行 文件上傳 操作。
創(chuàng)建上傳腳本
"upload_file.php" 文件含有供上傳文件的代碼:
    
<?php
if ($_FILES["file"]["error"] > 0)
  {
  echo "Error: " . $_FILES["file"]["error"] . "<br />";
  }
else
  {
  echo "Upload: " . $_FILES["file"]["name"] . "<br />";
  echo "Type: " . $_FILES["file"]["type"] . "<br />";
  echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
  echo "Stored in: " . $_FILES["file"]["tmp_name"];
  }
?>

  

通過使用 PHP 的全局?jǐn)?shù)組 $_FILES,你可以從客戶計(jì)算機(jī)向遠(yuǎn)程服務(wù)器上傳文件。

第一個(gè)參數(shù)是表單的 input name,第二個(gè)下標(biāo)可以是 "name", "type", "size", "tmp_name" 或 "error"。就像這樣:

$_FILES["file"]["name"] - 被上傳文件的名稱
$_FILES["file"]["type"] - 被上傳文件的類型
$_FILES["file"]["size"] - 被上傳文件的大小,以字節(jié)計(jì)
$_FILES["file"]["tmp_name"] - 存儲在服務(wù)器的文件的臨時(shí)副本的名稱
$_FILES["file"]["error"] - 由 文件上傳 導(dǎo)致的錯(cuò)誤代碼
這是一種非常簡單 文件上傳 方式?;诎踩矫娴目紤],您應(yīng)當(dāng)增加有關(guān)什么用戶有權(quán)上傳文件的限制。
上傳限制
在這個(gè)腳本中,我們增加了對 文件上傳 的限制。用戶只能上傳 .gif 或 .jpeg 文件,文件大小必須小于 20 kb:
    
<?php

if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 20000))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Error: " . $_FILES["file"]["error"] . "<br />";
    }
  else
    {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
    echo "Stored in: " . $_FILES["file"]["tmp_name"];
    }
  }
else
  {
  echo "Invalid file";
  }

?>

  

注釋:對于 IE,識別 jpg 文件的類型必須是 pjpeg,對于 FireFox,必須是 jpeg。
保存被上傳的文件
上面的例子在服務(wù)器的 PHP 臨時(shí)文件夾創(chuàng)建了一個(gè)被上傳文件的臨時(shí)副本。

這個(gè)臨時(shí)的復(fù)制文件會在腳本結(jié)束時(shí)消失。要保存被上傳的文件,我們需要把它拷貝到另外的位置:
    
<?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 20000))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
    }
  else
    {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
    echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";

    if (file_exists("upload/" . $_FILES["file"]["name"]))
      {
      echo $_FILES["file"]["name"] . " already exists. ";
      }
    else
      {
      move_uploaded_file($_FILES["file"]["tmp_name"],
      "upload/" . $_FILES["file"]["name"]);
      echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
      }
    }
  }
else
  {
  echo "Invalid file";
  }
?>

  

上面的腳本檢測了是否已存在此文件,如果不存在,則把文件拷貝到指定的文件夾。

注釋:這個(gè)例子把文件保存到了名為 "upload" 的新文件夾。

PHP Cookies
cookie 常用于識別用戶。
什么是 Cookie?
cookie 常用于識別用戶。cookie 是服務(wù)器留在用戶計(jì)算機(jī)中的小文件。每當(dāng)相同的計(jì)算機(jī)通過瀏覽器請求頁面時(shí),它同時(shí)會發(fā)送 cookie。通過 PHP,您能夠創(chuàng)建并取回 cookie 的值。
如何創(chuàng)建 cookie?
setcookie() 函數(shù)用于設(shè)置 cookie。

注釋:setcookie() 函數(shù)必須位于 <html> 標(biāo)簽之前。

語法
    
setcookie(name, value, expire, path, domain);

  

例子
在下面的例子中,我們將創(chuàng)建名為 "user" 的 cookie,把為它賦值 "Alex Porter"。我們也規(guī)定了此 cookie 在一小時(shí)后過期:
    
<?php 
setcookie("user", "Alex Porter", time()+3600);
?>

<html>
<body>

</body>
</html>

  

注釋:在發(fā)送 cookie 時(shí),cookie 的值會自動進(jìn)行 URL 編碼,在取回時(shí)進(jìn)行自動解碼(為防止 URL 編碼,請使用 setrawcookie() 取而代之)。
如何取回 Cookie 的值?
PHP 的 $_COOKIE 變量用于取回 cookie 的值。

在下面的例子中,我們?nèi)』亓嗣麨?"user" 的 cookie 的值,并把它顯示在了頁面上:
    
<?php
// Print a cookie
echo $_COOKIE["user"];

// A way to view all cookies
print_r($_COOKIE);
?>

  

在下面的例子中,我們使用 isset() 函數(shù)來確認(rèn)是否已設(shè)置了 cookie:
    
<html>
<body>

<?php
if (isset($_COOKIE["user"]))
  echo "Welcome " . $_COOKIE["user"] . "!<br />";
else
  echo "Welcome guest!<br />";
?>

</body>
</html>

  

如何刪除 cookie?
當(dāng)刪除 cookie 時(shí),您應(yīng)當(dāng)使過期日期變更為過去的時(shí)間點(diǎn)。

刪除的例子:
    
<?php 
// set the expiration date to one hour ago
setcookie("user", "", time()-3600);
?>

  

如果瀏覽器不支持 cookie 該怎么辦?
如果您的應(yīng)用程序涉及不支持 cookie 的瀏覽器,您就不得不采取其他方法在應(yīng)用程序中從一張頁面向另一張頁面?zhèn)鬟f信息。一種方式是從表單傳遞數(shù)據(jù)(有關(guān)表單和用戶輸入的內(nèi)容,稍早前我們已經(jīng)在本教程中介紹過了)。

下面的表單在用戶單擊提交按鈕時(shí)向 "welcome.php" 提交了用戶輸入:
    
<html>
<body>

<form action="welcome.php" method="post">
Name: <input type="text" name="name" />
Age: <input type="text" name="age" />
<input type="submit" />
</form>

</body>
</html>

  

取回 "welcome.php" 中的值,就像這樣:
    
<html>
<body>

Welcome <?php echo $_POST["name"]; ?>.<br />
You are <?php echo $_POST["age"]; ?> years old.

</body>
</html>

  


PHP Sessions
PHP session 變量用于存儲有關(guān)用戶會話的信息,或更改用戶會話的設(shè)置。Session 變量保存的信息是單一用戶的,并且可供應(yīng)用程序中的所有頁面使用。
PHP Session 變量
當(dāng)您運(yùn)行一個(gè)應(yīng)用程序時(shí),您會打開它,做些更改,然后關(guān)閉它。這很像一次會話。計(jì)算機(jī)清楚你是誰。它知道你何時(shí)啟動應(yīng)用程序,并在何時(shí)終止。但是在因特網(wǎng)上,存在一個(gè)問題:服務(wù)器不知道你是誰以及你做什么,這是由于 HTTP 地址不能維持狀態(tài)。

通過在服務(wù)器上存儲用戶信息以便隨后使用,PHP session 解決了這個(gè)問題(比如用戶名稱、購買商品等)。不過,會話信息是臨時(shí)的,在用戶離開網(wǎng)站后將被刪除。如果您需要永久儲存信息,可以把數(shù)據(jù)存儲在數(shù)據(jù)庫中。

Session 的工作機(jī)制是:為每個(gè)訪問者創(chuàng)建一個(gè)唯一的 id (UID),并基于這個(gè) UID 來存儲變量。UID 存儲在 cookie 中,亦或通過 URL 進(jìn)行傳導(dǎo)。
開始 PHP Session
在您把用戶信息存儲到 PHP session 中之前,首先必須啟動會話。

注釋:session_start() 函數(shù)必須位于 <html> 標(biāo)簽之前:
    
<?php session_start(); ?>

<html>
<body>

</body>
</html>

  

上面的代碼會向服務(wù)器注冊用戶的會話,以便您可以開始保存用戶信息,同時(shí)會為用戶會話分配一個(gè) UID。
存儲 Session 變量
存儲和取回 session 變量的正確方法是使用 PHP $_SESSION 變量:
    
<?php
session_start();
// store session data
$_SESSION['views']=1;
?>

<html>
<body>

<?php
//retrieve session data
echo "Pageviews=". $_SESSION['views'];
?>

</body>
</html>

  

輸出:

Pageviews=1在下面的例子中,我們創(chuàng)建了一個(gè)簡單的 page-view 計(jì)數(shù)器。isset() 函數(shù)檢測是否已設(shè)置 "views" 變量。如果已設(shè)置 "views" 變量,我們累加計(jì)數(shù)器。如果 "views" 不存在,則我們創(chuàng)建 "views" 變量,并把它設(shè)置為 1:
    
<?php
session_start();

if(isset($_SESSION['views']))
  $_SESSION['views']=$_SESSION['views']+1;

else
  $_SESSION['views']=1;
echo "Views=". $_SESSION['views'];
?>

  

終結(jié) Session
如果您希望刪除某些 session 數(shù)據(jù),可以使用 unset() 或 session_destroy() 函數(shù)。

unset() 函數(shù)用于釋放指定的 session 變量:
    
<?php
unset($_SESSION['views']);
?>

  

您也可以通過 session_destroy() 函數(shù)徹底終結(jié) session:
    
<?php
session_destroy();
?>

  

注釋:session_destroy() 將重置 session,您將失去所有已存儲的 session 數(shù)據(jù)。

PHP 發(fā)送電子郵件
PHP 允許您從腳本直接發(fā)送電子郵件。
PHP mail() 函數(shù)
PHP mail() 函數(shù)用于從腳本中發(fā)送電子郵件。

語法
    
mail(to,subject,message,headers,parameters)

  

PHP 高級

注釋:PHP 需要一個(gè)已安裝且正在運(yùn)行的郵件系統(tǒng),以便使郵件函數(shù)可用。所用的程序通過在 php.ini 文件中的配置設(shè)置進(jìn)行定義。請?jiān)谖覀兊?PHP Mail 參考手冊閱讀更多內(nèi)容。
PHP 簡易 E-Mail
通過 PHP 發(fā)送電子郵件的最簡單的方式是發(fā)送一封文本 email。

在下面的例子中,我們首先聲明變量($to, $subject, $message, $from, $headers),然后我們在 mail() 函數(shù)中使用這些變量來發(fā)送了一封 e-mail:
    
<?php

$to = "someone@example.com";
$subject = "Test mail";
$message = "Hello! This is a simple email message.";
$from = "someonelse@example.com";
$headers = "From: $from";
mail($to,$subject,$message,$headers);
echo "Mail Sent.";

?>

  

PHP Mail Form
通過 PHP,您能夠在自己的站點(diǎn)制作一個(gè)反饋表單。下面的例子向指定的 e-mail 地址發(fā)送了一條文本消息:
    
<html>
<body>

<?php
if (isset($_REQUEST['email']))
//if "email" is filled out, send email
  {
  //send email
  $email = $_REQUEST['email'] ; 
  $subject = $_REQUEST['subject'] ;
  $message = $_REQUEST['message'] ;
  mail( "someone@example.com", "Subject: $subject",
  $message, "From: $email" );
  echo "Thank you for using our mail form";
  }
else
//if "email" is not filled out, display the form
  {
  echo "<form method='post' action='mailform.php'>
  Email: <input name='email' type='text' /><br />
  Subject: <input name='subject' type='text' /><br />
  Message:<br />
  <textarea name='message' rows='15' cols='40'>
  </textarea><br />
  <input type='submit' />
  </form>";
  }
?>

</body>
</html>

  

例子解釋:
首先,檢查是否填寫了郵件輸入框
如果未填寫(比如在頁面被首次訪問時(shí)),輸出 HTML 表單
如果已填寫(在表單被填寫后),從表單發(fā)送郵件
當(dāng)點(diǎn)擊提交按鈕后,重新載入頁面,顯示郵件發(fā)送成功的消息
PHP Mail 參考手冊
如需更多有關(guān) PHP mail() 函數(shù)的信息,請?jiān)L問我們的 PHP Mail 參考手冊。

PHP 安全的電子郵件
PHP E-mail 注入
首先,請看上一節(jié)中的 PHP 代碼:
    
<html>
<body>

<?php
if (isset($_REQUEST['email']))
//if "email" is filled out, send email
  {
  //send email
  $email = $_REQUEST['email'] ; 
  $subject = $_REQUEST['subject'] ;
  $message = $_REQUEST['message'] ;
  mail("someone@example.com", "Subject: $subject",
  $message, "From: $email" );
  echo "Thank you for using our mail form";
  }
else
//if "email" is not filled out, display the form
  {
  echo "<form method='post' action='mailform.php'>
  Email: <input name='email' type='text' /><br />
  Subject: <input name='subject' type='text' /><br />
  Message:<br />
  <textarea name='message' rows='15' cols='40'>
  </textarea><br />
  <input type='submit' />
  </form>";
  }
?>

</body>
</html>

  

以上代碼存在的問題是,未經(jīng)授權(quán)的用戶可通過輸入表單在郵件頭部插入數(shù)據(jù)。

假如用戶在表單中的輸入框內(nèi)加入這些文本,會出現(xiàn)什么情況呢?

someone@example.com%0ACc:person2@example.com
%0ABcc:person3@example.com,person3@example.com,
anotherperson4@example.com,person5@example.com
%0ABTo:person6@example.com
與往常一樣,mail() 函數(shù)把上面的文本放入郵件頭部,那么現(xiàn)在頭部有了額外的 Cc:, Bcc: 以及 To: 字段。當(dāng)用戶點(diǎn)擊提交按鈕時(shí),這封 e-mail 會被發(fā)送到上面所有的地址!
PHP 防止 E-mail 注入
防止 e-mail 注入的最好方法是對輸入進(jìn)行驗(yàn)證。

下面的代碼與上一節(jié)類似,不過我們已經(jīng)增加了檢測表單中 email 字段的輸入驗(yàn)證程序:
    
<html>
<body>
<?php
function spamcheck($field)
  {
  //filter_var() sanitizes the e-mail 
  //address using FILTER_SANITIZE_EMAIL
  $field=filter_var($field, FILTER_SANITIZE_EMAIL);
  
  //filter_var() validates the e-mail
  //address using FILTER_VALIDATE_EMAIL
  if(filter_var($field, FILTER_VALIDATE_EMAIL))
    {
    return TRUE;
    }
  else
    {
    return FALSE;
    }
  }

if (isset($_REQUEST['email']))
  {//if "email" is filled out, proceed

  //check if the email address is invalid
  $mailcheck = spamcheck($_REQUEST['email']);
  if ($mailcheck==FALSE)
    {
    echo "Invalid input";
    }
  else
    {//send email
    $email = $_REQUEST['email'] ; 
    $subject = $_REQUEST['subject'] ;
    $message = $_REQUEST['message'] ;
    mail("someone@example.com", "Subject: $subject",
    $message, "From: $email" );
    echo "Thank you for using our mail form";
    }
  }
else
  {//if "email" is not filled out, display the form
  echo "<form method='post' action='mailform.php'>
  Email: <input name='email' type='text' /><br />
  Subject: <input name='subject' type='text' /><br />
  Message:<br />
  <textarea name='message' rows='15' cols='40'>
  </textarea><br />
  <input type='submit' />
  </form>";
  }
?>

</body>
</html>

  

在上面的代碼中,我們使用了 PHP 過濾器來對輸入進(jìn)行驗(yàn)證:

FILTER_SANITIZE_EMAIL 從字符串中刪除電子郵件的非法字符
FILTER_VALIDATE_EMAIL 驗(yàn)證電子郵件地址
您可以在我們的 PHP 過濾器這一節(jié)中閱讀更多有關(guān)過濾器的內(nèi)容。

PHP 錯(cuò)誤處理
在 PHP 中,默認(rèn)的錯(cuò)誤處理很簡單。一條消息會被發(fā)送到瀏覽器,這條消息帶有文件名、行號以及一條描述錯(cuò)誤的消息。
PHP 錯(cuò)誤處理
在創(chuàng)建腳本和 web 應(yīng)用程序時(shí),錯(cuò)誤處理是一個(gè)重要的部分。如果您的代碼缺少錯(cuò)誤檢測編碼,那么程序看上去很不專業(yè),也為安全風(fēng)險(xiǎn)敞開了大門。

本教程介紹了 PHP 中一些最為重要的錯(cuò)誤檢測方法。

我們將為您講解不同的錯(cuò)誤處理方法:

簡單的 "die()" 語句
自定義錯(cuò)誤和錯(cuò)誤觸發(fā)器
錯(cuò)誤報(bào)告
基本的錯(cuò)誤處理:使用 die() 函數(shù)
第一個(gè)例子展示了一個(gè)打開文本文件的簡單腳本:
    
<?php
$file=fopen("welcome.txt","r");
?>

  

如果文件不存在,您會獲得類似這樣的錯(cuò)誤:

Warning: fopen(welcome.txt) [function.fopen]: failed to open stream:
No such file or directory in C:\webfolder\test.php on line 2
為了避免用戶獲得類似上面的錯(cuò)誤消息,我們在訪問文件之前檢測該文件是否存在:
    
<?php
if(!file_exists("welcome.txt"))
 {
 die("File not found");
 }
else
 {
 $file=fopen("welcome.txt","r");
 }
?>

  

現(xiàn)在,假如文件不存在,您會得到類似這樣的錯(cuò)誤消息:

File not found
比起之前的代碼,上面的代碼更有效,這是由于它采用了一個(gè)簡單的錯(cuò)誤處理機(jī)制在錯(cuò)誤之后終止了腳本。

不過,簡單地終止腳本并不總是恰當(dāng)?shù)姆绞健W屛覀冄芯恳幌掠糜谔幚礤e(cuò)誤的備選的 PHP 函數(shù)。
創(chuàng)建自定義錯(cuò)誤處理器
創(chuàng)建一個(gè)自定義的錯(cuò)誤處理器非常簡單。我們很簡單地創(chuàng)建了一個(gè)專用函數(shù),可以在 PHP 中發(fā)生錯(cuò)誤時(shí)調(diào)用該函數(shù)。

該函數(shù)必須有能力處理至少兩個(gè)參數(shù) (error level 和 error message),但是可以接受最多五個(gè)參數(shù)(可選的:file, line-number 以及 error context):

語法
    
error_function(error_level,error_message,
error_file,error_line,error_context)

  

PHP 高級

錯(cuò)誤報(bào)告級別
這些錯(cuò)誤報(bào)告級別是錯(cuò)誤處理程序旨在處理的錯(cuò)誤的不同的類型:
PHP 高級

現(xiàn)在,讓我們創(chuàng)建一個(gè)處理錯(cuò)誤的函數(shù):
    
function customError($errno, $errstr)
 { 
 echo "<b>Error:</b> [$errno] $errstr<br />";
 echo "Ending Script";
 die();
 }
 
  

上面的代碼是一個(gè)簡單的錯(cuò)誤處理函數(shù)。當(dāng)它被觸發(fā)時(shí),它會取得錯(cuò)誤級別和錯(cuò)誤消息。然后它會輸出錯(cuò)誤級別和消息,并終止腳本。

現(xiàn)在,我們已經(jīng)創(chuàng)建了一個(gè)錯(cuò)誤處理函數(shù),我們需要確定在何時(shí)觸發(fā)該函數(shù)。
Set Error Handler
PHP 的默認(rèn)錯(cuò)誤處理程序是內(nèi)建的錯(cuò)誤處理程序。我們打算把上面的函數(shù)改造為腳本運(yùn)行期間的默認(rèn)錯(cuò)誤處理程序。

可以修改錯(cuò)誤處理程序,使其僅應(yīng)用到某些錯(cuò)誤,這樣腳本就可以不同的方式來處理不同的錯(cuò)誤。不過,在本例中,我們打算針對所有錯(cuò)誤來使用我們的自定義錯(cuò)誤處理程序:

set_error_handler("customError");
由于我們希望我們的自定義函數(shù)來處理所有錯(cuò)誤,set_error_handler() 僅需要一個(gè)參數(shù),可以添加第二個(gè)參數(shù)來規(guī)定錯(cuò)誤級別。

實(shí)例
通過嘗試輸出不存在的變量,來測試這個(gè)錯(cuò)誤處理程序:
    
<?php
//error handler function
function customError($errno, $errstr)
 { 
 echo "<b>Error:</b> [$errno] $errstr";
 }

//set error handler
set_error_handler("customError");

//trigger error
echo($test);
?>

  

以上代碼的輸出應(yīng)該類似這樣:

Error: [8] Undefined variable: test觸發(fā)錯(cuò)誤
在腳本中用戶輸入數(shù)據(jù)的位置,當(dāng)用戶的輸入無效時(shí)觸發(fā)錯(cuò)誤的很有用的。在 PHP 中,這個(gè)任務(wù)由 trigger_error() 完成。

例子
在本例中,如果 "test" 變量大于 "1",就會發(fā)生錯(cuò)誤:
    
<?php
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below");
}
?>

  

以上代碼的輸出應(yīng)該類似這樣:

Notice: Value must be 1 or below
in C:\webfolder\test.php on line 6
您可以在腳本中任何位置觸發(fā)錯(cuò)誤,通過添加的第二個(gè)參數(shù),您能夠規(guī)定所觸發(fā)的錯(cuò)誤級別。

可能的錯(cuò)誤類型:
E_USER_ERROR - 致命的用戶生成的 run-time 錯(cuò)誤。錯(cuò)誤無法恢復(fù)。腳本執(zhí)行被中斷。
E_USER_WARNING - 非致命的用戶生成的 run-time 警告。腳本執(zhí)行不被中斷。
E_USER_NOTICE - 默認(rèn)。用戶生成的 run-time 通知。腳本發(fā)現(xiàn)了可能的錯(cuò)誤,也有可能在腳本運(yùn)行正常時(shí)發(fā)生。
例子
在本例中,如果 "test" 變量大于 "1",則發(fā)生 E_USER_WARNING 錯(cuò)誤。如果發(fā)生了 E_USER_WARNING,我們將使用我們的自定義錯(cuò)誤處理程序并結(jié)束腳本:
    
<?php
//error handler function
function customError($errno, $errstr)
 { 
 echo "<b>Error:</b> [$errno] $errstr<br />";
 echo "Ending Script";
 die();
 }

//set error handler
set_error_handler("customError",E_USER_WARNING);

//trigger error
$test=2;
if ($test>1)
 {
 trigger_error("Value must be 1 or below",E_USER_WARNING);
 }
?>

  

以上代碼的輸出應(yīng)該類似這樣:

Error: [512] Value must be 1 or below
Ending Script現(xiàn)在,我們已經(jīng)學(xué)習(xí)了如何創(chuàng)建自己的 error,以及如何處罰它們,現(xiàn)在我們研究一下錯(cuò)誤記錄。
錯(cuò)誤記錄
默認(rèn)地,根據(jù)在 php.ini 中的 error_log 配置,PHP 向服務(wù)器的錯(cuò)誤記錄系統(tǒng)或文件發(fā)送錯(cuò)誤記錄。通過使用 error_log() 函數(shù),您可以向指定的文件或遠(yuǎn)程目的地發(fā)送錯(cuò)誤記錄。

通過電子郵件向您自己發(fā)送錯(cuò)誤消息,是一種獲得指定錯(cuò)誤的通知的好辦法。

通過 E-Mail 發(fā)送錯(cuò)誤消息
在下面的例子中,如果特定的錯(cuò)誤發(fā)生,我們將發(fā)送帶有錯(cuò)誤消息的電子郵件,并結(jié)束腳本:
    
<?php
//error handler function
function customError($errno, $errstr)
 { 
 echo "<b>Error:</b> [$errno] $errstr<br />";
 echo "Webmaster has been notified";
 error_log("Error: [$errno] $errstr",1,
 "someone@example.com","From: webmaster@example.com");
}

//set error handler
set_error_handler("customError",E_USER_WARNING);

//trigger error
$test=2;
if ($test>1)
 {
 trigger_error("Value must be 1 or below",E_USER_WARNING);
 }
?>

  

以上代碼的輸出應(yīng)該類似這樣:

Error: [512] Value must be 1 or below
Webmaster has been notified
接收自以上代碼的郵件類似這樣:

Error: [512] Value must be 1 or below
這個(gè)方法不適合所有的錯(cuò)誤。常規(guī)錯(cuò)誤應(yīng)當(dāng)通過使用默認(rèn)的 PHP 記錄系統(tǒng)在服務(wù)器上進(jìn)行記錄。

PHP 異常處理
異常(Exception)用于在指定的錯(cuò)誤發(fā)生時(shí)改變腳本的正常流程。
什么是異常?
PHP 5 提供了一種新的面向?qū)ο蟮腻e(cuò)誤處理方法。

異常處理用于在指定的錯(cuò)誤(異常)情況發(fā)生時(shí)改變腳本的正常流程。這種情況稱為異常。

當(dāng)異常被觸發(fā)時(shí),通常會發(fā)生:

當(dāng)前代碼狀態(tài)被保存
代碼執(zhí)行被切換到預(yù)定義的異常處理器函數(shù)
根據(jù)情況,處理器也許會從保存的代碼狀態(tài)重新開始執(zhí)行代碼,終止腳本執(zhí)行,或從代碼中另外的位置繼續(xù)執(zhí)行腳本
我們將展示不同的錯(cuò)誤處理方法:

異常的基本使用
創(chuàng)建自定義的異常處理器
多個(gè)異常
重新拋出異常
設(shè)置頂層異常處理器
異常的基本使用
當(dāng)異常被拋出時(shí),其后的代碼不會繼續(xù)執(zhí)行,PHP 會嘗試查找匹配的 "catch" 代碼塊。

如果異常沒有被捕獲,而且又沒用使用 set_exception_handler() 作相應(yīng)的處理的話,那么將發(fā)生一個(gè)嚴(yán)重的錯(cuò)誤(致命錯(cuò)誤),并且輸出 "Uncaught Exception" (未捕獲異常)的錯(cuò)誤消息。

讓我們嘗試拋出一個(gè)異常,同時(shí)不去捕獲它:
    
<?php
//create function with an exception
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("Value must be 1 or below");
  }
 return true;
 }

//trigger exception
checkNum(2);
?>

  

上面的代碼會獲得類似這樣的一個(gè)錯(cuò)誤:

Fatal error: Uncaught exception 'Exception'
with message 'Value must be 1 or below' in C:\webfolder\test.php:6
Stack trace: #0 C:\webfolder\test.php(12):
checkNum(28) #1 {main} thrown in C:\webfolder\test.php on line 6Try, throw 和 catch
要避免上面例子出現(xiàn)的錯(cuò)誤,我們需要創(chuàng)建適當(dāng)?shù)拇a來處理異常。

處理處理程序應(yīng)當(dāng)包括:

Try - 使用異常的函數(shù)應(yīng)該位于 "try" 代碼塊內(nèi)。如果沒有觸發(fā)異常,則代碼將照常繼續(xù)執(zhí)行。但是如果異常被觸發(fā),會拋出一個(gè)異常。
Throw - 這里規(guī)定如何觸發(fā)異常。每一個(gè) "throw" 必須對應(yīng)至少一個(gè) "catch"
Catch - "catch" 代碼塊會捕獲異常,并創(chuàng)建一個(gè)包含異常信息的對象
讓我們觸發(fā)一個(gè)異常:
    
<?php
//創(chuàng)建可拋出一個(gè)異常的函數(shù)
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("Value must be 1 or below");
  }
 return true;
 }

//在 "try" 代碼塊中觸發(fā)異常
try
 {
 checkNum(2);
 //If the exception is thrown, this text will not be shown
 echo 'If you see this, the number is 1 or below';
 }

//捕獲異常
catch(Exception $e)
 {
 echo 'Message: ' .$e->getMessage();
 }
?>

  

上面代碼將獲得類似這樣一個(gè)錯(cuò)誤:

Message: Value must be 1 or below 例子解釋:
上面的代碼拋出了一個(gè)異常,并捕獲了它:

創(chuàng)建 checkNum() 函數(shù)。它檢測數(shù)字是否大于 1。如果是,則拋出一個(gè)異常。
在 "try" 代碼塊中調(diào)用 checkNum() 函數(shù)。
checkNum() 函數(shù)中的異常被拋出
"catch" 代碼塊接收到該異常,并創(chuàng)建一個(gè)包含異常信息的對象 ($e)。
通過從這個(gè) exception 對象調(diào)用 $e->getMessage(),輸出來自該異常的錯(cuò)誤消息
不過,為了遵循“每個(gè) throw 必須對應(yīng)一個(gè) catch”的原則,可以設(shè)置一個(gè)頂層的異常處理器來處理漏掉的錯(cuò)誤。
創(chuàng)建一個(gè)自定義的 Exception 類
創(chuàng)建自定義的異常處理程序非常簡單。我們簡單地創(chuàng)建了一個(gè)專門的類,當(dāng) PHP 中發(fā)生異常時(shí),可調(diào)用其函數(shù)。該類必須是 exception 類的一個(gè)擴(kuò)展。

這個(gè)自定義的 exception 類繼承了 PHP 的 exception 類的所有屬性,您可向其添加自定義的函數(shù)。

我們開始創(chuàng)建 exception 類:
    
<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
  .': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
  return $errorMsg;
  }
 }

$email = "someone@example...com";

try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 }

catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

  

這個(gè)新的類是舊的 exception 類的副本,外加 errorMessage() 函數(shù)。正因?yàn)樗桥f類的副本,因此它從舊類繼承了屬性和方法,我們可以使用 exception 類的方法,比如 getLine() 、 getFile() 以及 getMessage()。

例子解釋:
上面的代碼拋出了一個(gè)異常,并通過一個(gè)自定義的 exception 類來捕獲它:

customException() 類是作為舊的 exception 類的一個(gè)擴(kuò)展來創(chuàng)建的。這樣它就繼承了舊類的所有屬性和方法。
創(chuàng)建 errorMessage() 函數(shù)。如果 e-mail 地址不合法,則該函數(shù)返回一條錯(cuò)誤消息
把 $email 變量設(shè)置為不合法的 e-mail 地址字符串
執(zhí)行 "try" 代碼塊,由于 e-mail 地址不合法,因此拋出一個(gè)異常
"catch" 代碼塊捕獲異常,并顯示錯(cuò)誤消息
多個(gè)異常
可以為一段腳本使用多個(gè)異常,來檢測多種情況。

可以使用多個(gè) if..else 代碼塊,或一個(gè) switch 代碼塊,或者嵌套多個(gè)異常。這些異常能夠使用不同的 exception 類,并返回不同的錯(cuò)誤消息:
    
<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}

$email = "someone@example.com";

try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 //check for "example" in mail address
 if(strpos($email, "example") !== FALSE)
  {
  throw new Exception("$email is an example e-mail");
  }
 }

catch (customException $e)
 {
 echo $e->errorMessage();
 }

catch(Exception $e)
 {
 echo $e->getMessage();
 }
?>

  

例子解釋:
上面的代碼測試了兩種條件,如何任何條件不成立,則拋出一個(gè)異常:

customException() 類是作為舊的 exception 類的一個(gè)擴(kuò)展來創(chuàng)建的。這樣它就繼承了舊類的所有屬性和方法。
創(chuàng)建 errorMessage() 函數(shù)。如果 e-mail 地址不合法,則該函數(shù)返回一個(gè)錯(cuò)誤消息。
執(zhí)行 "try" 代碼塊,在第一個(gè)條件下,不會拋出異常。
由于 e-mail 含有字符串 "example",第二個(gè)條件會觸發(fā)異常。
"catch" 代碼塊會捕獲異常,并顯示恰當(dāng)?shù)腻e(cuò)誤消息
如果沒有捕獲 customException,緊緊捕獲了 base exception,則在那里處理異常。
重新拋出異常
有時(shí),當(dāng)異常被拋出時(shí),您也許希望以不同于標(biāo)準(zhǔn)的方式對它進(jìn)行處理??梢栽谝粋€(gè) "catch" 代碼塊中再次拋出異常。

腳本應(yīng)該對用戶隱藏系統(tǒng)錯(cuò)誤。對程序員來說,系統(tǒng)錯(cuò)誤也許很重要,但是用戶對它們并不感興趣。為了讓用戶更容易使用,您可以再次拋出帶有對用戶比較友好的消息的異常:
    
<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = $this->getMessage().' is not a valid E-Mail address.';
  return $errorMsg;
  }
 }

$email = "someone@example.com";

try
 {
 try
  {
  //check for "example" in mail address
  if(strpos($email, "example") !== FALSE)
   {
   //throw exception if email is not valid
   throw new Exception($email);
   }
  }
 catch(Exception $e)
  {
  //re-throw exception
  throw new customException($email);
  }
 }

catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

  

例子解釋:
上面的代碼檢測在郵件地址中是否含有字符串 "example"。如果有,則再次拋出異常:

customException() 類是作為舊的 exception 類的一個(gè)擴(kuò)展來創(chuàng)建的。這樣它就繼承了舊類的所有屬性和方法。
創(chuàng)建 errorMessage() 函數(shù)。如果 e-mail 地址不合法,則該函數(shù)返回一個(gè)錯(cuò)誤消息。
把 $email 變量設(shè)置為一個(gè)有效的郵件地址,但含有字符串 "example"。
"try" 代碼塊包含另一個(gè) "try" 代碼塊,這樣就可以再次拋出異常。
由于 e-mail 包含字符串 "example",因此觸發(fā)異常。
"catch" 捕獲到該異常,并重新拋出 "customException"。
捕獲到 "customException",并顯示一條錯(cuò)誤消息。
如果在其目前的 "try" 代碼塊中異常沒有被捕獲,則它將在更高層級上查找 catch 代碼塊。
設(shè)置頂層異常處理器 (Top Level Exception Handler)
set_exception_handler() 函數(shù)可設(shè)置處理所有未捕獲異常的用戶定義函數(shù)。
    
<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}

set_exception_handler('myException');

throw new Exception('Uncaught Exception occurred');
?>

  

以上代碼的輸出應(yīng)該類似這樣:

Exception: Uncaught Exception occurred在上面的代碼中,不存在 "catch" 代碼塊,而是觸發(fā)頂層的異常處理程序。應(yīng)該使用此函數(shù)來捕獲所有未被捕獲的異常。
異常的規(guī)則
需要進(jìn)行異常處理的代碼應(yīng)該放入 try 代碼塊內(nèi),以便捕獲潛在的異常。
每個(gè) try 或 throw 代碼塊必須至少擁有一個(gè)對應(yīng)的 catch 代碼塊。
使用多個(gè) catch 代碼塊可以捕獲不同種類的異常。
可以在 try 代碼塊內(nèi)的 catch 代碼塊中再次拋出(re-thrown)異常。
簡而言之:如果拋出了異常,就必須捕獲它。

PHP 過濾器(Filter)
PHP 過濾器用于驗(yàn)證和過濾來自非安全來源的數(shù)據(jù),比如用戶的輸入。
什么是 PHP 過濾器?
PHP 過濾器用于驗(yàn)證和過濾來自非安全來源的數(shù)據(jù)。

驗(yàn)證和過濾用戶輸入或自定義數(shù)據(jù)是任何 Web 應(yīng)用程序的重要組成部分。

設(shè)計(jì) PHP 的過濾器擴(kuò)展的目的是使數(shù)據(jù)過濾更輕松快捷。
為什么使用過濾器?
幾乎所有 web 應(yīng)用程序都依賴外部的輸入。這些數(shù)據(jù)通常來自用戶或其他應(yīng)用程序(比如 web 服務(wù))。通過使用過濾器,您能夠確保應(yīng)有程序獲得正確的輸入類型。

您應(yīng)該始終對外部數(shù)據(jù)進(jìn)行過濾!

輸入過濾是最重要的應(yīng)用程序安全課題之一。

什么是外部數(shù)據(jù)?
來自表單的輸入數(shù)據(jù)
Cookies
服務(wù)器變量
數(shù)據(jù)庫查詢結(jié)果
函數(shù)和過濾器
如需過濾變量,請使用下面的過濾器函數(shù)之一:

filter_var() - 通過一個(gè)指定的過濾器來過濾單一的變量
filter_var_array() - 通過相同的或不同的過濾器來過濾多個(gè)變量
filter_input - 獲取一個(gè)輸入變量,并對它進(jìn)行過濾
filter_input_array - 獲取多個(gè)輸入變量,并通過相同的或不同的過濾器對它們進(jìn)行過濾
在下面的例子中,我們用 filter_var() 函數(shù)驗(yàn)證了一個(gè)整數(shù):
    
<?php
$int = 123;

if(!filter_var($int, FILTER_VALIDATE_INT))
 {
 echo("Integer is not valid");
 }
else
 {
 echo("Integer is valid");
 }
?>

  

上面的代碼使用了 "FILTER_VALIDATE_INT" 過濾器來過濾變量。由于這個(gè)整數(shù)是合法的,因此代碼的輸出是:"Integer is valid"。

假如我們嘗試使用一個(gè)非整數(shù)的變量,則輸出是:"Integer is not valid"。

如需完整的函數(shù)和過濾器列表,請?jiān)L問我們的 PHP Filter 參考手冊。
Validating 和 Sanitizing
有兩種過濾器:

Validating 過濾器:
用于驗(yàn)證用戶輸入
嚴(yán)格的格式規(guī)則(比如 URL 或 E-Mail 驗(yàn)證)
返回若成功預(yù)期的類型,否則返回 FALSE
Sanitizing 過濾器:
用于允許或禁止字符串中指定的字符
無數(shù)據(jù)格式規(guī)則
始終返回字符串
選項(xiàng)和標(biāo)志
選項(xiàng)和標(biāo)志用于向指定的過濾器添加額外的過濾選項(xiàng)。

不同的過濾器有不同的選項(xiàng)和標(biāo)志。

在下面的例子中,我們用 filter_var() 和 "min_range" 以及 "max_range" 選項(xiàng)驗(yàn)證了一個(gè)整數(shù):
    
<?php
$var=300;

$int_options = array(
"options"=>array
 (
 "min_range"=>0,
 "max_range"=>256
 )
);

if(!filter_var($var, FILTER_VALIDATE_INT, $int_options))
 {
 echo("Integer is not valid");
 }
else
 {
 echo("Integer is valid");
 }
?>

  

就像上面的代碼一樣,選項(xiàng)必須放入一個(gè)名為 "options" 的相關(guān)數(shù)組中。如果使用標(biāo)志,則不需在數(shù)組內(nèi)。

由于整數(shù)是 "300",它不在指定的氛圍內(nèi),以上代碼的輸出將是 "Integer is not valid"。

如需完整的函數(shù)及過濾器列表,請?jiān)L問 W3School 提供的 PHP Filter 參考手冊。您可以看到每個(gè)過濾器的可用選項(xiàng)和標(biāo)志。
驗(yàn)證輸入
讓我們試著驗(yàn)證來自表單的輸入。

我們需要作的第一件事情是確認(rèn)是否存在我們正在查找的輸入數(shù)據(jù)。

然后我們用 filter_input() 函數(shù)過濾輸入的數(shù)據(jù)。

在下面的例子中,輸入變量 "email" 被傳到 PHP 頁面:
    
<?php
if(!filter_has_var(INPUT_GET, "email"))
 {
 echo("Input type does not exist");
 }
else
 {
 if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL))
  {
  echo "E-Mail is not valid";
  }
 else
  {
  echo "E-Mail is valid";
  }
 }
?>

  

例子解釋:
上面的例子有一個(gè)通過 "GET" 方法傳送的輸入變量 (email):

檢測是否存在 "GET" 類型的 "email" 輸入變量
如果存在輸入變量,檢測它是否是有效的郵件地址
凈化輸入
讓我們試著清理一下從表單傳來的 URL。

首先,我們要確認(rèn)是否存在我們正在查找的輸入數(shù)據(jù)。

然后,我們用 filter_input() 函數(shù)來凈化輸入數(shù)據(jù)。

在下面的例子中,輸入變量 "url" 被傳到 PHP 頁面:
    
<?php
if(!filter_has_var(INPUT_POST, "url"))
 {
 echo("Input type does not exist");
 }
else
 {
 $url = filter_input(INPUT_POST, 
 "url", FILTER_SANITIZE_URL);
 }
?>

  

例子解釋:
上面的例子有一個(gè)通過 "POST" 方法傳送的輸入變量 (url):

檢測是否存在 "POST" 類型的 "url" 輸入變量
如果存在此輸入變量,對其進(jìn)行凈化(刪除非法字符),并將其存儲在 $url 變量中
假如輸入變量類似這樣:"http://www.W3#$%S^%$#ool.com.cn/",則凈化后的 $url 變量應(yīng)該是這樣的:

http://www.W3School.com.cn/過濾多個(gè)輸入
表單通常由多個(gè)輸入字段組成。為了避免對 filter_var 或 filter_input 重復(fù)調(diào)用,我們可以使用 filter_var_array 或 the filter_input_array 函數(shù)。

在本例中,我們使用 filter_input_array() 函數(shù)來過濾三個(gè) GET 變量。接收到的 GET 變量是一個(gè)名稱、一個(gè)年齡以及一個(gè)郵件地址:
    
<?php
$filters = array
 (
 "name" => array
  (
  "filter"=>FILTER_SANITIZE_STRING
  ),
 "age" => array
  (
  "filter"=>FILTER_VALIDATE_INT,
  "options"=>array
   (
   "min_range"=>1,
   "max_range"=>120
   )
  ),
 "email"=> FILTER_VALIDATE_EMAIL,
 );

$result = filter_input_array(INPUT_GET, $filters);

if (!$result["age"])
 {
 echo("Age must be a number between 1 and 120.<br />");
 }
elseif(!$result["email"])
 {
 echo("E-Mail is not valid.<br />");
 }
else
 {
 echo("User input is valid");
 }
?>

  

例子解釋:
上面的例子有三個(gè)通過 "GET" 方法傳送的輸入變量 (name, age and email)

設(shè)置一個(gè)數(shù)組,其中包含了輸入變量的名稱,以及用于指定的輸入變量的過濾器
調(diào)用 filter_input_array 函數(shù),參數(shù)包括 GET 輸入變量及剛才設(shè)置的數(shù)組
檢測 $result 變量中的 "age" 和 "email" 變量是否有非法的輸入。(如果存在非法輸入,)
filter_input_array() 函數(shù)的第二個(gè)參數(shù)可以是數(shù)組或單一過濾器的 ID。

如果該參數(shù)是單一過濾器的 ID,那么這個(gè)指定的過濾器會過濾輸入數(shù)組中所有的值。

如果該參數(shù)是一個(gè)數(shù)組,那么此數(shù)組必須遵循下面的規(guī)則:

必須是一個(gè)關(guān)聯(lián)數(shù)組,其中包含的輸入變量是數(shù)組的鍵(比如 "age" 輸入變量)
此數(shù)組的值必須是過濾器的 ID ,或者是規(guī)定了過濾器、標(biāo)志以及選項(xiàng)的數(shù)組
使用 Filter Callback
通過使用 FILTER_CALLBACK 過濾器,可以調(diào)用自定義的函數(shù),把它作為一個(gè)過濾器來使用。這樣,我們就擁有了數(shù)據(jù)過濾的完全控制權(quán)。

您可以創(chuàng)建自己的自定義函數(shù),也可以使用已有的 PHP 函數(shù)。

規(guī)定您準(zhǔn)備用到過濾器的函數(shù),與規(guī)定選項(xiàng)的方法相同。

在下面的例子中,我們使用了一個(gè)自定義的函數(shù)把所有 "_" 轉(zhuǎn)換為空格:
    
<?php
function convertSpace($string)
{
return str_replace("_", " ", $string);
}

$string = "Peter_is_a_great_guy!";

echo filter_var($string, FILTER_CALLBACK,
array("options"=>"convertSpace"));
?>

  

以上代碼的結(jié)果是這樣的:

Peter is a great guy!例子解釋:
上面的例子把所有 "_" 轉(zhuǎn)換成空格:

創(chuàng)建一個(gè)把 "_" 替換為空格的函數(shù)
調(diào)用 filter_var() 函數(shù),它的參數(shù)是 FILTER_CALLBACK 過濾器以及包含我們的函數(shù)的數(shù)組

PHP 高級


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 草综合 | 国产精品一二三区 | 欧美激情亚洲激情 | 成人在线h| 古代级a毛片免费观看 | 国内精品小视频福利网址 | 亚洲精品九九 | 欧美一区二区三 | 国产第一页在线视频 | 91精品欧美一区二区三区 | 黄色日韩视频 | 91免费观看视频 | 亚洲黄页| 国产在线二区 | 能看的毛片网站 | 国产成人一区二区三区 | 男女交叉视频 | 懂色中文一区二区三区在线视频 | 一级毛片视频免费观看 | 秦浩最新电视剧 | 亚洲综合久久伊人热 | 99精品视频在线视频免费观看 | 91精品网| 俄罗斯厕所偷窥视频 | 亚洲成人网页 | 日日夜夜视频 | 日韩一区二区三区在线 | 国产福利在线视频 | 成人久久免费视频 | 97精品国产高清久久久久蜜芽 | 在线观看欧美成人 | 欧美韩国日本一区 | 高清国产一区二区三区四区五区 | 欧美在线中文字幕 | 精品无人乱码一区二区三区 | 欧美午夜视频 | 日本高清不卡视频 | 成人 日韩| 午夜院线 | www91com国产91 | 小明永久视频免费播放 |