Home  >  Article  >  Backend Development  >  PHP advanced tutorial, PHP tutorial_PHP tutorial

PHP advanced tutorial, PHP tutorial_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 09:45:041121browse

php advanced tutorial, php tutorial

PHP - Multidimensional Array

A multidimensional array refers to an array containing one or more arrays.

Note: The dimensions of the array indicate the number of indexes at which you need to select the element.

  • For 2D arrays you need two indices to select elements
  • For three-dimensional arrays, you need three indices to select elements

PHP - Two-dimensional array

$cars = array
  (
  array("Volvo",22,18),
  array("BMW",15,13),
  array("Saab",5,2),
  array("Land Rover",17,15)
  );
To access an element in the $cars array we have to use two indices (row and column):
<?php
echo $cars[0][0].": 库存:".$cars[0][1].", 销量:".$cars[0][2].".<br>";
echo $cars[1][0].": 库存:".$cars[1][1].", 销量:".$cars[1][2].".<br>";
echo $cars[2][0].": 库存:".$cars[2][1].", 销量:".$cars[2][2].".<br>";
echo $cars[3][0].": 库存:".$cars[3][1].", 销量:".$cars[3][2].".<br>";
?>
or:
<?php
for ($row = 0; $row < 4; $row++) {
  echo "<p><b>Row number $row</b></p>";
  echo "<ul>";
  for ($col = 0; $col < 3; $col++) {
    echo "<li>".$cars[$row][$col]."</li>";
  }
  echo "</ul>";
}
?>
PHP date() function is used to format date or time.

Grammar

<span>date(format,timestamp)</span>
参数 描述
format 必需。规定时间戳的格式。
timestamp 可选。规定时间戳。默认是当前时间和日期。
Parameter
Description
format Required. Specifies the format of the timestamp.
timestamp Optional. Specify timestamp. The default is the current time and date.
<span><?php
echo "今天是 " . date("Y/m/d") . "<br>";
echo "今天是 " . date("Y.m.d") . "<br>";
echo "今天是 " . date("Y-m-d") . "<br>";
echo "今天是 " . date("l");
?></span>

PHP 提示 - 自动版权年份

使用 date() 函数在您的网站上自动更新版本年份:

<span>版权所有 2010-<?php echo date("Y")?></span>

获得简单的时间

  • h - 带有首位零的 12 小时小时格式
  • i - 带有首位零的分钟
  • s - 带有首位零的秒(00 -59)
  • a - 小写的午前和午后(am 或 pm)
<?php
echo "现在时间是 " . date("h:i:sa");
?>

获得时区

<?php
date_default_timezone_set("Asia/Shanghai");
echo "当前时间是 " . date("h:i:sa");
?>

通过 PHP mktime() 创建日期

mktime() 函数返回日期的 Unix 时间戳。Unix 时间戳包含 Unix 纪元(1970 年 1 月 1 日 00:00:00 GMT)与指定时间之间的秒数。

语法

mktime(hour,minute,second,month,day,year)
创建日期是 2015-06-10 09:12:31am

通过 PHP strtotime() 用字符串来创建日期

PHP strtotime() 函数用于把人类可读的字符串转换为 Unix 时间。

语法

strtotime(time,now)

PHP 在将字符串转换为日期这方面非常聪明,所以您能够使用各种值:

实例

<?php
$d=strtotime("tomorrow");
echo date("Y-m-d h:i:sa", $d) . "<br>";
$d=strtotime("next Saturday");
echo date("Y-m-d h:i:sa", $d) . "<br>";
$d=strtotime("+3 Months");
echo date("Y-m-d h:i:sa", $d) . "<br>";
?>
<?php
$d1=strtotime("December 31");
$d2=ceil(($d1-time())/60/60/24);
echo "距离十二月三十一日还有:" . $d2 ." 天。";
?>
服务器端包含 (SSI) 用于创建可在多个页面重复使用的函数、页眉、页脚或元素。

PHP include 和 require 语句

通过 include 或 require 语句,可以将 PHP 文件的内容插入另一个 PHP 文件(在服务器执行它之前)。

