Web_PHP_PHP高级知识;

PHP 高级教程 2014-12-29 10:49
[冷静、沉稳;自信、乐观;自觉自律、自强不息]


一、PHP 多维数组
说明:多维数组指的是包含一个或多个数组的数组。
注意:PHP 能理解两、三、四或五级甚至更多级的多维数组。不过,超过三级深的数组对于大多数人难于管理。
注释:数组的维度指示您需要选择元素的索引数。对于二维数组,您需要两个索引来选取元素。对于三维数组,您需要三个索引来选取元素。
1、两维数组
说明:两维数组是数组的数组(三维数组是数组的数组的数组)。




二、PHP 日期和时间
引言:PHP date() 函数用于对日期或时间进行格式化。
1、Date() 函数
说明:PHP Date() 函数把时间戳格式化为更易读的日期和时间。
语法:date(format,timestamp);
注释:时间戳是一种字符序列,它表示具体事件发生的日期和时间。


2、获得简单的日期
(1)、格式参数
说明:date() 函数的格式参数是必需的,它们规定如何格式化日期或时间。
d - 表示月里的某天(01-31)
m - 表示月(01-12)
Y - 表示年(四位数)
1 - 表示周里的某天
注意:其他字符,比如 "/", "." 或 "-" 也可被插入字符中,以增加其他格式。
(2)、用三种不同方法格式今天的日期
<?php
echo "今天是 " . date("Y/m/d") . "<br>";
echo "今天是 " . date("Y.m.d") . "<br>";
echo "今天是 " . date("Y-m-d") . "<br>";
echo "今天是 " . date("l"); // 今天是 Monday;
?>


3、自动版权年份
说明:使用 date() 函数在您的网站上自动更新版本年份:
实例:© 2010-<?php echo date("Y")?>


4、获得简单的时间
h - 带有首位零的 12 小时小时格式
i - 带有首位零的分钟
s - 带有首位零的秒(00 -59)
a - 小写的午前和午后(am 或 pm)
示例:以指定的格式输出当前时间
<?php
echo "现在时间是 " . date("h:i:sa");
?>
注释:请注意 PHP date() 函数会返回服务器的当前日期/时间!


5、获得时区
说明:如果从代码返回的不是正确的时间,有可能是因为您的服务器位于其他国家或者被设置为不同时区。因此,如果您需要基于具体位置的准确时间,您可以设置要用的时区。
实例:把时区设置为 "Asia/Shanghai",然后以指定格式输出当前时间
<?php
date_default_timezone_set("Asia/Shanghai");
echo "当前时间是 " . date("h:i:sa");
?>


6、通过 PHP mktime() 创建日期
说明:date() 函数中可选的时间戳参数规定时间戳。如果您未规定时间戳,将使用当前日期和时间(正如上例中那样)。mktime() 函数返回日期的 Unix 时间戳。Unix 时间戳包含 Unix 纪元(1970 年 1 月 1 日 00:00:00 GMT)与指定时间之间的秒数。
语法:mktime(hour,minute,second,month,day,year);
实例:创建日期和时间
<?php
$d=mktime(9, 12, 31, 6, 10, 2015);
echo "创建日期是 " . date("Y-m-d h:i:sa", $d); // 创建日期是 2015-06-10 09:12:31am;
?>


7、通过 PHP strtotime() 用字符串来创建日期
说明:PHP strtotime() 函数用于把人类可读的字符串转换为 Unix 时间。
语法:strtotime(time,now);
实例:创建日期时间
<?php
$d=strtotime("10:38pm April 15 2015");
echo "创建日期是 " . date("Y-m-d h:i:sa", $d);
?>
<?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>";
?>
注意:不过,strtotime() 并不完美,所以请记得检查放入其中的字符串。




