韩顺平PHP从入门到精通视频教程笔记

37 整型细节说明

$a;
echo $a;
var_dump($a) //NULL

一个数总是要占用内存空间(字节),在 php 中一个整数一般占用四个字节(与平台相关),一个字节占用 8bit
php 的整数的二进制的最高位表示符号 0 表示正数 1 表示负数
通过 PHP_INT_SIZE 可以显示我们自己的电脑上一个整数用几个字节表示

echo PHP_INT_SIZE;  //4 我的电脑中一个整数是4个字节 32bit
echo PHP_INT_MAX;  //整型最大的数为2147483647  最大负数为-2147483647
//2147483647 = 2^31 - 1    二进制表示01111111 11111111 11111111 11111111

如果给定一个数超出了 int 范围,将会解释为 float

38 布尔数细节 浮点数细节 字符串字节

布尔数细节

以下值被当做 false:

  • 布尔值 false
  • 整型值 0
  • 浮点值 0.0
  • 空字符串以及字符串“0”
  • 不包括任何元素的数组
  • 不包括任何成员的对象
  • 特殊类型 NULL(包括未设定的变量)

浮点数细节

浮点数的字长和平台相关,通常最大值是 1.8e308 并具有 14 位十进制数字的精度
浮点数精度是 14 位(从左边开始第一个非零的数就是精度的第一位)

$a = 0.1234567890222298;
echo $a;  //0.12345678902223

字符串细节

$a = “hello” //$a 占用 5 个字节
""中的变量将被解析,‘’中的变量直接输出其字符本身

39 算术运算符 比较运算符 逻辑运算符

$a=10;$b=7;
if($a++>10 && $b++>7){  //注意后++和前++的运算顺序
    echo 'ok'  //不输出
}
echo $a;  //11
echo $b;  //7
$f = false or true;
echo $f;  //false   or的优先级比=还低

and && 都表示逻辑与 区别在于&&的优先级比 and 高
or || 都表示逻辑或 区别在于||的优先级比 or 高

44 布置练习

$_REQUEST()接受的参数要和提交数据的页面给出的 html 元素名字一致,否则接受的数据是 null 或""

45 break continue 常量

break/continue 语句可以接受一个可选的数字参数来决定跳出几重循环
geto 语句常用来跳出循环或 switch,可替代多层 break

47 函数使用

include 与 require 区别:

  • 当 include 包含的文件出错时,提出警告,程序继续往下执行
  • 当 require 包含的文件出错时,致命性错误,终止程序

include_once 与 require_once 当需包含的文件已经包含时,则不执行
项目中经常使用 require_once,放在页面头部

48 函数调用深入理解

含糊调用时会开辟一个新栈,各栈中变量是相互独立的,参数是以值形式传递
函数名不区分大小写
在 PHP 中错误有 3 种形式:

  1. Notice:注意
  2. Warning:警告
  3. Error:错误

51 位运算

  1. 二进制的最高位是符号位:0 表示正数,1 表示负数
  2. 原码:用二进制来表示的代码
    正数的原码 反码 补码 都一样
    负数的反码:原码符号位不变,其他位取反(0->1 1->0)
    负数的的补码:反码+1
  3. 0 的反码补码都是 0
  4. php 无符号数
  5. 在计算机运算的时候都是以补码来运算的
  • 按位与&: 两个全为 1,结果为 1
  • 按位或|: 两个中有一个为 1,结果为 1
  • 按位异或^:两个一个为 0,一个为 1,结果为 1
  • 按位取反~:0=>1 1->0
  • 算术左移<<:符号位不变,低位补 0 (左移 1 位相当于乘以 1 个 2)
  • 算术右移>>: 低位溢出,符号位不变,并用符号位补溢出的高位

55 数组使用细节

unset()可以删除数组中的某个值,该索引不会重新自动建立。也可销毁某个变量,
$a + $b 数组的联合操作