include 和 require 语句是相同的,除了错误处理方面:

  • require 会生成致命错误(E_COMPILE_ERROR)并停止脚本
  • include 只生成警告(E_WARNING),并且脚本会继续

假设我们有一个名为 "footer.php" 的标准的页脚文件,就像这样:

<?php
echo "<p>Copyright &copy; 2006-" . date("Y") . " W3School.com.cn</p>";
?>

如需在一张页面中引用这个页脚文件,请使用 include 语句:

<html>
<body>
<h1>欢迎访问我们的首页!</h1>
<p>一段文本。</p>
<p>一段文本。</p>
<?php include 'footer.php';?>
</body>
</html>

PHP 操作文件

PHP 拥有的多种函数可供创建、读取、上传以及编辑文件。

注意:请谨慎操作文件!

当您操作文件时必须非常小心。如果您操作失误,可能会造成非常严重的破坏。常见的错误是:

  • 编辑错误的文件
  • 被垃圾数据填满硬盘
  • 意外删除文件内容

PHP readfile() 函数

readfile() 函数读取文件,并把它写入输出缓冲。

假设我们有一个名为 "webdictionary.txt" 的文本文件,存放在服务器上,就像这样:

AJAX = Asynchronous JavaScript and XML
CSS = Cascading Style Sheets
HTML = Hyper Text Markup Language
PHP = PHP Hypertext Preprocessor
SQL = Structured Query Language
SVG = Scalable Vector Graphics
XML = EXtensible Markup Language

读取此文件并写到输出流的 PHP 代码如下(如读取成功则 readfile() 函数返回字节数):

实例

<?php
echo readfile("webdictionary.txt");
?>

PHP Open File - fopen()

fopen() 的第一个参数包含被打开的文件名,第二个参数规定打开文件的模式。如果 fopen() 函数未能打开指定的文件,下面的例子会生成一段消息:
<?php
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
echo fread($myfile,filesize("webdictionary.txt"));
fclose($myfile);
?>

文件会以如下模式之一打开:

模式 描述
r 打开文件为只读。文件指针在文件的开头开始。
w 打开文件为只写。删除文件的内容或创建一个新的文件,如果它不存在。文件指针在文件的开头开始。
a 打开文件为只写。文件中的现有数据会被保留。文件指针在文件结尾开始。创建新的文件,如果文件不存在。
x 创建新文件为只写。返回 FALSE 和错误,如果文件已存在。
r+ 打开文件为读/写、文件指针在文件开头开始。
w+ 打开文件为读/写。删除文件内容或创建新文件,如果它不存在。文件指针在文件开头开始。
a+ 打开文件为读/写。文件中已有的数据会被保留。文件指针在文件结尾开始。创建新文件,如果它不存在。
x+ 创建新文件为读/写。返回 FALSE 和错误,如果文件已存在。

PHP 读取文件 - fread()

fread() 的第一个参数包含待读取文件的文件名,第二个参数规定待读取的最大字节数。

如下 PHP 代码把 "webdictionary.txt" 文件读至结尾:

<span>fread($myfile,filesize("webdictionary.txt"));</span>

PHP 关闭文件 - fclose()

注释:用完文件后把它们全部关闭是一个良好的编程习惯。您并不想打开的文件占用您的服务器资源。

fclose() 需要待关闭文件的名称(或者存有文件名的变量):

<span><?php
$myfile = fopen("webdictionary.txt", "r");
// some code to be executed....
fclose($myfile);
?></span>

PHP 读取单行文件 - fgets()

下例输出 "webdictionary.txt" 文件的首行:
<?php
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
echo fgets($myfile);
fclose($myfile);
?>
注释:调用 fgets() 函数之后,文件指针会移动到下一行。

PHP 检查 End-Of-File - feof()

feof() 对于遍历未知长度的数据很有用。

下例逐行读取 "webdictionary.txt" 文件,直到 end-of-file:

<?php
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
// 输出单行直到 end-of-file
while(!feof($myfile)) {
  echo fgets($myfile) . "<br>";
}
fclose($myfile);
?>

PHP 读取单字符 - fgetc()