三、PHP Include 文件 2014/12/30 0:05
引言:服务器端包含 (SSI) 用于创建可在多个页面重复使用的函数、页眉、页脚或元素。
说明:include (或 require)语句会获取指定文件中存在的所有文本/代码/标记,并复制到使用 include 语句的文件中。包含文件很有用,如果您需要在网站的多张页面上引用相同的 PHP、HTML 或文本的话。
1、PHP include 和 require 语句
前言:通过 include 或 require 语句,可以将 PHP 文件的内容插入另一个 PHP 文件(在服务器执行它之前)。
(1)、两者区别:include 和 require 语句是相同的,除错误处理方面
>require 会生成致命错误(E_COMPILE_ERROR)并停止脚本;
>include 只生成警告(E_WARNING),并且脚本会继续;
注意:如果您希望继续执行,并向用户输出结果,即使包含文件已丢失,那么请使用 include。否则,在框架、CMS 或者复杂的 PHP 应用程序编程中,请始终使用 require 向执行流引用关键文件。这有助于提高应用程序的安全性和完整性,在某个关键文件意外丢失的情况下。
意义:包含文件省去大量的工作。这意味着您可以为所有页面创建标准页头、页脚或者菜单文件。然后,在页头需要更新时,您只需更新这个页头包含文件即可。
(2)、语法
include 'filename';或 require 'filename';


2、include 实例
->footer.php页脚文件
<?php
echo "<p>Copyright © 2006-" . date("Y") . " 2WorkRoom3</p>";
?>
->include 引用代码
<html>
<body>
<h1>欢迎访问我们的首页!</h1>
<p>一段文本。</p>
<p>一段文本。</p>
<?php include 'footer.php';?>
</body>
</html>


3、include vs require
前言:require 语句同样用于向 PHP 代码中引用文件。不过,include 与 require 有一个巨大的差异:如果用 include 语句引用某个文件并且 PHP 无法找到它,脚本会继续执行:
注释:当文件被应用程序请求时,请在此时使用 require;当文件不是必需的,且应用程序在文件未找到时应该继续运行时,请在此时使用 include;




四、PHP 文件处理
1、PHP 操作文件
前言:PHP 拥有的多种函数可供创建、读取、上传以及编辑文件。


2、常见错误
前言:当您操作文件时必须非常小心。如果您操作失误,可能会造成非常严重的破坏。
>编辑错误的文件;
>被垃圾数据填满硬盘;
>意外删除文件内容;


3、readfile()函数
前言: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
echo readfile("webdictionary.txt"); // 输出:AJAX = Asynchronous JavaScript and XML ... XML = EXtensible Markup Language236;
?>
注释:如果您想做的所有事情就是打开一个文件并读取器内容,那么 readfile() 函数很有用。




五、PHP 文件打开/读取/关闭
引言:如何在服务器上打开、读取以及关闭文件。


1、fopen()_打开文件
前言:打开文件的更好的方法是通过 fopen() 函数。此函数为您提供比 readfile() 函数更多的选项。
实例:打开、读取、关闭(fopen() 的第一个参数包含被打开的文件名,第二个参数规定打开文件的模式)
<?php
$myfile = fopen("webdictionary.txt", "r") or die("Unable to open file!");
echo fread($myfile,filesize("webdictionary.txt"));
fclose($myfile);
?>
(1)、文件打开模式
r 打开文件为只读。文件指针在文件的开头开始。
w 打开文件为只写。删除文件的内容或创建一个新的文件,如果它不存在。文件指针在文件的开头开始。
a 打开文件为只写。文件中的现有数据会被保留。文件指针在文件结尾开始。创建新的文件,如果文件不存在。
x 创建新文件为只写。返回 FALSE 和错误,如果文件已存在。
r+ 打开文件为读/写、文件指针在文件开头开始。
w+ 打开文件为读/写。删除文件内容或创建新文件,如果它不存在。文件指针在文件开头开始。
a+ 打开文件为读/写。文件中已有的数据会被保留。文件指针在文件结尾开始。创建新文件,如果它不存在。
x+ 创建新文件为读/写。返回 FALSE 和错误,如果文件已存在。


2、fread()_读取文件
前言:fread() 函数读取打开的文件。fread() 的第一个参数包含待读取文件的文件名,第二个参数规定待读取的最大字节数。
实例:PHP 代码把 "webdictionary.txt" 文件读至结尾
fread($myfile,filesize("webdictionary.txt"));


3、fclose()_关闭文件
前言:fclose() 函数用于关闭打开的文件。
注释:用完文件后把它们全部关闭是一个良好的编程习惯。您并不想打开的文件占用您的服务器资源吧。
语法:fclose() 需要待关闭文件的名称(或者存有文件名的变量)
<?php
$myfile = fopen("webdictionary.txt", "r");
// some code to be executed....
fclose($myfile);
?>


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


