欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Php高级知识 2

程序员文章站 2022-08-21 19:33:54
8、php cookies cookie 常用于识别用户。 8.1 什么是 cookie? cookie 常用于识别用户。cookie 是服务器留在用户计算机中的小文件。每当相同的计算机通过请...

8、php cookies

cookie 常用于识别用户。

8.1 什么是 cookie?

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

8.2 如何创建 cookie?

setcookie() 函数用于设置 cookie。

注释:setcookie() 函数必须位于

标签之前。

语法

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

例子

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



注释:在发送 cookie 时,cookie 的值会自动进行 url 编码,在取回时进行自动解码(为防止 url 编码,请使用 setrawcookie() 取而代之)。

8.3 如何取回 cookie 的值?

php 的 $_cookie 变量用于取回 cookie 的值。

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


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



"; else echo "welcome guest!
"; ?>

8.4 如何删除 cookie?

当删除 cookie 时,您应当使过期日期变更为过去的时间点。

删除的例子:



8.5 如果浏览器不支持 cookie 该怎么办?

如果应用程序涉及不支持 cookie 的浏览器,应采取其他方法在应用程序中从一张页面向另一张页面传递信息。一种方式是从表单传递数据(有关表单和用户输入的内容,在前面已介绍过了)。

下面的表单在用户单击提交按钮时向 "welcome.php" 提交了用户输入:
 

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

 

取回 "welcome.php" 中的值,就像这样:


welcome .
you are years old.

 

9、php sessions

php session 变量用于存储有关用户会话的信息,或更改用户会话的设置。session 变量保存的信息是单一用户的,并且可供应用程序中的所有页面使用。

9.1 php session 变量

当运行一个应用程序时,会打开它,做些更改,然后关闭它。这很像一次会话。计算机清楚你是谁。它知道你何时启动应用程序,并在何时终止。但是在因特网上,存在一个问题:服务器不知道你是谁以及你做什么,这是由于 http 地址不能维持状态。

通过在服务器上存储用户信息以便随后使用,php session 解决了这个问题(比如用户名称、购买商品等)。不过,会话信息是临时的,在用户离开网站后将被删除。如果需要永久储存信息,可以把数据存储在中。

session 的工作机制是:为每个访问者创建一个唯一的 id (uid),并基于这个 uid 来存储变量。uid 存储在 cookie 中,亦或通过 url 进行传导。

9.2 开始 php session

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

注释:session_start() 函数必须位于

标签之前:


上面的代码会向服务器注册用户的会话,以便您可以开始保存用户信息,同时会为用户会话分配一个 uid。

9.3 存储 session 变量

存储和取回 session 变量的正确方法是使用 php $_session 变量:



输出:

pageviews=1

在下面的例子中,我们创建了一个简单的 page-view 计数器。isset() 函数检测是否已设置 "views" 变量。如果已设置 "views" 变量,我们累加计数器。如果 "views" 不存在,则我们创建 "views" 变量,并把它设置为 1:


9.4 终结 session

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

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


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


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

10、php 发送电子邮件

php 允许您从脚本直接发送电子邮件。

10.1 php mail() 函数

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

语法

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

 

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

可选。规定附加的标题,比如 from、cc 以及 bcc。

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

parameters 可选。对邮件发送程序规定额外的参数

 

注释:php 需要一个已安装且正在运行的邮件,以便使邮件函数可用。所用的程序通过在 php.ini 文件中的配置设置进行定义。

10.2 php 简易 e-mail

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

在下面的例子中,我们首先声明变量($to, $subject, $message, $from, $headers),然后我们在 mail() 函数中使用这些变量来发送了一封 e-mail:



10.3 php mail form

通过 php,能够在自己的站点制作一个反馈表单。下面的例子向指定的 e-mail 地址发送了一条文本消息:



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

例子解释:

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

 

11、php 安全的电子邮件

在前面的 php e-mail 脚本中,存在着一个。

11.1 php e-mail 注入

首先,请看前面的 php 代码:



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

以上代码存在的问题是,未经授权的用户可通过输入表单在邮件头部插入数据。

假如用户在表单中的输入框内加入这些文本,会出现什么情况呢?

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() 函数把上面的文本放入邮件头部,那么现在头部有了额外的 cc:, bcc: 以及 to: 字段。当用户点击提交按钮时,这封 e-mail 会被发送到上面所有的地址!

11.2 php 防止 e-mail 注入

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

下面的代码增加了检测表单中 email 字段的输入验证程序:



<!--?php
function spamcheck($field)
  {
  //filter_var() sanitizes the e-mail 
  //address using filter_sanitize_email
  $field=filter_var($field, <code-->filter_sanitize_email);
   
  //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>";
  }
?>

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

filter_sanitize_email 从字符串中删除电子邮件的非法字符filter_validate_email 验证电子邮件地址