下例逐字符读取 "webdictionary.txt" 文件,直到 end-of-file:
<?php
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
// 输出单字符直到 end-of-file
while(!feof($myfile)) {
  echo fgetc($myfile);
}
fclose($myfile);
?>
注释:在调用 fgetc() 函数之后,文件指针会移动到下一个字符。

PHP 创建文件 - fopen()

如果您用 fopen() 打开并不存在的文件,此函数会创建文件,假定文件被打开为写入(w)或增加(a)。

下面的例子创建名为 "testfile.txt" 的新文件。此文件将被创建于 PHP 代码所在的相同目录中:

$myfile = fopen("testfile.txt", "w")

PHP 文件权限

如果您试图运行这段代码时发生错误,请检查您是否有向硬盘写入信息的 PHP 文件访问权限。

PHP 写入文件 - fwrite()

fwrite() 的第一个参数包含要写入的文件的文件名,第二个参数是被写的字符串。
<?php
$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "Bill Gates\n";
fwrite($myfile, $txt);
$txt = "Steve Jobs\n";
fwrite($myfile, $txt);
fclose($myfile);
?>

PHP 覆盖(Overwriting)

如果现在 "newfile.txt" 包含了一些数据,我们可以展示在写入已有文件时发生的的事情。所有已存在的数据会被擦除并以一个新文件开始。

<?php
$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "Mickey Mouse\n";
fwrite($myfile, $txt);
$txt = "Minnie Mouse\n";
fwrite($myfile, $txt);
fclose($myfile);
?>

创建上传脚本

"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"];
  }
?>
  • $_FILES["file"]["name"] - 被上传文件的名称
  • $_FILES["file"]["type"] - 被上传文件的类型
  • $_FILES["file"]["size"] - 被上传文件的大小,以字节计
  • $_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
  • $_FILES["file"]["error"] - 由文件上传导致的错误代码

上传限制

在这个脚本中,我们增加了对文件上传的限制。用户只能上传 .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。

保存被上传的文件

上面的例子在服务器的 PHP 临时文件夹创建了一个被上传文件的临时副本。

这个临时的复制文件会在脚本结束时消失。要保存被上传的文件,我们需要把它拷贝到另外的位置:

<?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";
  }
?>

上面的脚本检测了是否已存在此文件,如果不存在,则把文件拷贝到指定的文件夹。

注释:这个例子把文件保存到了名为 "upload" 的新文件夹。

cookie 常用于识别用户。

setcookie() 函数用于设置 cookie。

注释:setcookie() 函数必须位于 100db36a723c770d327fc0aef2ce13b1 标签之前。

语法

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

在下面的例子中,我们将创建名为 "user" 的 cookie,把为它赋值 "Alex Porter"。我们也规定了此 cookie 在一小时后过期:

<?php 
setcookie("user", "Alex Porter", time()+3600);
?>
注释:在发送 cookie 时,cookie 的值会自动进行 URL 编码,在取回时进行自动解码(为防止 URL 编码,请使用 setrawcookie() 取而代之)。
PHP 的 $_COOKIE 变量用于取回 cookie 的值。

在下面的例子中,我们取回了名为 "user" 的 cookie 的值,并把它显示在了页面上:

<?php
// Print a cookie
echo $_COOKIE["user"];
// A way to view all cookies
print_r($_COOKIE);
?>

在下面的例子中,我们使用 isset() 函数来确认是否已设置了 cookie:

<html>
<body>
<?php
if (isset($_COOKIE["user"]))
  echo "Welcome " . $_COOKIE["user"] . "!<br />";
else
  echo "Welcome guest!<br />";
?>
</body>
</html>
当删除 cookie 时,您应当使过期日期变更为过去的时间点。
<?php 
// set the expiration date to one hour ago
setcookie("user", "", time()-3600);
?>
PHP session 变量用于存储有关用户会话的信息,或更改用户会话的设置。Session 变量保存的信息是单一用户的,并且可供应用程序中的所有页面使用。
不过,会话信息是临时的,在用户离开网站后将被删除。如果您需要永久储存信息,可以把数据存储在数据库中。
Session 的工作机制是:为每个访问者创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,亦或通过 URL 进行传导。

在您把用户信息存储到 PHP session 中之前,首先必须启动会话。