$a  = array( "a"  =>  "apple" ,  "b"  =>  "banana" );
 $b  = array( "a"  =>  "pear" ,  "b"  =>  "strawberry" ,  "c"  =>  "cherry" );
 $c  =  $a  +  $b ;  // Union of $a and $b
 echo  "Union of \$a and \$b: \n" ;
 var_dump ( $c );
 //array( "a"  =>  "apple" ,  "b"  =>  "banana" ,"c"  =>  "cherry")
 $c  =  $b  +  $a ;  // Union of $b and $a
 echo  "Union of \$b and \$a: \n" ;
 var_dump ( $c );
 //array( "a"  =>  "pear" ,  "b"  =>  "strawberry" ,  "c"  =>  "cherry" )

提交给当前页面时,阻止 Notice 报错的方法:

  1. 将 php.ini 文件中的 error_reporting 改为:error_reporting = E_ALL & ~E_NOTICE
  2. 在当前页面添加error_reporting(E_ALL ^E_NOTICE);
  3. 添加一个隐藏的 input<input type="hidden" name="action" value="submitted">
    在 php 文件中if(isset($_POST['action']) && $_POST['action'] == "submitted"){}

56 排序方法

常用排序方法:

  1. 内部排序法
    1. 交换式排序法
      1. 冒泡排序法
        基本思想:每走一次外层循环就排好一个数,里层循环的循环次数也就少了一个
      2. 快速排序法
    2. 选择式排序法
      1. 选择排序法
        基本思想:第一次外层循环选出数组中最小的数与原数组第一个数交换,第二次循环从剩余的数(不包括第一项)中选出最小的数与原数组第二个数交换……
      2. 堆排序法
    3. 插入式排序法
      1. 插入排序法
        基本思想:把 n 个待排序的数分为一个有序表(含一个元素)和一个无序表(含 n-1 个元素),排序过程中依次从无序表中取出一个数与有序表中的元素进行排序并插入适当位置。
      2. 谢尔排序法
      3. 二叉树排序法
  2. 外部排序法

冒泡排序法

function bubbleSort(&$array){  //数组默认传递的是值
    $temp = 0;
    for($i = 0;$i < count($array) -1;$i++){
        for($j = 0;$j < count($array) - 1 -$i;$j++){
            if($array[$j] > $array[$j+1]){  //从小到大排列
                $temp = $array[$j];
                $array[$j] = $array[$j+1];
                $array[$j+1] = $temp;
            }
        }
    }
}

选择排序法 效率比选择排序法稍高,不是每一次都需要交换

function selectSort(&$array){
    $temp = 0;
    for($i = 0;$i < count($array) - 1;$i++){
        $minVal = $array[$i];  //假设$i就是最小值
        $minValIndex = $i;
        for($j = $i+1;$j < count($array);$j++){
            if($minVal > $array[$j]){    //从小到达排列
                $minVal = $array[$j];     //找最小值
                $minValIndex = $j;
            }
        }
        $temp = $array[$i];
        $array[$i] = $array[$minValIndex];
        $array[$minValIndex] = $temp;
    }
}

插入排序法

function insertSort(&$array){  //从小到大排列
    //先默认$array[0],已经有序,是有序表
    for($i = 1;$i < count($array);$i++){
        $insertVal = $array[$i]; //$insertVal是准备插入的数
        $insertIndex = $i - 1; //有序表中准备比较的数的下标
        while($insertIndex >= 0 && $insertVal < $array[$insertIndex]){
            $array[$insertIndex + 1] = $array[$insertIndex]; //将数组往后挪
            $insertIndex--; //将下标往前挪,准备与前一个进行比较
        }
        if($insertIndex + 1 !== $i){
            $array[$insertIndex + 1] = $insertVal;
        }
    }
}

快速排序法