5、feof()_检查 End-Of-File
前言:feof() 函数检查是否已到达 "end-of-file" (EOF)。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);
?>


6、fgetc()_读取单字符
前言: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 文件创建/写入
引言:如何在服务器上创建并写入文件。
1、fopen()_创建文件(当然,也能打开文件,这取决于第二个模式参数)
前言:fopen() 函数也用于创建文件。也许有点混乱,但是在 PHP 中,创建文件所用的函数与打开文件的相同。如果您用 fopen() 打开并不存在的文件,此函数会创建文件,假定文件被打开为写入(w)或增加(a)。
实例:创建名为 "testfile.txt" 的新文件
$myfile = fopen("testfile.txt", "w");


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


3、fwrite()_写入文件
前言:fwrite() 函数用于写入文件。fwrite() 的第一个参数包含要写入的文件的文件名,第二个参数是被写的字符串。
实例:把姓名写入名为 "newfile.txt" 的新文件中
<?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);
?>
注意:使用w模式创建文件,如果该文件已经存在,所有已存在的数据会被擦除并以一个新文件开始。




七、文件上传
引言:通过 PHP,可以把文件上传到服务器。
1、文件上传表单
前言:允许用户从表单上传文件是非常有用的。
表单:(允许用户上传文件是一个巨大的安全风险。请仅仅允许可信的用户执行文件上传操作)
<html>
<body>
// <form> enctype属性规定在提交表单时要使用哪种内容类型。在表单需要二进制数据时,比如文件内容,请使用 "multipart/form-data"。
<form action="upload_file.php" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
// <input> type="file"属性规定应该把输入作为文件来处理。举例来说,当在浏览器中预览时,会看到输入框旁边有一个浏览按钮。
<input type="file" name="file" id="file" /> 
<br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>


2、创建上传脚本
前言:"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"];
}
?>
(1)、全局数组 $_FILES
前言:通过使用 PHP 的全局数组 $_FILES,你可以从客户计算机向远程服务器上传文件。
参数:第一个参数是表单的 input name,第二个下标可以是 "name", "type", "size", "tmp_name" 或 "error"。
$_FILES["file"]["name"] - 被上传文件的名称
$_FILES["file"]["type"] - 被上传文件的类型
$_FILES["file"]["size"] - 被上传文件的大小,以字节计
$_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"] - 由文件上传导致的错误代码


3、上传限制
// 只能上传 .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。


4、保存上传文件
前言:上传文件的临时副本,这个临时的复制文件会在脚本结束时消失。要保存被上传的文件,需要把它拷贝到另外的位置;
<?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";
  }
?>


八、PHP Cookies
引言:cookie 常用于识别用户。


1、什么是 Cookie?
cookie 常用于识别用户。cookie 是服务器留在用户计算机中的小文件。每当相同的计算机通过浏览器请求页面时,它同时会发送 cookie。通过 PHP,您能够创建并取回 cookie 的值。


2、如何创建 cookie?
前言:setcookie() 函数用于设置 cookie。
注释:setcookie() 函数必须位于 <html> 标签之前。
语法:setcookie(name, value, expire, path, domain);
(1)、实例_创建名为 "user" 的 cookie
<?php 
setcookie("user", "cyb_23", time()+3600); // 此cookie一小时后过期;
?>
<html></html>
注释:在发送 cookie 时,cookie 的值会自动进行 URL 编码,在取回时进行自动解码(为防止 URL 编码,请使用 setrawcookie() 取而代之)。


3、如何取回 Cookie 的值?
前言:PHP 的 $_COOKIE 变量用于取回 cookie 的值。
实例:取得"user" 的 cookie值
<?php
// Print a cookie
echo $_COOKIE["user"];
// A way to view all cookies
print_r($_COOKIE);
?>
(1)确认是否设置:isset() 函数用来确认是否已设置cookie;
<html>
<body>
<?php
if (isset($_COOKIE["user"]))
 echo "Welcome " . $_COOKIE["user"] . "!<br />";
else
 echo "Welcome guest!<br />";
?>
</body>
</html>


4、如何删除 cookie?
前言:当删除 cookie 时,您应当使过期日期变更为过去的时间点。
<?php 
// set the expiration date to one hour ago
setcookie("user", "", time()-3600);
?>