注释:session_start() 函数必须位于 100db36a723c770d327fc0aef2ce13b1 标签之前

存储 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

终结 Session

如果您希望删除某些 session 数据,可以使用 unset() 或 session_destroy() 函数。

unset() 函数用于释放指定的 session 变量:

<?php
unset($_SESSION['views']);
?>

您也可以通过 session_destroy() 函数彻底终结 session:

<?php
session_destroy();
?>

注释:session_destroy() 将重置 session,您将失去所有已存储的 session 数据。

PHP mail() 函数

PHP mail() 函数用于从脚本中发送电子邮件。

语法

<span>mail(to,subject,message,headers,parameters)</span>
参数 描述
to 必需。规定 email 接收者。
subject 必需。规定 email 的主题。注释:该参数不能包含任何新行字符。
message 必需。定义要发送的消息。应使用 LF (\n) 来分隔各行。
headers

可选。规定附加的标题,比如 From、Cc 以及 Bcc。

应当使用 CRLF (\r\n) 分隔附加的标题。

parameters 可选。对邮件发送程序规定额外的参数。
注释:PHP 需要一个已安装且正在运行的邮件系统,以便使邮件函数可用。所用的程序通过在 php.ini 文件中的配置设置进行定义。

PHP 简易 E-Mail

通过 PHP 发送电子邮件的最简单的方式是发送一封文本 email。

在下面的例子中,我们首先声明变量($to, $subject, $message, $from, $headers),然后我们在 mail() 函数中使用这些变量来发送了一封 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,您能够在自己的站点制作一个反馈表单。下面的例子向指定的 e-mail 地址发送了一条文本消息:

<span><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></span>

例子解释:

  1. 首先,检查是否填写了邮件输入框
  2. 如果未填写(比如在页面被首次访问时),输出 HTML 表单
  3. 如果已填写(在表单被填写后),从表单发送邮件
  4. 当点击提交按钮后,重新载入页面,显示邮件发送成功的消息

PHP 防止 E-mail 注入

防止 e-mail 注入的最好方法是对输入进行验证。

