PHPDay0B:错误与异常,会话,Cookie,用户登录实战

​​​​​​目录

0x00 错误与异常

0x01 用户自定义错误

0x02 错误的显示控制:

0x03 记录错误日志

0x04 异常

0x05自定义异常类

0x06 会话

0x07 Cookie

1.cookie的原理

2.cookie的使用

3.删除cookie的方法

0x08 SESSION

0x09 关闭Cookie怎么办?

0x0A关于session的配置

0x0C 用户登录实战


0x00 错误与异常

错误:语法错误,编译错误

异常:逻辑上的错误,即按照我们的逻辑不应该出现,但是仍然出现的错误。

错误级别:

E_ALL:所有的错误值

E_ERROR:致命的运行时错误 1 Fatal Error 例如重复定义函数。

E_PARSE:编译时的解析错误

E_WARNING:警告,例如引入了一个不存在的文件。

E_NOTICE:运行时的提醒,通常是逻辑上的错误。例如,使用了一个未定义的变量

E_USER_EROOR:用户自定义的致命错误

E_USER_WARING:用户自定义的警告

E_USER_NOTICE:用户自定义的提醒

deprecated:废弃的,表示你用了比较老的,已经废弃的东西。

0x01 用户自定义错误

<?php
set_error_handler('Produce_Error',E_ALL);
function Produce_Error($a,$b,$c,$d){

echo '这是我定义的错误处理函数';

echo '<br/>';

echo '错误级别'.$a;

echo '<br/>';

echo '错误信息:'.$b;

echo '<br/>';

echo '发生错误的脚本的绝对路径'.$c;

echo '<br/>';

echo '错误行号:'.$d;

echo '<br/>';

}
echo $a;

?>

trigger_error(“自定义错误提示”,错误提示类型)

错误提示类型:E_USER_ERROR,E_USER_NOTICE(默认),E_USER_PARSE,E_USER_WARNING

trigger_error(“我是用户自定义的错误”,);

E_USER_NOTICE错误之后的代码仍然可以执行。

注册错误处理函数:

set_error_handler(”错误处理函数名“,E_ALL);

例如:

上线前需要错误显示,来修改代码,上线后则必须屏蔽掉错误的显示,屏蔽错误显示的方法有以下几种:

第一种:错误抑制符@ 

可以控制notice 和warning的错误

不推荐这样用。最好的方法就是不要出现错误

1.脚本中

在哪个脚本中设置,只在哪个脚本中生效。

脚本中的配置优先于配置文件中的配置。

Ini_set(‘display_errors’,true);//true或者1表示展示错误

Ini_set(‘display_errors’,false);//false 或者0表示不展示错误

例如:

修改错误级别:

首先打开错误显示,然后限定只报告ERROR错误和NOTICE错误。

在所有php脚本中都生效。

打开php.ini,修改:

Development Value:On//开发环境中打开

Production Value:Off//生产环境即线上环境关闭。

display error = On

error_reporting  = E_ALL表示报告所有错误,前提是display error打开。可以修改此选项,只报告特定的错误。

然后重启

0x02 错误的显示控制:

<?php
echo @$a;

@include_once 'lalala.php';

?>

第二种修改错误的级别

<?php
ini_set('display_errors',false);
echo $a;
include_once 'lalala.php';
?>

注意:这个不能屏蔽解析错误,因为解析错误是在代码执行之前,解析时报的错误,这个时候代码还没有执行,所以屏蔽错误的语句还没有生效。

<?php
ini_set('display_errors',true);
error_reporting(E_ERROR|E_NOTICE);
echo $a;

include_once 'lalala.php';

?>

2.修改配置文件

<?php
try{
echo 'before','<br/>';

throw new Exception('我是一个异常信息');//Exception是一个内置的类。throw关键字用于抛出异常

//改变执行流程
echo 'after'.'<br/>';

}catch(Exception $e){//Exception用于限定$e的类型,即限定$e必须是Exception的一个对象

echo $e->getMessage();//打印收到的异常信息。

echo '执行流程已改变';

}
?>

0x03 记录错误日志

在php.ini中配置:

log_errors = On;

Error_log = php_error.log //表示错误日志存储到php_error.log这个文件中,可以修改该文件名称。

默认在脚本的同源文件夹中保存该文件。

在脚本中可以向错误日志中写入自定义的错误。

error_log(‘自定义的错误信息,自动发送到错误日志’,0); //0默认向系统日志中写。系统日志就是上文中提到的那个日志