5、如果浏览器不支持 cookie 该怎么办?
前言:如果您的应用程序涉及不支持 cookie 的浏览器,您就不得不采取其他方法在应用程序中从一张页面向另一张页面传递信息。一种方式是从表单传递数据(有关表单和用户输入的内容,稍早前我们已经在本教程中介绍过)。




九、PHP Sessions
引言;PHP session 变量用于存储有关用户会话的信息,或更改用户会话的设置。Session 变量保存的信息是单一用户的,并且可供应用程序中的所有页面使用。
1、Session 变量
当您运行一个应用程序时,您会打开它,做些更改,然后关闭它。这很像一次会话。计算机清楚你是谁。它知道你何时启动应用程序,并在何时终止。但是在因特网上,存在一个问题:服务器不知道你是谁以及你做什么,这是由于 HTTP 地址不能维持状态。
通过在服务器上存储用户信息以便随后使用,PHP session 解决了这个问题(比如用户名称、购买商品等)。不过,会话信息是临时的,在用户离开网站后将被删除。如果您需要永久储存信息,可以把数据存储在数据库中。
Session 的工作机制是:为每个访问者创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,亦或通过 URL 进行传导。


2、Session创建_启动会话
前言:在您把用户信息存储到 PHP session 中之前,首先必须启动会话。
注释:session_start() 函数必须位于 <html> 标签之前
解说:上面的代码会向服务器注册用户的会话,以便您可以开始保存用户信息,同时会为用户会话分配一个 UID。


3、存储 Session 变量
说明:存储和取回 session 变量的正确方法是使用 PHP $_SESSION 变量;
实例:计时器
//如果已设置 "views" 变量,则累加计数器。如果 "views" 不存在,则创建 "views" 变量,并把它设置为 1;
<?php
session_start();
if(isset($_SESSION['views']))
 $_SESSION['views']=$_SESSION['views']+1;
else
 $_SESSION['views']=1;
echo "Views=". $_SESSION['views'];
?>


4、终结 Session
前言:如果您希望删除某些 session 数据,可以使用 unset() 或 session_destroy() 函数。
(1)、unset() 函数_用于释放指定的 session 变量;
<?php
unset($_SESSION['views']);
?>
(2)、session_destroy()_函数彻底终结session;
<?php
session_destroy();
?>
注释:session_destroy() 将重置 session,您将失去所有已存储的 session 数据。




十、PHP 发送电子邮件
引言:PHP 允许您从脚本直接发送电子邮件。