function quickSort($array){
    if(!isset($array[1]))
        return $array;
    $mid = $array[0]; //获取一个用于分割的关键字,一般是首个元素
    $leftArray = array();
    $rightArray = array();
    foreach($array as $v)
    {
        if($v > $mid)
            $rightArray[] = $v;  //把比$mid大的数放到一个数组里
        if($v < $mid)
            $leftArray[] = $v;   //把比$mid小的数放到另一个数组里
    }
    $leftArray = quickSort($leftArray); //把比较小的数组再一次进行分割
    $leftArray[] = $mid;        //把分割的元素加到小的数组后面,不能忘了它哦
    $rightArray = quickSort($rightArray);  //把比较大的数组再一次进行分割
    return array_merge($leftArray,$rightArray);  //组合两个结果
}

58 顺序查找 二分法查找

顺序查找

function search(&$array,$findVal){
    $flag = false;
    for($i = 0;$i < count($array);$i++){
        if($findVal == $array[$i]){
            echo "find it,it's index is $i";
            $flag = true;
            break;   //找到第一个就停止
        }
    }
    if(!$flag){
        echo 'can not find it!'
    }
}

二分法查找
二分法查找的前提是数组已排序好
首先找到数组的中间数,与要找的数进行比较,如果要找的数大于中间数,则向后找,如果要找的数小于中间数,则向前找,如果相等则已找到。

function binarySearch(&$array,$findVal,$leftIndex,$rightIndex){
    if($leftIndex > $rightIndex){
        echo "找不到!";
    }
    $middleIndex = round(($leftIndex + $rightIndex)/2);//找到中间数下标
    if($findVal > $array[$middleIndex]){  //如果要找的数大于中间数,则向后找
        binarySearch($array,$findVal,$middleIndex + 1,$rightIndex);
    }else if($findVal < $array[$middleIndex]){ //如果要找的数小于中间数,则向前找
        binarySearch($array,$findVal,$leftIndex,$middleIndex - 1);
    }else{  //如果相等则已找到
        echo "find it,it's index is $middleIndex";
    }
}

64 函数传递即本数据类型和数组的方式

函数在传递基本数据类型(整型 浮点型 字符串 布尔型)是以值传递的,加上&符号之后是以引用传递
在传递数组时,默认也是按值传递

67 构造方法

对象在创建时即使类中没有明确定义构造方法,会使用默认的构造方法,一旦定义构造方法默认的将被覆盖
构造方法的默认修饰符是 public
构造方法中的形参个数与对象创建时的实参个数需一致

68 析构方法

析构函数的作用是释放资源的操作,并不是销毁对象本身
销毁的顺序是先创建的对象最后被销毁,按栈(先入后出)顺序
什么时候调用?

  1. 当程序(进程结束)退出的时候
  2. 当一个对象成为垃圾对象(没有任何引用指向它)的时候,析构方法立即调用

69 静态变量

定义静态变量: [访问修饰符] static $变量名
静态变量的访问:

  • 如果在类中访问 self::$变量名
  • 如果在类外访问 类名::$变量名
  • 静态变量属于类的
class Person{
    public static $a = 90;
    public function __construct(){  //代码未执行
        $this -> a = 45;
    }
}
echo Person::$a; //90

70 静态方法

静态方法也叫类方法,是属于所有对象的实例
[访问修饰符] static 方法名(){}
常用静态方法操作静态变量,而不能操作非静态变量
在类外部: 类名::类方法名 或者 对象名->类方法名
在类内部: self::类方法名 或者 类名::类方法名

71 面向对象特性

成员属性前必须指定访问修饰符
成员方法前默认访问修饰符为 public

protected 和 public 所修饰的成员属性和成员方法在被子类继承时,修饰符不变
子类实例化时默认不会调用父类的构造方法,若需要调用可使用父类名::方法名或者 parent::方法名来使用
PHP5 默认情况下不直接支持重载,但可通过魔术方法__call()来实现重载效果
在方法的覆盖时,子类的访问权限不能小于父类的访问权限

75 抽象类

抽象类主要用途是让子类来继承,其本身并不需要实例化,这样可以达到代码复用。用 abstract 来修饰
一个类中只要含有抽象方法,则该类必须声明为抽象方法
抽象类实质是子类的父类,它可以有抽象方法,也可以有可实例化的方法