<span><html>
<body>
<?php
function spamcheck($field)
  {
  //filter_var() sanitizes the e-mail 
  //address using FILTER_SANITIZE_EMAIL
  $field=filter_var($field, <code>FILTER_SANITIZE_EMAIL</code>);
  
  //filter_var() validates the e-mail
  //address using FILTER_VALIDATE_EMAIL
  if(filter_var($field, <code>FILTER_VALIDATE_EMAIL</code>))
    {
    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></span>

在上面的代码中,我们使用了 PHP 过滤器来对输入进行验证:

  • FILTER_SANITIZE_EMAIL 从字符串中删除电子邮件的非法字符
  • FILTER_VALIDATE_EMAIL 验证电子邮件地址
在 PHP 中,默认的错误处理很简单。一条消息会被发送到浏览器,这条消息带有文件名、行号以及一条描述错误的消息。

基本的错误处理:使用 die() 函数    

die("File not found");

创建自定义错误处理器

创建一个自定义的错误处理器非常简单。我们很简单地创建了一个专用函数,可以在 PHP 中发生错误时调用该函数。

该函数必须有能力处理至少两个参数 (error level 和 error message),但是可以接受最多五个参数(可选的:file, line-number 以及 error context):

语法

<span>error_function(error_level,error_message,
error_file,error_line,error_context)</span>
参数 描述
error_level

必需。为用户定义的错误规定错误报告级别。必须是一个值数。

参见下面的表格:错误报告级别。

error_message 必需。为用户定义的错误规定错误消息。
error_file 可选。规定错误在其中发生的文件名。
error_line 可选。规定错误发生的行号。
error_context 可选。规定一个数组,包含了当错误发生时在用的每个变量以及它们的值。

错误报告级别

常量 描述
2 E_WARNING 非致命的 run-time 错误。不暂停脚本执行。
8 E_NOTICE

Run-time 通知。

脚本发现可能有错误发生,但也可能在脚本正常运行时发生。

256 E_USER_ERROR 致命的用户生成的错误。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_ERROR。
512 E_USER_WARNING 非致命的用户生成的警告。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_WARNING。
1024 E_USER_NOTICE 用户生成的通知。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_NOTICE。
4096 E_RECOVERABLE_ERROR 可捕获的致命错误。类似 E_ERROR,但可被用户定义的处理程序捕获。(参见 set_error_handler())
8191 E_ALL

所有错误和警告,除级别 E_STRICT 以外。

(在 PHP 6.0,E_STRICT 是 E_ALL 的一部分)

<span>function customError($errno, $errstr)
 { 
 echo "<b>Error:</b> [$errno] $errstr<br />";
 echo "Ending Script";
 die();
 }</span>

上面的代码是一个简单的错误处理函数。当它被触发时,它会取得错误级别和错误消息。然后它会输出错误级别和消息,并终止脚本。

Set Error Handler

PHP 的默认错误处理程序是内建的错误处理程序。我们打算把上面的函数改造为脚本运行期间的默认错误处理程序。

可以修改错误处理程序,使其仅应用到某些错误,这样脚本就可以不同的方式来处理不同的错误。不过,在本例中,我们打算针对所有错误来使用我们的自定义错误处理程序:

<span>set_error_handler("customError");</span>

由于我们希望我们的自定义函数来处理所有错误,set_error_handler() 仅需要一个参数,可以添加第二个参数来规定错误级别。

触发错误

在脚本中用户输入数据的位置,当用户的输入无效时触发错误的很有用的。在 PHP 中,这个任务由 trigger_error() 完成。

您可以在脚本中任何位置触发错误,通过添加的第二个参数,您能够规定所触发的错误级别。

可能的错误类型:

  • E_USER_ERROR - 致命的用户生成的 run-time 错误。错误无法恢复。脚本执行被中断。
  • E_USER_WARNING - 非致命的用户生成的 run-time 警告。脚本执行不被中断。
  • E_USER_NOTICE - 默认。用户生成的 run-time 通知。脚本发现了可能的错误,也有可能在脚本运行正常时发生。

错误记录

默认地,根据在 php.ini 中的 error_log 配置,PHP 向服务器的错误记录系统或文件发送错误记录。通过使用 error_log() 函数,您可以向指定的文件或远程目的地发送错误记录。

通过电子邮件向您自己发送错误消息,是一种获得指定错误的通知的好办法。

通过 E-Mail 发送错误消息

在下面的例子中,如果特定的错误发生,我们将发送带有错误消息的电子邮件,并结束脚本:

<?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);
 }
?>

以上代码的输出应该类似这样:

Error: [512] Value must be 1 or below
Webmaster has been notified

接收自以上代码的邮件类似这样:

Error: [512] Value must be 1 or below

这个方法不适合所有的错误。常规错误应当通过使用默认的 PHP 记录系统在服务器上进行记录。

异常(Exception)用于在指定的错误发生时改变脚本的正常流程。

当异常被触发时,通常会发生:

  • 当前代码状态被保存
  • 代码执行被切换到预定义的异常处理器函数
  • 根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本

异常的基本使用

当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块。

如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 "Uncaught Exception" (未捕获异常)的错误消息。

正确的处理程序应当包括:

  1. Try - 使用异常的函数应该位于 "try" 代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
  2. Throw - 这里规定如何触发异常。每一个 "throw" 必须对应至少一个 "catch"
  3. Catch - "catch" 代码块会捕获异常,并创建一个包含异常信息的对象

创建一个自定义的 Exception 类

这个自定义的 exception 类继承了 PHP 的 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();
 }
?>

例子解释:

上面的代码抛出了一个异常,并通过一个自定义的 exception 类来捕获它:

  1. customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。
  2. 创建 errorMessage() 函数。如果 e-mail 地址不合法,则该函数返回一条错误消息
  3. 把 $email 变量设置为不合法的 e-mail 地址字符串
  4. 执行 "try" 代码块,由于 e-mail 地址不合法,因此抛出一个异常
  5. "catch" 代码块捕获异常,并显示错误消息

多个异常

可以使用多个 if..else 代码块,或一个 switch 代码块,或者嵌套多个异常。这些异常能够使用不同的 exception 类,并返回不同的错误消息:
<span><?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();
 }
?></span>

