zoukankan      html  css  js  c++  java
  • php高级教程

    PHP - 多维数组

    多维数组指的是包含一个或多个数组的数组。

    注释:数组的维度指示您需要选择元素的索引数。

    • 对于二维数组,您需要两个索引来选取元素
    • 对于三维数组,您需要三个索引来选取元素

    PHP - 两维数组

    $cars = array
      (
      array("Volvo",22,18),
      array("BMW",15,13),
      array("Saab",5,2),
      array("Land Rover",17,15)
      );
    如需访问 $cars 数组中的元素,我们必须使用两个索引(行和列):
    <?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>";
    ?>
    或者:
    <?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() 函数用于对日期或时间进行格式化。

    语法

    date(format,timestamp)
    参数描述
    format 必需。规定时间戳的格式。
    timestamp 可选。规定时间戳。默认是当前时间和日期。
    <?php
    echo "今天是 " . date("Y/m/d") . "<br>";
    echo "今天是 " . date("Y.m.d") . "<br>";
    echo "今天是 " . date("Y-m-d") . "<br>";
    echo "今天是 " . date("l");
    ?>

    PHP 提示 - 自动版权年份

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

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

    获得简单的时间

    • 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 © 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" 文件读至结尾:

    fread($myfile,filesize("webdictionary.txt"));

    PHP 关闭文件 - fclose()

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

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

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

    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
    ";
    fwrite($myfile, $txt);
    $txt = "Steve Jobs
    ";
    fwrite($myfile, $txt);
    fclose($myfile);
    ?>

    PHP 覆盖(Overwriting)

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

    <?php
    $myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
    $txt = "Mickey Mouse
    ";
    fwrite($myfile, $txt);
    $txt = "Minnie Mouse
    ";
    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() 函数必须位于 <html> 标签之前。

    语法

    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() 函数必须位于 <html> 标签之前

    存储 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() 函数用于从脚本中发送电子邮件。

    语法

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

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

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

    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 地址发送了一条文本消息:

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

    例子解释:

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

    PHP 防止 E-mail 注入

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

    <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 过滤器来对输入进行验证:

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

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

    die("File not found");

    创建自定义错误处理器

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

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

    语法

    error_function(error_level,error_message,
    error_file,error_line,error_context)
    参数描述
    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 的一部分)

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

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

    Set Error Handler

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

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

    set_error_handler("customError");

    由于我们希望我们的自定义函数来处理所有错误,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 类,并返回不同的错误消息:
    <?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();
     }
    ?>

    例子解释:

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

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

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

    重新抛出异常

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

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

    <?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"。如果有,则再次抛出异常:

    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() 函数可设置处理所有未捕获异常的用户定义函数。

    <?php
    function myException($exception)
    {
    echo "<b>Exception:</b> " , $exception->getMessage();
    }
    
    set_exception_handler('myException');
    
    throw new Exception('Uncaught Exception occurred');
    ?>

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

    Exception: Uncaught Exception occurred

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

    异常的规则

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

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

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

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

    什么是外部数据?

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

    函数和过滤器

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

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

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

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

    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(!filter_var($var, FILTER_VALIDATE_INT, $int_options))
     {
     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 (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL))
      {
      echo "E-Mail is not valid";
      }
     else
      {
      echo "E-Mail is valid";
      }
     }
    ?>

    例子解释:

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

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

    净化输入

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

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

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

    在下面的例子中,输入变量 "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);
     }
    ?>

    例子解释:

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

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

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

    http://www.W3School.com.cn/

    过滤多个输入

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

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

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

    例子解释:

    上面的例子有三个通过 "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 函数。

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

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

    <?php
    function convertSpace($string)
    {
    return str_replace("_", " ", $string);
    }
    
    $string = "Peter_is_a_great_guy!";
    
    echo filter_var($string, FILTER_CALLBACK, array("options"=>"convertSpace"));
    ?>

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

    Peter is a great guy!

    例子解释:

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

    1. 创建一个把 "_" 替换为空格的函数
    2. 调用 filter_var() 函数,它的参数是 FILTER_CALLBACK 过滤器以及包含我们的函数的数组
  • 相关阅读:
    python基础学习笔记(五)
    python进阶学习笔记(一)
    python基础学习笔记(七)
    LoadRunner 技巧之 脚本设计
    python基础学习笔记(八)
    python基础学习笔记(三)
    python基础学习笔记(十一)
    性能测试知多少性能分析与调优的原理
    python基础学习笔记(十)
    python基础学习笔记(六)
  • 原文地址:https://www.cnblogs.com/echohao/p/4713209.html
Copyright © 2011-2022 走看看