abstract class Animal{
    public $name="abc";
    protected $age;
    abstract public function cry();
    public function getName(){
        return $this->name;
    }
    public static function test(){
        echo "可以条调用";
    }
}
class Cat extends Animal{
    public function cry(){
        echo "miaomiao";
    }
}
$cat1 = new Cat();
$cat1->cry();
echo $cat1->getName(); //abc
Animal::test(); //可以条调用

76 接口

接口的作用主要是制定规范(定义方法或属性,供类来实现它)。

interface 接口名1{
    const A=90;  //可以定义常量
    public function start();
}
interface 接口名2{
    public function stop();
}
class 类名 implements 接口名1,接口名2{  //可实现多个接口
    public fucntion start(){
        //your code
    }
    public fucntion stop(){
        //your code
    }
}
echo 接口名1::A;  //90
  • 接口名一般以 i 开头
  • 接口不能实例化,只能由类来实现
  • 接口里的所有方法都没有方法体,只有当某个类去实现它的时候才把写出方法体
  • 一个类可以实现多个接口,需用逗号隔开
  • 接口中可以有属性,但必须是常量,并且是 public
  • 接口中的方法必须是 public,默认是 public
  • 接口不能继承类,但是接口可以继承多个其他接口
  • 实现接口是对单一继承的补充
    interface iUsb1{
        public function a();
    }
    interface iUsb2{
        public function b();
    }
    interface iUsb extends iUsb1,iUsb2{
        public function c();
    }
    class usb implements iUsb{  //必须全部实现所有接口定义的方法
        public function a(){}
        public function b(){}
        public function c(){}
    }

77 final const

如果我们希望某个类不被其他类继承时,可以使用 final 修饰符
如果我们希望某个方法不能被子类改写,可以使用 final 修饰符
final 不能修饰成员属性
类中常量 const
基本用法 const 常量名=值
访问: 类名::常量名 或 接口名::常量名
常量名应全部大写,并且前面不能有$符,常量在定义是必须赋值,常量是属于类的

81 错误处理

set_error_handle();设置自定义错误处理函数
trigger_error();错误触发器
error_log();向指定的文件发送个错误记录

82 异常处理

当捕获到一个异常后,try 块中的后续代码不被继续执行

84 HTTP 协议深度剖析 1

HTTP请求报文基本结构
请求行 GET http://localhost/Study/PHP/demo/84.html HTTP/1.1
首部字段 Host: localhost Proxy-Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch, br Accept-Language: zh-CN,zh;q=0.8 Cookie: _ga=GA1.1.1178440987.1493386332
空行
报文主体 GET请求的数据会显示在地址栏,POST请求发送的数据会在这里显示
HTTP响应报文基本结构
状态行 HTTP/1.1 200 OK
首部字段 Date: Sat, 29 Apr 2017 11:06:17 GMT Server: Apache Vary: Accept-Encoding Content-Encoding: gzip Cache-Control: max-age=0 Expires: Sat, 29 Apr 2017 11:06:17 GMT Content-Length: 275 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=UTF-8
空行
报文主体 请求的内容(一般是网页代码)

get/post 的区别

  1. 安全性
    get 请求的数据会显示在地址栏,post 请求的数据放在 http 协议的请求体
  2. 数据大小
    http 协议本身并不限制请求数据大小,浏览器会限制 url 的长度
  3. get 请求携带参数可以更好的添加到收藏夹

利用$_SERVER[‘HTTP_REFERER’]实现防盗链

if(isset($_SERVER['HTTP_REFERER'])){
    if(strpos($_SERVER['HTTP_REFERER'],"http://www.127.0.0.1/") == 0 ){
        echo "正常访问";
    }else{
        header("Location:Waarning.php");
    }
}else{
    echo "你是非法盗链者";
}

85 HTTP 协议深度剖析 2 (状态码说明)