例子解释:

上面的代码测试了两种条件,如何任何条件不成立,则抛出一个异常:

  1. customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。
  2. 创建 errorMessage() 函数。如果 e-mail 地址不合法,则该函数返回一个错误消息。
  3. 执行 "try" 代码块,在第一个条件下,不会抛出异常。
  4. 由于 e-mail 含有字符串 "example",第二个条件会触发异常。
  5. "catch" 代码块会捕获异常,并显示恰当的错误消息

如果没有捕获 customException,紧紧捕获了 base exception,则在那里处理异常。

重新抛出异常

有时,当异常被抛出时,您也许希望以不同于标准的方式对它进行处理。可以在一个 "catch" 代码块中再次抛出异常。

脚本应该对用户隐藏系统错误。对程序员来说,系统错误也许很重要,但是用户对它们并不感兴趣。为了让用户更容易使用,您可以再次抛出带有对用户比较友好的消息的异常:

<span><?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();
 }
?>
</span>

例子解释:

上面的代码检测在邮件地址中是否含有字符串 "example"。如果有,则再次抛出异常:

  1. customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。
  2. 创建 errorMessage() 函数。如果 e-mail 地址不合法,则该函数返回一个错误消息。
  3. 把 $email 变量设置为一个有效的邮件地址,但含有字符串 "example"。
  4. "try" 代码块包含另一个 "try" 代码块,这样就可以再次抛出异常。
  5. 由于 e-mail 包含字符串 "example",因此触发异常。
  6. "catch" 捕获到该异常,并重新抛出 "customException"。
  7. 捕获到 "customException",并显示一条错误消息。

如果在其目前的 "try" 代码块中异常没有被捕获,则它将在更高层级上查找 catch 代码块。

设置顶层异常处理器 (Top Level Exception Handler)

set_exception_handler() 函数可设置处理所有未捕获异常的用户定义函数。

<span><?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}

set_exception_handler('myException');

throw new Exception('Uncaught Exception occurred');
?></span>

以上代码的输出应该类似这样:

<span>Exception: Uncaught Exception occurred</span>

在上面的代码中,不存在 "catch" 代码块,而是触发顶层的异常处理程序。应该使用此函数来捕获所有未被捕获的异常。

异常的规则

  • 需要进行异常处理的代码应该放入 try 代码块内,以便捕获潜在的异常。
  • 每个 try 或 throw 代码块必须至少拥有一个对应的 catch 代码块。
  • 使用多个 catch 代码块可以捕获不同种类的异常。
  • 可以在 try 代码块内的 catch 代码块中再次抛出(re-thrown)异常。

简而言之:如果抛出了异常,就必须捕获它。

PHP 过滤器用于验证和过滤来自非安全来源的数据,比如用户的输入。

您应该始终对外部数据进行过滤!

什么是外部数据?

  • 来自表单的输入数据
  • Cookies
  • 服务器变量
  • 数据库查询结果

函数和过滤器

如需过滤变量,请使用下面的过滤器函数之一:

  • filter_var() - 通过一个指定的过滤器来过滤单一的变量
  • filter_var_array() - 通过相同的或不同的过滤器来过滤多个变量
  • filter_input - 获取一个输入变量,并对它进行过滤
  • filter_input_array - 获取多个输入变量,并通过相同的或不同的过滤器对它们进行过滤

在下面的例子中,我们用 filter_var() 函数验证了一个整数:

<span><?php
$int = 123;

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

Validating 和 Sanitizing

有两种过滤器:

Validating 过滤器:

  • 用于验证用户输入
  • 严格的格式规则(比如 URL 或 E-Mail 验证)
  • 如果成功则返回预期的类型,如果失败则返回 FALSE

Sanitizing 过滤器:

  • 用于允许或禁止字符串中指定的字符
  • 无数据格式规则
  • 始终返回字符串

选项和标志

选项和标志用于向指定的过滤器添加额外的过滤选项。

不同的过滤器有不同的选项和标志。

在下面的例子中,我们用 filter_var() 和 "min_range" 以及 "max_range" 选项验证了一个整数:

<?php
$var=300;

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

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

验证输入