1、mail() 函数
前言:PHP mail() 函数用于从脚本中发送电子邮件。要使邮件函数可用,PHP 需要已安装且正在运行的邮件系统。要使用的程序是由 php.ini 文件中的配置设置定义的。
(1)、语法
说明:mail() 函数允许您从脚本中直接发送电子邮件。如果邮件的投递被成功地接收,则返回 true,否则返回 false。
mail(to,subject,message,headers,parameters);
to 必需,email 接收者。
subject 必需,email 主题。注释:该参数不能包含任何新行字符。
message 必需。定义要发送的消息。应使用 LF[line feed] (\n) 来分隔各行。
headers 可选。附加标题,比如 From、Cc 以及 Bcc。应当使用 CRLF (\r\n) 分隔附加的标题。
parameters 可选。对邮件发送程序规定额外的参数。
注释:PHP 需要一个已安装且正在运行的邮件系统,以便使邮件函数可用。所用的程序通过在 php.ini 文件中的配置设置进行定义。请在我们的 PHP Mail 参考手册[http://w3school.com.cn/php/php_ref_mail.asp]阅读更多内容。
注意:如果想直接在PHP中发送邮件而不需要那么麻烦,可以使用PHPMailer类来实现,具体可以参考:http://blog.csdn.net/cyb_23/article/details/42291293;


2、运行时配置
前言:邮件函数的行为受 php.ini 的影响。
SMTP "localhost" Windows 专用:SMTP 服务器的 DNS 名称或 IP 地址。
smtp_port "25" Windows 专用:SMTP 端口号。自 PHP 4.3 起可用。
sendmail_from NULL Windows 专用:规定从 PHP 发送的邮件中使用的 "from" 地址。
sendmail_path NULL Unix 系统专用:规定sendmail 程序的路径(通常 /usr/sbin/sendmail 或 /usr/lib/sendmail)


3、PHP 简易 E-Mail
前言:通过 PHP 发送电子邮件的最简单的方式是发送一封文本 email。
<?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.";
?>


4、PHP Mail Form
实例:反馈表单,向指定的 e-mail 地址发送,一条文本消息;
<html>
<body>
<?php
//if "email" is filled out, send email
if (isset($_REQUEST['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>




十一、PHP 安全的电子邮件
1、PHP E-mail 注入
->mailform.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>
隐患:未经授权的用户可通过输入表单在邮件头部插入数据。
再现:假如用户在表单中的输入框内加入这些文本,会出现什么情况呢?
someone@example.com
%0ACc:person2@example.com
%0ABcc:person3@example.com,anotherperson4@example.com,person5@example.com
%0ABTo:person6@example.com
与往常一样,mail() 函数把上面的文本放入邮件头部,那么现在头部有了额外的 Cc:, Bcc: 以及 To: 字段。当用户点击提交按钮时,这封 e-mail 会被发送到上面所有的地址!


2、PHP 防止 E-mail 注入
前言:防止 e-mail 注入的最好方法是对输入进行验证。
实例:加入检测表单中 email 字段的输入的验证程序
<html>
<body>
<?php
// 邮箱检验
function spamcheck($field)
 {
 //filter_var()函数使用FILTER_SANITIZE_EMAIL模式过滤email字段数据
 $field=filter_var($field, FILTER_SANITIZE_EMAIL);
 
 //filter_var()函数使用FILTER_VALIDATE_EMAIL模式验证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 错误处理(Error)
引言:在 PHP 中,默认的错误处理很简单。一条消息会被发送到浏览器,这条消息带有文件名、行号以及一条描述错误的消息。


1、PHP 错误处理
前言:在创建脚本和 web 应用程序时,错误处理是一个重要的部分。如果您的代码缺少错误检测编码,那么程序看上去很不专业,也为安全风险敞开了大门。


2、错误处理方法
>简单 "die()" 语句;
>自定义错误和错误触发器[错误定义、错误处理、错误监听、错误触发];
>错误报告;


3、die() 函数_基本的错误处理
实例:打开不存在的文本文件
<?php
$file=fopen("welcome.txt","r");
?>
报错:Warning: fopen(welcome.txt) [function.fopen]: failed to open stream: No such file or directory in C:\webfolder\test.php on line 2;
矫正:事前验证
<?php
if(!file_exists("welcome.txt"))
{
die("File not found");// 终止代码并输出相关信息;
}
else
{
$file=fopen("welcome.txt","r");
}
?>


4、错误处理器
引言:如何创建自定义错误处理器?
语法:error_function(error_level,error_message,error_file,error_line,error_context)
参数:
error_level 必需。为定义的错误规定错误报告级别。必须是一个值数。可参见错误报告级别表格。
error_message 必需。为定义的错误规定错误消息。
error_file 可选。规定错误在其中发生的文件名。
error_line 可选。规定错误发生的行号。
error_context 可选。规定一个数组,包含当错误发生时在用的每个变量以及它们的值。
创建:处理错误的函数
function customError($errno, $errstr)

echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Ending Script";
die();
}
解说:上面代码是个简单的错误处理函数。当它被触发时,它会取得错误级别和错误消息。然后它会输出错误级别和消息,并终止脚本。


5、错误报告级别
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 的一部分)


6、Set Error Handler
前言:PHP 的默认错误处理程序是内建的错误处理程序。我们打算把上面的函数改造为脚本运行期间的默认错误处理程序。可以修改错误处理程序,使其仅应用到某些错误,这样脚本就可以不同的方式来处理不同的错误。
实例:针对所有错误使用自定义错误处理程序
<?php
// 错误处理
function customError($errno, $errstr)

echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Ending Script";
die();
}
// 错误监听
set_error_handler("customError"); // 可以添加第二个参数来规定错误级别;
// 错误发生(触发)_输出不存在的变量
echo($test); // 输出不存在的变量:
?>


7、触发错误
引言:在脚本中用户输入数据的位置,当用户的输入无效时触发错误的方式很有用的。在 PHP 中,这个任务由 trigger_error() 完成。
实例:如果 "test" 变量大于 "1",就会发生错误
<?php
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below");
}
//错误输出类似:Notice: Value must be 1 or below in C:\webfolder\test.php on line 6;
?>
注意:您可以在脚本中任何位置触发错误,通过添加的第二个参数,您能够规定所触发的错误级别。


8、错误类型
E_USER_ERROR - 致命的用户生成的 run-time 错误。错误无法恢复。脚本执行被中断。
E_USER_WARNING - 非致命的用户生成的 run-time 警告。脚本执行不被中断。
E_USER_NOTICE - 默认。用户生成的 run-time 通知。脚本发现可能的错误,也有可能在脚本运行正常时发生。
实例:如果 "test" 变量大于 "1",则发生 E_USER_WARNING 错误;如果发生 E_USER_WARNING将使用自定义错误处理程序并结束脚本
<?php
// 错误处理
function customError($errno, $errstr)

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


// 错误监听_E_USER_WARNING类型错误,并被customError处理
set_error_handler("customError",E_USER_WARNING);


// 错误触发
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below",E_USER_WARNING); // 触发E_USER_WARNING类型错误;
}