302 重定向

header("Location:84.html");

304 未修改,从缓存中提取

echo "hello <br>";
echo "<img src='1.jpg'>"

chrome 浏览器默认不发出 304 请求,直接是使用缓存(前提是允许缓存)

86 HTTP 协议深度剖析 3(禁用缓存)

因为各个浏览器控制缓存的方式不同,一般以下三个属性都设置

header("Expires:-1");
header("Cache-Control:no-cache");
header("Pragma:no-cache");

87 HTTP 协议深度剖析 4(文件下载 )

/**
 * [fileDown description]
 * @param  [type] $file_name    [文件名称]
 * @param  [type] $file_sub_dir [下载文件子路径]
 * @return [type]               [返回文件数据]
 */
function fileDown($file_name,$file_sub_dir){
    //对文件名中的中文进行转码
    $file_name = iconv("utf-8","gb2312",$file_name);
    //文件绝对路径
    $file_path = $_SERVER['DOCUMENT_ROOT'].$file_sub_dir.$file_name;
    if(!file_exists($file_path)){
        echo "文件不存在!";
        return ;
    }
    //文件指针
    $fp = fopen($file_path, "r");
    //文件大小
    $file_size = filesize($file_path);
    //返回的文件类型
    header("Content-type: application/octet-stream");
    //按照字节返回
    header("Accept-Ranges: bytes");
    header("Accept-Length: $file_size");
    //浏览器弹出对话框 对应文件名
    header("Content-Disposition: attachment;filename=".$file_name);
    //向客户端回送数据
    $buffer = 1024;
    //为了下载的安全,最好做一个文件字节读取计数器
    $file_count = 0;
    while(!feof($fp) && ($file_size - $file_count > 0)){
        $file_data = fread($fp,$buffer);
        //统计读了多少个字节
        $file_count += $buffer;
        echo $file_data;
    }
    //关闭文件
    fclose($fp);
}
fileDown("截图.jpg","study/php/exercise/")

89 PHP 数据库编程-使用 mysql 扩展库

php 有三种方式来操作我们的 MySQL 数据库

  1. mysql 扩展库
  2. mysqli 扩展库
  3. pdo 扩展库

在 php.ini 文件中配置 mysql 扩展库,去掉 extension=php_mysql.dll 前面的注释符

创建数据库和 test 表

CREATE DATABASE IF NOT EXISTS test;

USE test;

CREATE TABLE user1(
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(32) NOT NULL,
    password VARCHAR(64) NOT NULL,
    email VARCHAR(123) NOT NULL,
    age TINYINT UNSIGNED NOT NULL
);

INSERT INTO user1(name,password,email,age) VALUES ('zs',md5('123456'),'zs@sohu.com',30),('ls',md5('123456'),'ls@sohu.com',40),('ww',md5('123456'),'ww@sohu.com',50);

INSERT INTO user1(name,password,email,age) VALUES ('顺平',md5('123456'),'sp@sohu.com',60);
//查看mysql客户端字符集编码方式
show variables like '%char%';
//若客户端出现不支持中文时,可如下设置
set chatacter_set_client=gbk;
set chatacter_set_result=gbk;

SHOW TABLES;//查看该数据库下有哪些表
DESE user1; //查看user1表

char(10)固定长度大小,varchar(32)长度可变,多余可以回收

编写 php 程序

 //mysql扩展库操作mysql数据库步骤如下
 //1. 获取连接
 $conn=mysql_connect("127.0.0.1","root","131978");
 if(!$conn){
     die("连接失败".mysql_error());
 }
 //2. 选择数据库
 mysql_select_db("test");
 //3. 设置操作编码(建议有)!!!
 mysql_query("set names utf8"); //保证我们的php程序是按照utf8码操作.
 //4. 发送指令sql (ddl 数据定义语句 , dml(数据操作语言 update insert ,delete) ,dql (select ), dtl 数据事务语句 rollback commit... )
 $sql="select * from user1";
 //函数
 //$res 表示结果集,你可以简单的理解就是 一张表.
 $res=mysql_query($sql,$conn);
 //var_dump($res); //mysql result 资源类型

 //5. 接收返回的结果,并处理.(显示)
 // mysql_fecth_row 会依次取出$res结果集的下一行数据,赋值给$row
 // $row就是一个数组, 样式array(5) { [0]=> string(1) "1" [1]=> string(2) "zs" [2]=> string(32) "e10adc3949ba59abbe56e057f20f883e" [3]=> string(11) "zs@sohu.com" [4]=> string(2) "30" }