Error_log('自定义错误信息’,3,’xxx.txt’);3表示向自定义的xxx.txt中写入错误信息。

0x04 异常

自定义的异常类必须继承系统的异常类

一次请求一次响应就是一个会话

0x05自定义异常类

<?php
class MyException extends Exception{

public function test(){

echo '这是自定义的异常类';

}
}
try{
throw new MyException('这是自定义的异常类');

}catch(MyException $mye){

echo $mye->test();

}
?>

0x06 会话

其中path限定了cookie什么情况下被发送。

如果设置为true,那么只能通过http请求的方式获得cookie,例如:js的document.cookie这种方式就不能输出httponly属性为true的cookie行了。

<?php
setcookie('only','189',time()+3600,"/","",false,true);
?>

<?php
var_dump($_COOKIE);
echo '<script>alert(document.cookie);</script>'

?>

删除cookie

 

0x07 Cookie

1.cookie的原理

cookie存储在客户端(浏览器)

但是cookie是服务器生成的一小段ASCII文本,然后将cookie存到http响应的set-cookie键值对发给浏览器,设置浏览器的cookie

当浏览器收到这段文本后,会以键值对的形式将cookie存在本地的一个目录下。

当浏览器下一次向同一个服务器发送请求的时候,就会将本地存储的cookie加入http请求的cookie键值对发给服务器。

Cookie值会自动存入服务器的php脚本的$_COOKIE数组中。

注意:$_COOKIE数组只有当请求中有cookie键值对的时候,才会被填充数据。也就是说如果在同一个脚本中setcookie和var_dump($COOKIE)。

那么第一次请求这个页面的时候,是不会打印出$COOKIE的。因为第一次请求中并没有cookie键值对。

2.cookie的使用

setcookie(name,value)设置cookie的键和值,如果没有指定第三个参数(删除cookie的时间),默认为当关闭浏览器后自动删除cookie

setcookie(’name’,’xiaoming’,time()+60*60) 第三个参数的单位为s

设置cookie的过期时间(expires)为设置成功之后的1个小时后,即便是关闭浏览器,只要没有到cookie的过期时间,cookie还会存在我们的客户端。

time()返回的当前时间的时间戳,

即请求/Company目录下的任何一个php文件时,该cookie(number:189)都会被包在请求中发送

请求/(服务器公开根目录)下的任何一个php文件时,该cookie(name:xiaoming)都会被包在请求中发送

也就是说

在setcookie函数中,如果不设置path参数,那么默认cookie的发送范围就是当前文件夹。

设置path:

Setcookie(’name’,’dahua’,time()+7*24*3600,’\’);设置cookie的path属性为公开根目录,也就是说,不论请求公开目录(及其子目录)下那个php文件,这个cookie都会被带在请求中发过去。

setcookie函数的第五个参数是域名Domain,建议设置为”“,表示当前域名

第六个参数设置https,如果设置为1或者true,表示该cookie只能以https的方式来设置。如果不是https,那么就会设置失败。0表示关闭

第七个参数设置httponly,默认为false或者空,

3.删除cookie的方法

方法一:将值设置为空

setcookie(要删除的cookie名,’’,time()-1,以前在哪个路径下设置的就要在哪个路径下删)

或者setcookie(要删除的cookie名.null,time()-1,path)

方法二:

unset($_COOKIE['name'])这种方式最好不要用,有坑。

0x08 SESSION

1.session原理:

session值 == 超市门前储物柜里存放的东西 >>打印出来一个条形码session_id

将session_id以cookie的形式存起来

即 session的存取依靠于cookie

session值存在服务器上。

session_id以cookie的形式存在客户端。

2.session使用

setSession.php

step1.先启动session:

<?php
session_start();
?>

启动session时服务器会做两个操作:

1.在服务器端生成文件sess(存在公开目录下的tmp文件夹中),大小为0KB,里面是空的,将来要存我们设置的session值。该文件的文件名由sess_'sessionID'组成。例如:sess_snrkjg35mrt0fmtt7a37uqdavn

2.在客户端设置cookie,即响应报文的set-cookie字段 :PHPSESSID = snrkjg35mrt0fmtt7a37uqdavn

step2.赋值

<?php
//setSession.php
session_start();
$_SESSION['username'] = 'xiaoming';
?>

该session值将会被存入sess文件中

step3.访问

例如:

可以在同一个文件访问它,也可以在另一文件比如printSession.php来访问它。同样,在访问前也必须session_start()

<?php
//printSession.php
session_start();
echo $_SESSION['username'];
?>

当浏览器请求printSession.php的时候,请求头中cookie字段中便存有session_id。服务器接到请求后,根据session_id去寻找服务器上对应的sess文件。然后将sess文件中存储的值响应给浏览器。

一旦session_id被删除,那么请求printSesson.php时,cookie字段中就没有session_id。服务器收到请求后更无法找到对应的sess文件。也无法将值返回给浏览器。

session_id被删除后,再次请求setSession.php文件,将重新设置session_id;

同一台终端的不同浏览器,请求setSession.php文件,在服务器端将为每个浏览器生成各自的sess文件。并且返回各自的session_id存在各个浏览器上。

3.删除session

deleteSession.php

<?php
session_start();
session_destroy();
?>

 这种方式直接删除了整个sess的文件(并不会删除客户端的存储session_id的cookie,要删除此cookie,需要我们自己手动删除)。但是如果我们只想删除sess文件中的一个键值对呢?

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

这种方式只删除session文件中,索引为user的session值,不会删除其他的数据。

4.如何在php脚本中输出session_id的cookie键值对呢?

<?php
session_start();
echo session_name();//key
echo '<br/>';
echo session_id();//value
echo '<br/>';
?>

0x09 关闭Cookie怎么办?

关闭cookie的方法:

FireFox 首选项>>隐私与安全>>Cookie>>权限管理>>输入网址,可以禁止访问该网址时使用cookie

关闭cookie,只是禁止在请求头中发送cookie字段。并没有禁止响应头中set-Cookie字段。也就是说服务器仍然可以设置浏览器上的cookie,但是浏览器不能向服务器发送cookie

当浏览器关闭cookie后,session还能用吗?

能!

当关闭cookie后,setSession.php可以正常运行,设置浏览器上的cookie,向sess文件中存值。但是,如果反复请求setSession.php,将会更新浏览器上的cookie(即session_id),并在服务器上生成新的sess文件。

因为反复请求setSession时,本应该发送第一次设置好的session_id。这样服务器就知道session_id已经设置好了。但是,因为关闭了cookie。所以,不能成功发送。所以,服务器认为session_id并没有设置成功,所以生成了新的sess文件,并在set-cookie中存了新的session_id.

<?php
//setSession.php
session_start();
$_SESSION['username'] = 'xiaoming';
$_SESSION['pwd'] = '23141';

?>

解决方法:

getSession.php

<?php
//printSession.php
session_id('snrkjg35mrt0fmtt7a37uqdavn');//对应的session_id
session_start();
echo $_SESSION['username'];
?>

这样一来就不需要浏览器向服务器发送session_id了。直接请求该printSession脚本,脚本中就存了session_id.

完整版解决方案:

用get传参发送session_id.

<?php
//setSession.php
session_start();
$_SESSION['username'] = 'xiaoming';
$session_id = session_id();
echo "<a href = 'printSession.php?sid=".$session_id."'>发送session_id</a>";
?>

printSession.php

<?php
//printSession.php
session_id($_GET['sid']);//对应的session_id
session_start();
echo $_SESSION['username'];
?>

0x0A关于session的配置

php.ini中

session.save_handler = files

表示session值存在sess文件中。以后可以修改为Redis数据库。

session.save_path=‘C:\xxx\xxx\xxx’;

表示服务器上sess文件存储的位置,可以自定义;

session.name = PHPSESSID

表示session_id的cookie的键是PHPSESSID,可以修改

session.auto_start = 0

表示每次都需要手动输入session_start.可以修改为1.以后就不需要session_start了。但是不建议这样搞

0x0B session和cookie的区别:

session值存在服务端,cookie存在客户端

session存储的大小可以说没限制,cookie最大为4KB

session安全一些。cookie相对不安全

session的存取基于cookie。但是cookie关闭后,session照样可以用。

0x0C 用户登录实战

流程:

  1. 用户输入用户名,密码
  2. 用户名和密码正确,设置session,跳转到用户中心
  3. 如果错误,跳转到登录页面。

忘了说明你敲得说,敲个几百遍,绝对忘不了。

php中header("Location:路径")函数可以用来跳转页面。

login.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset = 'utf-8'/>
    </head>
    <body>
        <form action="login.php" method = "post">
                用户名:<input type="text" name="username" id=""/><br/>
                密码:<input type="password" name="password" id=""><br/>
                <input type = "submit" value = "登录"/><br/>
        </form>
    </body>
</html>

login.php

<?php
//var_dump($_POST);
$user_name = $_POST['username'];
$password = $_POST['password'];
if($user_name == 'XDU' && $password == '123456'){
    echo '登录成功';
    session_start();
    $_SESSION['username'] = $user_name;
    header('Location:user.php?username='.$user_name);
}else{
    echo '失败';
}
?>

user.php用户中心

为什么要先判断$_SESSION['username']是否存在呢?因为如果不判断,用户可以从url栏中输入用户中心的网址,直接跳过登录,访问用户中心。

凡是正常登录的用户,必然会存一个session值。我们只要判断有没有这个session值,就可以将正常登录用户和非正常访问用户中心的用户区分开。

<?php
session_start();
if(isset($_SESSION['username'])){
    $user_name = $_GET['username'];
    echo $user_name.',欢迎到用户中心!';
    echo '<a href="logout.php">退出</a>';
}else{
    header('Location:login.html');
}
?>

logout.php

<?php
session_start();
unset($_SESSION['username']);
header('Location:login.html');
?>
发布了156 篇原创文章 · 获赞 19 · 访问量 8945

猜你喜欢

转载自blog.csdn.net/weixin_43415644/article/details/103994135