// 错误输出
// Error: [512] Value must be 1 or below
// Ending Script
?>


9、错误记录
前言:默认地,根据在 php.ini 中的 error_log 配置,PHP 向服务器的错误记录系统或文件发送错误记录。通过使用 error_log() 函数,您可以向指定的文件或远程目的地发送错误记录。通过电子邮件向您自己发送错误消息,是一种获得指定错误的通知的好办法。
(1)、通过 E-Mail 发送错误消息
<?php
// 错误处理:
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("customError",E_USER_WARNING);


// 触发错误
$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
?>




十三、PHP 异常处理
引言:异常(Exception)用于在指定的错误发生时改变脚本的正常流程。
1、什么是异常?
解释:异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程。这种情况称为异常。
(1)、当异常被触发时,通常会发生:
>当前代码状态被保存;
>代码执行被切换到预定义的异常处理器函数;
>根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本;
(2)、错误处理方法
异常基本使用;
自定义异常类;
多个异常处理;
重新抛出异常;
设置顶层异常;


2、异常基本使用
前言:当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块。
注意:如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 "Uncaught Exception" (未捕获异常)的错误消息。
(1)、抛出异常,且不捕获
<?php
//create function with an exception
function checkNum($number)
{
if($number>1)
{
// 抛出异常
throw new Exception("Value must be 1 or below");
}
return true;
}


// 触发异常
checkNum(2);

// 错误输出
// 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 6
?>
(2)、捕获异常:Try, throw 和 catch
<?php
// 创建可抛出异常的函数
function checkNum($number)
{
if($number>1)
 {
 throw new Exception("Value must be 1 or below");
 }
return true;
}


//在 "try" 代码块中触发异常
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();
}


// 错误输出:Message: Value must be 1 or below;
?>