//mysql_fetch_assoc mysql_fetch_array
  while($row=mysql_fetch_row($res)){
//第一种取法是 同 $row[$i]
//echo "<br/> $row[0]--$row[1]--$row[2]";
//echo "<br/>";
//var_dump($row);
//第二种取法
      foreach($row as $key => $val){
          echo "--$val";
      }
      echo "<br/>";
  }
  //6.释放资源
  mysql_free_result($res);
  //关闭连接,无需写会自动关闭
  mysql_close($conn);

处理 mysql 资源的几种方法:
mysql_fetch_row()
该函数将一条结果记录返回并以一个普通索引数组的形式保存
mysql_fetch_assoc()
该函数将一条结果记录返回并以一个普通关联数组的形式保存
mysql_fetch_object()
该函数将一条结果记录返回一条结果记录,各个字段需要以对象的形式访问
mysql_fetch_array() 不推荐使用
该函数可以将结果数据表中的每一行获取为一个关联数组或索引数组,或同时为关联数组和索引数组

对数据表的增删修改操作
//增加数据操作 返回 bool 类型 无需释放资源
$sql = “INSERT INTO user1 (name,password,email,age) VALUES (‘小明’,md5(‘123’),‘xiaoming @sohu.com’,34)”;
//删除数据操作 返回bool类型 无需释放资源
$sql = “DELETE FROM user1 WHERE id=6”;
//查询数据操作 返回资源类型
$sql=“SELECT * FROM user1”;
//更改数据操作 返回bool类型 无需释放资源
$sql = “UPDATE user1 SET age=100 WHERE id=4”;

94 PHP 数据库编程-使用 mysqli 扩展库

mysqli 是 mysql 扩展库的增强版
在 php.ini 文件中启用 mysqli 的扩展,取掉 extension=php_mysqli.dll 文件前的注释

  1. mysqli 的稳定性和安全性,效率有所提高
  2. mysqli 支持面向对编程,同时也支持面向过程风格
header("Content-type: text/html;charset=utf-8");
//mysql操作mysql数据库(面向对象风格)
//1.创建mysql 对象
$mysqli=new mysqli("localhost","root","131978","test");
//验证是否ok
if($mysql->connect_error){
    die("Connect Error".$mysql->connect_error);
}
//2. 操作数据库(发送sql)
$sql="select * from user1";
//$res 是结果集.mysql result
$res=$mysqli->query($sql);
//var_dump($res);
//3. 处理结果;
while($row=$res->fetch_row()){
   foreach($row as $key=>$val){
        echo "--$val";
   }
   echo "<br/>";
}
//4. 关闭资源,释放内存
$res->free();
//关闭连接
$mysql->close();

处理 mysqli 资源的 4 种方法:
fetch_row()
该函数将一条结果记录返回并以一个普通索引数组的形式保存
fetch_assoc()
该函数将一条结果记录返回并以一个普通关联数组的形式保存
fetch_object() 不推荐使用
该函数将一条结果记录返回一条结果记录,各个字段需要以对象的形式访问
fetch_array() 不推荐使用
该函数可以将结果数据表中的每一行获取为一个关联数组或索引数组,或同时为关联数组和索引数组

MYSQL 语句的特别说明
如果操作的字段类型为字符串型,则要求我们要使用单引号包起来
如果操作的字段类型为数值型,则可以使用单引号包起来,也可以不用