12、php 错误处理

在 php 中,默认的错误处理很简单。一条消息会被发送到浏览器,这条消息带有文件名、行号以及一条描述错误的消息。

12.1 php 错误处理

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

下面介绍 php 中一些最为重要的错误检测方法。

介绍不同的错误处理方法:

简单的 "die()" 语句 自定义错误和错误触发器错误报告

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

第一个例子展示了一个打开文本文件的简单脚本:


如果文件不存在,会获得类似这样的错误:

warning: fopen(welcome.txt) [function.fopen]: failed to open stream: 
no such file or directory in c:\webfolder\test.php on line 2

为了避免用户获得类似上面的错误消息,在访问文件之前检测该文件是否存在:


现在,假如文件不存在,会得到类似这样的错误消息:

file not found

比起之前的代码,上面的代码更有效,这是由于它采用了一个简单的错误处理机制在错误之后终止了脚本。

不过,简单地终止脚本并不总是恰当的方式。

12.3 创建自定义错误处理器

创建一个自定义的错误处理器非常简单。简单地创建了一个专用函数,可以在 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 可选。规定一个数组,包含了当错误发生时在用的每个变量以及它们的值。

12.4 错误报告级别

这些错误报告级别是错误处理程序旨在处理的错误的不同的类型:

 

错误报告级别
常量 描述
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 "error: [$errno] $errstr
";
 echo "ending script";
 die();
 }

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

现在,我们已经创建了一个错误处理函数,我们需要确定在何时触发该函数。

12.5 set error handler

php 的默认错误处理程序是内建的错误处理程序。想把上面的函数改造为脚本运行期间的默认错误处理程序。

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

set_error_handler("customerror");

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

实例

通过尝试输出不存在的变量,来测试这个错误处理程序:

1)
{
trigger_error("value must be 1 or below");
}
?>

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

notice: value must be 1 or below
in c:\webfolder\test.php on line 6

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

可能的错误类型:

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

例子

在本例中,如果 "test" 变量大于 "1",则发生 e_user_warning 错误。如果发生了 e_user_warning,将使用自定义错误处理程序并结束脚本:

1)
  {
  throw new exception("value must be 1 or below");
  }
 return true;
 }

//trigger exception
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

13.3 try, throw 和 catch

要避免上面例子出现的错误,我们需要创建适当的代码来处理异常。

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

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

让我们触发一个异常:

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 

例子解释:

上面的代码抛出了一个异常,并捕获了它:

创建 checknum() 函数。它检测数字是否大于 1。如果是,则抛出一个异常。在 "try" 代码块中调用 checknum() 函数。checknum() 函数中的异常被抛出"catch" 代码块接收到该异常,并创建一个包含异常信息的对象 ($e)。通过从这个 exception 对象调用 $e->getmessage(),输出来自该异常的错误消息

不过,为了遵循“每个 throw 必须对应一个 catch”的原则,可以设置一个顶层的异常处理器来处理漏掉的错误。

13.4 创建一个自定义的 exception 类

创建自定义的异常处理程序非常简单。简单地创建了一个专门的类,当 php 中发生异常时,可调用其函数。该类必须是 exception 类的一个扩展。

这个自定义的 exception 类继承了 php 的 exception 类的所有属性,您可向其添加自定义的函数。

开始创建 exception 类:

getline().' in '.$this->getfile()
  .': '.$this->getmessage().' 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 类的副本,外加 errormessage() 函数。正因为它是旧类的副本,因此它从旧类继承了属性和方法,可以使用 exception 类的方法,比如 getline() 、 getfile() 以及 getmessage()。

例子解释:

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

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

13.5 多个异常

可以为一段脚本使用多个异常,来检测多种情况。

可以使用多个 if..else 代码块,或一个 switch 代码块,或者嵌套多个异常。这些异常能够使用不同的 exception 类,并返回不同的错误消息:

getline().' in '.$this->getfile()
.': '.$this->getmessage().' 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();
 }
?>

例子解释:

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

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

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

13.6 重新抛出异常

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

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

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

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

13.7 设置顶层异常处理器 (top level exception handler)

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

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

就像上面的代码一样,选项必须放入一个名为 "options" 的相关数组中。如果使用标志,则不需在数组内。

由于整数是 "300",它不在指定的范围内,以上代码的输出将是 "integer is not valid"。

 

14.6 验证输入

验证来自表单的输入。

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

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

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

 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.
");
 }
elseif(!$result["email"])
 {
 echo("e-mail is not valid.
");
 }
else
 {
 echo("user input is valid");
 }
?>

例子解释:

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

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

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

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

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

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

14.9 使用 filter callback

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

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

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

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


                    
(0)
打赏 Php高级知识 2 微信扫一扫

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

Php高级知识 2
验证码: Php高级知识 2