3、创建自定义 Exception 类
->customException.php
<?php
// 异常类
class customException extends Exception
{
// errorMessage方法
public function errorMessage()
{
$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
{
// 检查是否为有效Email地址
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 类的副本,外加 errorMessage() 函数。正因为它是旧类的副本,因此它从旧类继承了属性和方法,我们可以使用 exception 类的方法,比如 getLine() 、 getFile() 以及 getMessage()。


4、多个异常
引言:可以为一段脚本使用多个异常,来检测多种情况。
<?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
{
// 验证Email有效性
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
 {
 //throw exception if email is not valid
 throw new customException($email);
 }
// 确认是否包含example字串
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();
}
?>


5、重新抛出异常
前言:有时,当异常被抛出时,您也许希望以不同于标准的方式对它进行处理。可以在一个 "catch" 代码块中再次抛出异常。
注释:脚本应该对用户隐藏系统错误。对程序员来说,系统错误也许很重要,但是用户对它们并不感兴趣。为了让用户更容易使用,您可以再次抛出带有对用户比较友好的消息的异常。
<?php
// 定义异常类
class customException extends Exception
{
public function errorMessage()
{
 $errorMsg = $this->getMessage().' is not a valid E-Mail address.';
 return $errorMsg;
}
}
// Email地址
$email = "someone@example.com";
try
{
try
 {
 // 是否包含example字串
 if(strpos($email, "example") !== FALSE)
 {
  //throw exception if email is not valid
  throw new Exception($email);
 }
 }
catch(Exception $e)
 {
 // 重抛出异常,让外层捕获处理
 throw new customException($email);
 }
}
catch (customException $e)
{
//display custom message
echo $e->errorMessage();
}
?>
注释:如果在其目前的 "try" 代码块中异常没有被捕获,则它将在更高层级上查找 catch 代码块。


6、顶层异常处理(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" 代码块,而是触发顶层的异常处理程序。应该使用此函数来捕获所有未被捕获的异常。


7、异常规则
>需要进行异常处理的代码应该放入 try 代码块内,以便捕获潜在的异常。
>每个 try 或 throw 代码块必须至少拥有一个对应的 catch 代码块。
>使用多个 catch 代码块可以捕获不同种类的异常。
>可以在 try 代码块内的 catch 代码块中再次抛出(re-thrown)异常。
总结:简而言之:如果抛出了异常,就必须捕获它。




十四、PHP 过滤器(Filter)
引言:PHP 过滤器用于验证和过滤来自非安全来源的数据,比如用户的输入。
1、什么是 PHP 过滤器?
PHP 过滤器用于验证和过滤来自非安全来源的数据。验证和过滤用户输入或自定义数据是任何 Web 应用程序的重要组成部分。设计 PHP 的过滤器扩展的目的是使数据过滤更轻松快捷。


2、为什么使用过滤器?
原因:几乎所有 web 应用程序都依赖外部的输入。这些数据通常来自用户或其他应用程序(比如 web 服务)。通过使用过滤器,您能够确保应有程序获得正确的输入类型。您应该始终对外部数据进行过滤!输入过滤是最重要的应用程序安全课题之一。


3、外部数据
>表单数据;
>Cookies;
>服务器变量;
>数据库查询结果;


4、函数和过滤器
(1)、过滤变量
filter_var() - 通过指定过滤器来过滤单一的变量
filter_var_array() - 通过相同的或不同的过滤器来过滤多个变量
filter_input - 获取一个输入变量,并对它进行过滤
filter_input_array - 获取多个输入变量,并通过相同的或不同的过滤器对它们进行过滤
实例:使用filter_var()验证整数
<?php
$int = 123;
// 使用"FILTER_VALIDATE_INT" 过滤器来过滤变量
if(!filter_var($int, FILTER_VALIDATE_INT))
{
echo("Integer is not valid");
}
else
{
echo("Integer is valid");
}
?>


5、Validating (验证)过滤器
>用于验证用户输入;
>严格的格式规则(比如 URL 或 E-Mail 验证);
>如果成功则返回预期的类型,如果失败则返回 FALSE;


6、Sanitizing (净化)过滤器
>用于允许或禁止字符串中指定的字符;
>无数据格式规则;
>始终返回字符串;


7、选项和标志
前言:选项和标志用于向指定的过滤器添加额外的过滤选项。不同的过滤器有不同的选项和标志。
实例:使用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");
}
?>


8、验证输入
引言:让我们试着验证来自表单的输入。
思路:先确认是否存在输入数据;再用 filter_input() 函数过滤输入数据;
实例:验证email提交字段
<?php
// 检查是否存在指定输入类型的email变量
if(!filter_has_var(INPUT_GET, "email"))
{
echo("Input type does not exist");
}
else
{
// 验证Email有效性
if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL))
 {
 echo "E-Mail is not valid";
 }
else
 {
 echo "E-Mail is valid";
 }
}
?>
解说:上面的例子有一个通过 "GET" 方法传送的输入变量 (email):检测是否存在 "GET" 类型的 "email" 输入变量;如果存在输入变量,检测它是否是有效的邮件地址;


9、净化输入
实例:清理表单URL字段数据
<?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):检测是否存在 "POST" 类型的 "url" 输入变量;如果存在此输入变量,对其进行净化(删除非法字符),并将其存储在 $url 变量中;


10、过滤多个输入
引言:表单通常由多个输入字段组成。为了避免对 filter_var 或 filter_input 重复调用,可以使用 filter_var_array 或 filter_input_array 函数。
实例:使用 filter_input_array() 函数来过滤三个 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");
}
?>


11、使用 Filter Callback_2014-12-31 17:30
前言:通过使用 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!;
?>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值