101 $_POST

在复选框表单提交时需注意:

<form action="test.php" method="post">
<input type="checkbox" name="hobby[]" value="book">  //复选框的name值需写为数组格式
<input type="checkbox" name="hobby[]" value="write">
</form>

IE 浏览器的 cookies 文件位置在C:\Users\Jesse\AppData\Local\Microsoft\Windows\Temporary Internet Files以*.txt 文件形式保存
Chrome 浏览器 cookies 文件在C:\Users\Jesse\AppData\Local\Google\Chrome\User Data\Default但是被加密过

bool setCookie ( string $name  [, string $value [, int $expire  = 0 [,string $path [,string $domain [, bool $secure  = false [, bool $httponly  = false ]]]]]] )
//第三个参数是表示cookiess在客户端保存多长时间按秒计算
//若不写则cookies不会保存,会话结束cookies失效
//只能保存字符串
setCookie("name","jesse",time()+3600);

$name = $_COOKIE['name'];
超过有效期则 cookie 不会写入 http 首部字段,不同的键值对可以指定不同的有效时间
cookie 也可以保存中文,中文默认采用 urlencode 编码

重新设置 cookie
setCookie("name","jack".time()+60);

要删除某个键值对时,只需把过期时间改成比当前时间还小即可
setCookie('name','jesse',time()-1)
要删除全部 cookie 遍历删除

foreach($_COOKIE as $key=>$value){
    setCookie($key,"",time()-1);
}

cookie 全部删除时 cookie 文件也将被删除

117 session

session 是一种服务端技术,服务器在运行时可以为每个用户创建一个其独享的 session 文件,当用户再去访问服务器中其他 web 资源时,服务器将从各自的 session 文件中取出数据。一个会话对应一个 session 文件,

session 可以存储的数据类型有 string boolean integer double array object
要使用 session 都必须初始化session_start()

创建 session

//1.初始化session
session_start();
$_SESSION['name']="jesse";
$_SESSION['age']="25";
$arr1 = array("one","two","three");
$_SESSION['arr1']=$arr1;

获取 session

session_start();
echo "<pre>";
print_r($_SESSION);
echo "<br/>";
//通过key获取指定的值
echo $_SESSION["name"];
echo "</pre>";
//如果我们需要取出对象,则需要事先申明该对象的类的信息
require_once("dog.class.php");

更新 session

session_start();
$_SESSION['name']="jack";

删除 session 数据

//1.删除某一个session
session_start();
unset($_SESSION['name']);
//2.删除全部session
//删除当前浏览器对应的session文件
session_destroy();

session 数据默认保存 1440s,在 php.ini 中可更改
session.gc_maxlifetime = 1440
session 文件默认把文件存在服务器的 c:/window/temp,在 php.ini 中可更改
本机 session 保存路径C:\Users\apache\AppData\Local\Temp;
Session 和 Cookie 的主要区别在于:

  • 存储的位置
    • Cookie 是把用户的数据存入用户的浏览器
    • Session 技术是把用户的数据写到该用户独占的$_SESSION 中,存于服务器的相应路径下的文件中
  • 安全性
    • session 的安全性高
  • 网络传输量
    • cookie 通过网络在客户端和服务器传输,session 无需传输

如果用户禁用 cookie,服务器每次 session_start()都会创建一个全新的 session 文件,导致多个 php 页面无法共享一份 session 文件

用户禁用 cookie 可以通过一下方法解决共享 session

  • 在每个超链接 action header(“Location:***”)中拼接 SID 常量即可
  • 启用 session.use_trans_sid,这样在链接跳转的地方会自动传输 session,不推荐使用

session 垃圾回收机制
session.gc_probability = 1;
session.gc_divisor = 1000;
当某个用户操作 session 的时候使用到 sesion_start(),该函数会调用 session 垃圾回收机,其发生的概率是 session.gc_probability/session.gc_divisor。网站规模越大,这个值设置的越小越好