我们需要作的第一件事情是确认是否存在我们正在查找的输入数据。

然后我们用 filter_input() 函数过滤输入的数据。

在下面的例子中,输入变量 "email" 被传到 PHP 页面:

<?php
if(!filter_has_var(INPUT_GET, "email"))
 {
 echo("Input type does not exist");
 }
else
 {
 if (!<code>filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL)</code>)
  {
  echo "E-Mail is not valid";
  }
 else
  {
  echo "E-Mail is valid";
  }
 }
?>

例子解释:

上面的例子有一个通过 "GET" 方法传送的输入变量 (email):

  1. 检测是否存在 "GET" 类型的 "email" 输入变量
  2. 如果存在输入变量,检测它是否是有效的邮件地址

净化输入

让我们试着清理一下从表单传来的 URL。

首先,我们要确认是否存在我们正在查找的输入数据。

然后,我们用 filter_input() 函数来净化输入数据。

在下面的例子中,输入变量 "url" 被传到 PHP 页面:

<span><?php
if(!filter_has_var(INPUT_POST, "url"))
 {
 echo("Input type does not exist");
 }
else
 {
 $url = <code>filter_input(INPUT_POST, "url", FILTER_SANITIZE_URL)</code>;
 }
?></span>

例子解释:

上面的例子有一个通过 "POST" 方法传送的输入变量 (url):

  1. 检测是否存在 "POST" 类型的 "url" 输入变量
  2. 如果存在此输入变量,对其进行净化(删除非法字符),并将其存储在 $url 变量中

假如输入变量类似这样:"http://www.W3非o法ol.com.c字符n/",则净化后的 $url 变量应该是这样的:

<span>http://www.W3School.com.cn/</span>

过滤多个输入

表单通常由多个输入字段组成。为了避免对 filter_var 或 filter_input 重复调用,我们可以使用 filter_var_array 或 the filter_input_array 函数。

在本例中,我们使用 filter_input_array() 函数来过滤三个 GET 变量。接收到的 GET 变量是一个名字、一个年龄以及一个邮件地址:

<span><?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 = <code>filter_input_array(INPUT_GET, $filters)</code>;

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");
 }
?></span>

例子解释:

上面的例子有三个通过 "GET" 方法传送的输入变量 (name, age and email)

  1. 设置一个数组,其中包含了输入变量的名称,以及用于指定的输入变量的过滤器
  2. 调用 filter_input_array 函数,参数包括 GET 输入变量及刚才设置的数组
  3. 检测 $result 变量中的 "age" 和 "email" 变量是否有非法的输入。(如果存在非法输入,)

filter_input_array() 函数的第二个参数可以是数组或单一过滤器的 ID。

如果该参数是单一过滤器的 ID,那么这个指定的过滤器会过滤输入数组中所有的值。

如果该参数是一个数组,那么此数组必须遵循下面的规则:

  • 必须是一个关联数组,其中包含的输入变量是数组的键(比如 "age" 输入变量)
  • 此数组的值必须是过滤器的 ID ,或者是规定了过滤器、标志以及选项的数组

使用 Filter Callback

通过使用 FILTER_CALLBACK 过滤器,可以调用自定义的函数,把它作为一个过滤器来使用。这样,我们就拥有了数据过滤的完全控制权。

您可以创建自己的自定义函数,也可以使用已有的 PHP 函数。

规定您准备用到过滤器函数的方法,与规定选项的方法相同。

在下面的例子中,我们使用了一个自定义的函数把所有 "_" 转换为空格:

<span><?php
function convertSpace($string)
{
return str_replace("_", " ", $string);
}

$string = "Peter_is_a_great_guy!";

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

以上代码的结果是这样的:

<span>Peter is a great guy!</span>

例子解释:

上面的例子把所有 "_" 转换成空格:

  1. 创建一个把 "_" 替换为空格的函数
  2. 调用 filter_var() 函数,它的参数是 FILTER_CALLBACK 过滤器以及包含我们的函数的数组

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1044671.htmlTechArticlephp高级教程,php教程 PHP - 多维数组 多维数组指的是包含一个或多个数组的数组。 注释:数组的维度指示您需要选择元素的索引数。 对于二...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn