网安小白筑基篇五:web后端基础之PHP

发布于:2025-04-07 ⋅ 阅读:(80) ⋅ 点赞:(0)

PHP

PHP简介

PHP是什么

  • php是一种通用的脚本语言
  • 语法吸收了c语言、java和perl的特点,利于学习,使用广泛

php的优点

  • PHP 可在不同的平台上运行(Windows、Linux、Unix、Mac OS X 等)
  • PHP 与目前几乎所有的正在被使用的服务器相兼容(Apache、IIS 等)
  • PHP 提供了广泛的数据库支持
  • PHP 易于学习,并可高效地运行在服务器端

安装phpstudy和phpstorm

  • 先安装phpstudy,因为phpstorm需要phpstudy解释器

  • 设置解释器:

    打开phpstudy其他选项菜单 -> 网站根目录 -> 复制该路径

    打开phpstorm -> setting -> PHP -> CLI Interpreter ··· -> 添加Local path -> 粘贴刚才复制的目录,在WWW同级目录下找到php文件夹,选择php较高版本文件夹中的php.exe -> 连续确认即可

PHP基础语法

PHP文件基础

  • PHP 脚本可以放在文档中的任何位置。

  • PHP 脚本的开始与结束

    以<?php开始,以?>结束

  • 文件扩展名

    PHP 文件的默认文件扩展名 是 .php

  • 输出“Hello World”

    PHP 文件通常包含 HTML 标签和一 些 PHP 脚本代码。 n 如浏览器输出文本 “Hello World!” :

    <!DOCTYPE html>
    <html lang="en">
    <body>
    <h1>My First PHP Page</h1>
    
    <?php
    echo "Hello World!";
    ?>
    
    </body>
    </html>
    

    运行前要将phpStorm的解释器设置好,并且要正常启动phpstudy,否则打开网址可能显示502

  • PHP 分隔符

    中的每个代码行都必须以分号结束。分号是一种分隔符, 用于把指令集区分开来

  • PHP注释

    // 和 # 是单行注释

    多行注释

    <?php
    /*
    这是注释
     */
    
    /*
     * 这也是注释,这样写更美观而已
     */
    ?>
    

PHP变量规则

  • 变量以 $ 符号开始,后面跟着变量的名称

  • 变量名必须以字母或者下划线字符开始

  • 变量名只能包含字母、数字以及下划线(A-z、0-9和_)

  • 变量名不能包含空格

  • 变量名是区分大小写的($y 和$Y 是两个不同的变量)

  • 举例

    <!DOCTYPE html>
    <html lang="en">
    <body>
    <h1>My First PHP Page</h1>
    
    <?php
    $y=10;
    $Y=12;
    $z = $y + $Y;//注意这里也要带上$
    echo $z;
    echo "<br>";//换行
    
    $str = "Hello World!";
    echo $str;
    ?>
    
    </body>
    </html>
    

PHP运算符

自增自减运算符
  • 在这里插入图片描述
判断运算符
  • 在这里插入图片描述

    举例

    $x=100;
    $y="100";
    var_dump($x!==$y);//用来输出变量的详细信息类型,这里返回true
    
逻辑判断
  • 在这里插入图片描述

PHP流控与数组

if 条件语句

  • if 语句 - 在条件成立时执行代码

  • if…else 语句: 在条件成立时执行一块代码,条件不成立时执行另一块代码

  • if…elseif…else 语句: 在若干条件之一成立时执行一个代码块

    举例:

    <?php
    
    $x=90;
    if($x<60){
        echo "不及格";
    }else if ($x<70){
        echo "及格";
    }else if ($x<80){
        echo "良好";
    }else{
        echo "优秀";
    }
    
    ?>
    

switch 语句

  • 有选择地执行若干代码块之一

    在这里插入图片描述

    <?php
    
    $x="red";
    switch($x){
        case "red"://直接判断“red”标签是否等于$x
            echo "你喜欢的颜色是红色";
            break;
        case "blue"://直接判断“blue”标签是否等于$x
            echo "你喜欢的颜色是蓝色";
            break;
        default:
            echo "你既不喜欢红色也不喜欢蓝色";
    }
    
    ?>
    

while循环语句

  • while语句:

    只要指定的条件成立,则循环执行代码块

    在这里插入图片描述

    <?php
    
    $x=1;
    while($x<=5){
        echo "这是第几个".$x."数字";//.号是并置运算符,把他们都连接起来输出
        echo "<br>";
        $x++;
    }
    
    ?>
    
  • do…while语句:

    首先执行一次代码块,然后在指定的条件成立时 重复这个循环

    在这里插入图片描述

    <?php
    
    $x=1;
    do{
        echo "这是第几个".$x."数字";//.号是并置运算符,把他们都连接起来输出
        echo "<br>";
        $x++;
    }while($x<=5);//这里的;可有可无
    
    ?>
    

for语句

  • 循环执行代码块指定的次数

    <?php
    
    for($x=1;$x<=10;$x++){
        echo "这是第几个".$x."数字";//.号是并置运算符,把他们都连接起来输出
        echo "<br>";
    }
    
    ?>
    

php数组

概念
  • PHP数组是一种数据结构,用于存储键值对集合,其中每个键可以是整数索引或字符串索引,而值可以是任何类型的数据

    在这里插入图片描述

创建数组
  • array() 函数用于创建数组

    <?php
    //自动分配索引
    $d=array("red",123);
    echo $d[0];
    echo "<br>";
    //手动分配索引
    $e[1]="blue";
    $e[2]=321;
    echo $e[2];
    echo "<br>";
    ?>
    
  • count() 函数用于返回数组的长度(元素的数量)

    $d=array("red",123,"blue");
    $l=count($d);
    
遍历数值数组
  • 可以使用for循环遍历

    <?php
    //for循环遍历数组
    $d=array("red",123,"blue");
    for($i=0;$i<count($d);$i++){
        echo $d[$i];
        echo "<br>";
    }
    ?>
    
  • 使用foreach循环遍历

    <?php
    //foreach遍历
    foreach($d as $value){
        echo $value."<br>";
    }
    ?>
    

函数调用

  • <?php
    function name($a,$b ){
        $x=$a+$b;
        return $x;
    }
    echo name(12,24);
    ?>
    

PHP其他概念

PHP表单与web操作

  • 表单是一个包含表单元素的区域。

  • 表单的作用是搜集不同类型的用户输入,然后将用户信息提交给服务器。

  • 表单元素是允许用户在表单中(比如:文本域、下拉列表、单选框、复选框等等)输入信息的元素。

  • 用户提交数据通常是使用表单进行提交,也可以使用网址中的参数传递数据,这些数据通过HTTP请求的方式发送,使web服务器获取。PHP提供了预定义的超全局变量,用来获取HTTP请求信息,这些变量的数据类型均为数组。

    • 举例说明:

      用html制作表单,然后用php处理数据

    在这里插入图片描述

    <!DOCTYPE html>
    <html lang="en">
    <body>
    <h1>php表单与web操作</h1>
    <form method="post"><!--设定请求的方法,有密码比较敏感,用post-->
        用户:<input type="text" name="user">
        密码:<input type="password" name="password">
        <input type="submit" value="提交" name="submit1">
    </form>
    <?php
    //isset()是php内置函数,用来判断变量是否被定义,被定义则返回true
    //$_POST是php默认全局变量,它以数组的方式接受post拿到的前端数据。如果是get则用$_GET
    //var_dump()是指用数据的详细信息去输出
    if(isset($_POST['submit1'])){//$_POST['submit1']拿到表单里submit1的值
        echo "<pre>"; //echo "<pre>",这个的作用是让中间的内容以更好阅读的的方式输出
        var_dump($_POST);
        echo "<pre>";
    
        //1.接收数据
        $user=isset($_POST['user'])?$_POST['user']:null;//=的优先级最低,isset($_POST['user'])判断user是否有输入
        $password=isset($_POST['password'])?$_POST['password']:null;
    
        //2.处理数据
        function checkLogin($user,$password){//检查用户名和密码
            if($user=="admin" && $password=="password"){
                return true;
            }else{
                return false;
            }
        }
        
        //3.返回结果
        if(checkLogin($user,$password)){ //调用函数判断是否登陆成功
            echo "success";
        }else{
            echo "failed";
        }
    }
    
    ?>
    
    </body>
    </html>
    

php文件上传

  • PHP文件上传是Web开发中常见的功能之一,它允许用户通过Web表单将文件(如图片、文档、视频等)上传到服务器

  • 文件上传总共分为三步

    1. PHP脚本处理
    2. 文件验证(检查文件类型(通过MIME类型或文件扩展名)
    3. 文件大小(通过$_FILES[‘fieldname’][‘size’]))
    4. 文件存储(move_uploaded_file()函数可以将上传的文件移动到指定目录)
  • 举例说明

    第一步:在html文档中先列好表单,并将php文档在html文档中采用外嵌方式进行引入

    <!--html文件-->
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>文件上传</title>
    </head>
    <body>
    <h1>文件上传</h1>
    <!--
    前提1:必须要用post使文件更加安全,
    前提2,需要文件上传的控件enctype="multipart/form-data"-->
    <!--外部引入php文件,要在这里表单的action中注明文件路径-->
    <form action="fileupload.php" method="post" enctype="multipart/form-data">
        <input type="file" name="fileToUpload">
        <input type="submit" value="上传文件" name="submit">
        <!--这里的submit和前面表单里的action绑定了,所以点击提交后会跳转执行php文件-->
    </form>
    </body>
    </html>
    

    第二步:先在php文件中打印接收到的文件信息

    <?php
    echo "<pre>";
    //print_r用于打印具体信息
    print_r($_FILES); //$_FILES用于以数组的方式接收前端传过来的数据
    echo "</pre>";//以可视化的方式输出
    ?>
    

    执行html文件并上传文件,提交后分别得到如下页面

    在这里插入图片描述

    在这里插入图片描述

    这里展示的$_FILES的array是二维数组,这里的fileToUpload是前端定义的file的name。

    第三步:在php文件中将临时文件夹下的文件通过move_uploaded_file(src,dst)函数移动到指定目录

    <?php
    echo "<pre>";
    //print_r用于打印具体信息
    print_r($_FILES); //$_FILES用于以数组的方式接收前端传过来的数据
    echo "</pre>";//以可视化的方式输出
    
    //设置上传图片的目标路径:注意右斜线要变为反斜线,最后还要加个斜线
    $target_dir="D:/Users/Projects/PHPStormProjects/phpstorm_study/文件上传测试/";
    //$_POST['submit']接收html表单中的提交按钮事件
    //isset()用于判断是否点击按钮
    if(isset($_POST['submit'])){
        $file=$_FILES['fileToUpload'];//获取文件信息,具体信息内容为上面打印的数组
        $file_name=basename($file['name']);//basename()用于返回路径中的文件名部分
        $target_file=$target_dir.$file_name;//目标的完整路径
        //移动
        //先判断文件是否上传成功再去移动
        if(move_uploaded_file($file['tmp_name'],$target_file)){
            echo "文件上传成功,保存为: $file_name";
        }else{
            echo "文件上传失败,请检查服务器配置、目录权限或文件大小限制";
        }
    }else{
        echo "没有提交文件或者表单提交方式不正确";
    }
    ?>
    

php函数

  • 将实现某一功能的代码块封装到一个结构中,实现代码复用 只要系统在内存中能够找到对应的函数,就可以执行(函数的调用可以在函数定义之前)
  • 应用代码见<PHP表单与web操作>章节代码

php面向对象

什么是面向对象
  • 面向对象是一种编程思想,是一种以对象(Object)为中心的编程思想。面向对象编程更注重对问题的抽象和封装,通过将问题分解为一系列相互协作的对象来实现程序的功能
php类和对象
  • 类是抽象的概念,仅仅是模板。用来描述具有相同属性和方法的对象的集合。

    比如: "人"是一个类。

  • 对象是类的实例,是某一个具体的事物 。如 “张三”则是具体存在人,是一个对象

  • 例:

    类:水果(抽象事物)

    对象: 西瓜、苹果、香蕉(实实在在东西)

创建对象和类
  • 在PHP中,使用class关键字来定义一个类

    class MyClass { 
    	// 类的属性和方法
    }
    
  • 类可以包含属性(变量)和方法(函数)。属性用于存储数据,而方法用于执行操作。

    class Fruit{
    	public $name;//pubilc公有属性
    	public $color;
    	public function say() {
    		echo "名字是:" . $this->name ." ". "颜色是:" . $this- >color;
    	}
    }
    

    在类内部,可以通过$this关键字访问当前对象的属性和方法。在类外部,需要通过实例化对象来访问这些成员。new关键字直接跟类名来创建对象

  • 在类外部,需要通过实例化对象来访问这些成员。new关键字直接跟类名来创建对象

    $p1=new Fruit();//创建对象
    $p1->name="香蕉";//对对象赋值
    $p1->color="黄色";
    $p1->say();//调用方法
    

PHP魔术方法

魔术方法简介

定义
  • PHP魔术方法(Magic Methods)是一类特殊的方法,它们在PHP中具有特定的命名和功能,能够在特定情况下自动被调用(被动技能)。
命名规则
  • 魔术方法通常以两个下划线(__)开头,后跟方法名称,如__construct()、 __destruct()等。
与普通方法的区别
  • 与普通方法不同,魔术方法不需要显式调用,而是由PHP解释器在特定时机自 动触发。
魔术方法的特点与作用
  • 特点

    自动触发、具有特定功能、遵循特定命名规则。

  • 作用

    魔术方法在PHP中扮演着重要的角色,它们能够简化代码、提高代码的可读性和可维护 性,以及实现一些高级功能,如对象序列化、属性访问控制等。

构造方法与析构方法

构造方法__construct()
定义与用途
  • __construct()是一个特殊的方法,当创建新对象时,该方法会自动被调用,用于初始化对象的状态或执行其他必要的操作。
参数列表
  • __construct()方法可以接受任意数量的参数,这些参数用于在创建对象时传递初始化数据。
使用示例
  • 在类中定义__construct()方法,并在创建对象时传递参数来初始化对象的状态。

  • 在类代码内右键 -> 选择generate -> 选择override method -> 选择__construct()确定 -> 生成构造函数(或者鼠标点击类内,按住ctrl+o)

  • <?php
    class Fruit{
        public $name;//pubilc公有属性
        public $color;
        public function say() {
            echo "名字是:" . $this->name ." ". "颜色是:" . $this->color;
    	}
    
        public function __construct($name="香蕉",$color="黄色")//析构函数在对象创建时运行
        {
            $this->name=$name;//this指的是对象实例化后的那个实例
            $this->color=$color;
    
        }
    }
    $p1=new Fruit();//创建对象
    $p1->name="苹果";//对对象赋值
    $p1->color="绿色";
    $p1->say();//调用方法
    echo "<br>";
    $p2=new Fruit();
    $p2->say();//p2属性没有赋任何值,任然会显示香蕉和黄色
    ?>
    
  • 在这里插入图片描述

  • 注意事项:如果类中定义了__construct()方法,则必须在创建对象时提供所需的参数,否则会导致错误。

析构方法__destruct()
定义与用途
  • __destruct()是另一个特殊的方法,当对象不再被引用或脚本执行结束(对象)时,该方法会自动被调用,用于执行清理操作,如 释放资源、关闭数据库连接等。
参数列表
  • 参数列表 __destruct()方法不接受任何参数。
使用示例
  • 在类中定义__destruct()方法,并在其中执行必要的清理操作。

  • <?php
    class Person{
        public $name;//pubilc公有属性
        public $age;
        public $sex;
    
        public function __construct($name="",$age="22",$sex="男")
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
        public function say(){
            echo "我叫:".$this->name."、性别:".$this->sex."、年龄:".$this->age;
        }
    
        public function __destruct()
        {
            // TODO: Implement __destruct() method.
            echo "<br>我现在要把对象杀死,只是他最后的遗言,他的名字是".$this->name;
        }
    
    }
    $p1=new Person("小明");
    $p1->say();
    unset($p1);//用于销毁对象$p1
    ?>
    
    
  • 在这里插入图片描述

注意事项
  • 与construct()方法不同,由于PHP的垃圾回收机制,析构函数可能总是被调用,因此不应依赖析构函数来执行关键任务。最好是在对象使用完毕后手动执行清理操作。

对象方法调用与静态方法调用

__call()方法
触发时机
  • 当调用对象中不可访问(如protected或private修饰,或根本不存在)的方法时,会自动调用__call() 方法。
参数列表
  • 该方法接收两个参数,第一个参数是调用方法的名称(字符串类型),第二个参数是传递给该方法的 参数数组。
作用与用途
  • __call()方法允许我们在调用不存在或不可访问的方法时执行一些自定义操作,如记录日志、抛出异常 或动态调用其他方法等。
返回值
  • 该方法的返回值将作为调用不存在或不可访问方法 的返回值。
举例说明
  • <?php
    class Person{
    
        public function say(){
            echo "hello world";
        }
    
        private function eat(){
    
        }
    
        public function __call($name, $arguments)
        {
            // TODO: Implement __call() method.
            echo "你所调用的方法:".$name."(参数:";//输出不存在的方法名
            print_r($arguments);//输出调用不存在的方法时的参数列表
            echo ")不存在或不允许访问!<br>\n";//结束换行
        }
    
    }
    $p1=new Person();
    $p1->run("nihao");//不存在方法
    $p1->eat("xie","xie");//不存在方法
    $p1->say();
    ?>
    
  • 在这里插入图片描述

__callStatic()方法
触发时机
  • 当调用一个类中不可访问的静态方法时,会自动调用__callStatic()方法。
参数列表
  • 与__call()方法类似,__callStatic()方法也接收 两个参数,第一个参数是调用静态方法的名称(字符串类型),第二个参数是传递给该静态方法的参数数组。
作用与用途
  • __callStatic()方法允许我们在调用不存在或 不可访问的静态方法时执行一些自定义操作,这为我们提供了一种处理静态方法调用的灵活机制。
返回值
  • 与__call()方法类似,__callStatic()方法的返回值 将作为调用不存在或不可访问静态方法的返回值。同时, 由于该方法是静态的,因此它可以在不实例化对象的情况 下被调用。
举例说明
  • <?php
    class Person{
        //静态方法的定义
        public static function run(){
            echo "我是用的静态方法,这是我输出的内容","<br>";
        }
    
        public static function __callStatic($name, $arguments)
        {
            // TODO: Implement __callStatic() method.
            echo "你所调用的静态方法:".$name."(参数:";//输出不存在的静态方法名
            print_r($arguments);//输出调用不存在的静态方法时的参数列表
            echo ")不存在或不允许访问!<br>\n";//结束换行
        }
    }
    $p1=new Person();
    $p1::run();//引用方法不同,为::
    Person::run();//静态方法不用实例化也可以调用
    $p1::say("nihao");//不存在的方法
    Person::say("xie","xie");//不存在的方法
    ?>
    
    
  • 在这里插入图片描述

静态方法的定义与使用
  • <?php
    class Person{
        //静态方法的定义
        public static function run(){
            echo "我是用的静态方法,这是我输出的内容","<br>";
        }
    
    
    }
    //静态方法的使用
    $p1=new Person();
    $p1::run();//引用方法不同,为::
    Person::run();//静态方法不用实例化也可以调用
    ?>
    

属性访问与操作

__get()方法
触发时机
  • 读取不可访问属性

    当试图读取一个对象的不可访问(protected或private)属性时,__get()方法会 被自动调用。

参数列表
  • 参数是对象访问的私有属性的名称字符串
作用与用途
  • 数据动态处理

    通过__get()方法,可以在读取属性前对其进行动态处理,如数据格式化、验证等 。

  • 实现属性的懒加载

    __get()方法 在某些情况下,属性的值可能需要通过复杂计算或从外部资源获取,__get()方法 允许在首次访问属性时进行这些操作,实现属性的懒加载。

举例说明
  • <?php
    class Person{
        private $name;
        private $age;
    
        function __construct($name="",$age=1)
        {
            $this->name=$name;
            $this->age=$age;
        }
        //该魔术方法用于对象调用私有属性时返回
        public function __get($name)//参数是对象访问的私有属性的名称字符串
        {
            if($name=="name"){
                return $this->name;
            }else{
                return $this->age;
            }
        }
    }
    $p1=new Person("小明","23");
    echo "名字是:".$p1->name."<br>";//名字是私有属性访问不了
    echo "年龄是:".$p1->age."<br>";//年龄是私有属性访问不了
    ?>
    
  • 在这里插入图片描述
__set()方法
触发时机
  • 在类外给未定义或不可访问 的属性赋值时调用

    __set()方法用于在给未定义 的属性赋值时调用,允许动 态地创建并设置对象的属性 值。

参数列表
  • 有两个参数,第一个参数是对象访问的属性的名称字符串,第二个参数是属性的值
作用与用途
  • 控制属性赋值

    通过__set()方法,可以在属性赋值前进行验证、过滤或 转换操作,确保数据的完整性和安全性。

  • 实现属性的动态创建

    如果对象中的属性不存在,__set()方法允许动态地创建 该属性并为其赋值。

  • 与__get()方法协同工作

    结合__get()方法,可以实现对对象属性的全面控制, 包括读取、赋值和验证等操作。

    __get()方法不能赋值,__set()方法可以赋值

举例说明
  • <?php
    class Person{
        private $name;
        public $age;
    
        function __construct($name="",$age=1)
        {
            $this->name=$name;
            $this->age=$age;
        }
    
        public function say()
        {
            echo "我叫".$this->name.",今年".$this->age."岁了";
        }
    
        public function __set($name1, $value)//与__get方法的区别是,__set可以修改值
        {
            $this->$name1=$value;//这里的$name1是属性名“name”,所以$this->$name1就相当于$this->name
        }
    }
    $p1=new Person("小明","23");
    $p1->name="张三";//这里会调用__set方法
    $p1->age="60";
    $p1->say()
    ?>
    
  • 在这里插入图片描述
__isset()
触发时机
  • __isset()方法在调用 isset()或empty()函数检查对象私有或被保护的属性时自动 触发
作用与用途
  • 检查属性是否存在

    __isset()方法在调用 isset()或empty()函数检查对象属性时自动 触发,用于确定属性是否已设置且非null

  • 自定义属性检查逻辑

    通过重写__isset()方 法,可以自定义属性检查的逻辑,如检查 某个属性是否满足特定条件。

参数列表
  • 参数是对象访问属性的名称字符串
举例说明
  • <?php
    class Person{
        private $name;
        private $age;
        public $sex;
        function __construct($name="",$age=1,$sex="male")
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
    
        public function say()
        {
            echo "我叫".$this->name.",今年".$this->age."岁了"."性别是".$this->sex."<br>";
        }
    
        public function __isset($name)//参数是属性的名称字符串
        {
            echo "在类外部使用isset()函数测定私有成员{$name}时,自动调用使用"."<br>";
        }
    }
    $p1=new Person("小明","23");
    $p1->say();
    echo var_dump(empty($p1->name))."<br>";//var_dump()用于显示变量的详细信息
    echo var_dump(isset($p1->age))."<br>";//在类外部name不可见,所以返回false
    echo var_dump(isset($p1->sex))."<br>";
    ?>
    

    在这里插入图片描述

    isset(公有属性)时,不调用__isset()

__unset()方法
触发时机
  • 当使用unset()函数尝试销毁对象私有或被保护的属性时,__unset()方法会被自动调用。
参数列表
  • 参数是对象访问属性的名称字符串
作用于用途
  • 删除对象属性

    当使用unset()函数尝试销毁对象属性时,__unset()方法会被自动调用。通过重写该方法,可以自定义属性的删除行为。

  • 实现属性的安全删除

    在__unset()方法中 ,可以添加额外的逻辑来确保只有满足特定条件的属性才能被删除,从而增强对象 属性的安全性。

举例说明
  • <?php
    class Person{
        private $name;
        private $age;
        public $sex;
        function __construct($name="",$age=1,$sex="male")
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
    
        public function say()
        {
            echo "我叫".$this->name.",今年".$this->age."岁了"."性别是".$this->sex."<br>";
        }
    
        public function __set($name1, $value)//与__get方法的区别是,__set可以修改值
        {
            $this->$name1=$value;//这里的$name1是属性名“name”,所以$this->$name1就相当于$this->name
        }
    
        public function __unset($name)//参数是对象访问的私有属性的名称字符串
        {
            echo "在类外部使用unset()函数删除私有成员{$name}时,自动调用使用"."<br>";
        }
    }
    $p1=new Person("小明","23");
    unset($p1->name);
    unset($p1->age);
    unset($p1->sex);
    echo $p1->say();
    ?>
    

    在这里插入图片描述

    报错是因为say想要调用sex时,sex已经被销毁

序列化与反序列化

什么是序列化
  • 把网页、代码等转化为方便机器传输和处理的数据。

  • 反序列化就是把序列化后的结果转化为更适合人阅读的形式,要先序列化才能进行反序列化(反序列化unserialized())

  • 序列化方法serialized()

    <?php
    class Person{
        public $name;
        public $age;
        public $sex;
        function __construct($name="",$age=1,$sex="male")
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
    }
    $p1=new Person("小明");
    echo serialize($p1);//对某数据进行序列化
    
    ?>
    

    在这里插入图片描述

    O:类型Object

    6:6个字符

    “Person”:类名

    3:有3个成员变量

    s:string类型

    4:占用4个字符

    6:一个中文3个字符,占用6个字符

    i:int类型

__sleep()方法
触发时机
  • 当对象被序列化时自动调用。
参数列表
  • 此方法不接受任何参数。
功能描述
  • 该方法可以清理对象,并 返回一个包含所有应被序 列化的属性名称的数组。 如果该方法未返回任何内 容,则 NULL 被序列化, 并产生一个 E_WARNING 级别的错误。
返回值
  • 返回一个包含所有需要被序列化的属性名称的数组
举例说明
  • <?php
    class Person{
        public $name;
        public $age;
        public $sex;
        function __construct($name="",$age=1,$sex="male")
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
    
        public function __sleep()
        {
            echo "当外部使用serialized()时,会调用__sleep()方法<br>";
            return array('name');//只对类成员里的name属性进行序列化
        }
    
    }
    $p1=new Person("小明");
    echo serialize($p1);//对某数据进行序列化
    ?>
    

    在这里插入图片描述

__wakeup()方法
触发时机
  • 当反序列化一个对象时自动调用。触发时机
参数列表
  • 此方法不接受任何参数。
功能描述
  • 该方法可以重新建立数据库连接,或执行其它初始化操作。它不需要任何参数,也没有任何返回值。
举例说明
  • <?php
    class Person{
        public $name;
        public $age;
        public $sex;
        function __construct($name="",$age=1,$sex="male")
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
    
        public function __wakeup()
        {
            echo "优先调用__wakeup()<br>";
            $this->name="张三";//在该方法内可以执行其他初始化
            $this->sex="男";
        }
    }
    $p1=new Person("小明");
    var_dump(serialize($p1));//对某数据进行序列化
    echo "<br>";
    var_dump(unserialize(serialize($p1)));//对某数据进行反序列化
    ?>
    

    在这里插入图片描述

    序列化数据类型是string,反序列化数据类型是object

安全问题
  • 需要注意的是,由于 __wakeup() 方法在对象反序列化时会被自动调用,因此它可能会成为安全漏洞的入口。在处理反序列化 数据时,应谨慎验证数据来源,并确保 __wakeup() 方法中的代码是安全的。

字符串表示、调用与对象复制

__toString()方法
作用
  • 当一个对象被当作字符串对待时,该方法会自动 被调用,以便返回一个代表该对象的字符串。
使用场景
  • 在需要输出对象信息或将对象与字符串进行连接操作时,可以通过重写该方法来自定义对象的字符串表示形式。
注意事项
  • 该方法必须返回一个字符串,如果返回了非字符 串值,将会导致一个级别为 E_RECOVERABLE_ERROR的致命错误。
示例代码
  • 在一个类中定义__toString()方法,并返回代表该类实例的字符串信息。

  • <?php
    class Person{
        public $name;
        public $age;
        public $sex;
        function __construct($name="",$age=1,$sex="male")
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
    
        public function __toString()
        {
            return "对象被当成字符串时,会调用__toString()";
        }
    
    }
    $p1=new Person("小明");
    echo $p1;//在这里对象被当成字符串时,会调用__toString()
    
    ?>
    

    在这里插入图片描述

__invoke()方法
作用
  • 当尝试以调用函数的方式调用一个对象时,该方法会自动被调用。
使用场景
  • 可以通过在类中实现该方法,使得对象可以像函数一样被调用,从而实现一些特殊的功能或语法。
注意事项
  • 该方法可以接受任意数量的参数,并且可以返回一 个值。如果类中没有定义该方法,而对象又被当作 函数调用,将会导致一个致命错误。
示例代码
  • 在一个类中定义__invoke()方法,并实现一些逻辑 处理,然后在外部以函数调用的方式使用该类的实 例。

  • <?php
    class Person{
        public $name;
        public $age;
        public $sex;
        function __construct($name="",$age=1,$sex="male")
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
    
        public function __invoke()
        {
            echo "这是对象";
            return 1;//可以返回任意值,也可以不返回
        }
    
    }
    $p1=new Person("小明");
    $p1();//把对象当成函数调用时,会自动调用__invoke()方法
    
    ?>
    

    在这里插入图片描述

__clone()方法
作用
  • 当对象被复制时,该方法会自动被调用,以便进行必要的初始化工作。
使用场景
  • PHP中对象的复制是通过引用实现的,而不是通过值传递。因此,如果需要对一个对象进行深拷贝(即创建一个与原始对象完全独立的新对象 ),可以通过重写该方法来实现。
注意事项
  • 在该方法中,可以访问原始对象的所有属性和方法,并可以根据需要对新对象进行初始化。需要注意的是,如果类中没有定义该方法,而对象又被复制了,那么复制的对象将与原始对象共享相同的属性值。
示例代码
  • 在一个类中定义__clone()方法,并在其中对新对象进行必要的初始化操作,以确保新对象与原始对象完全独立。例如 ,可以为新对象重新分配内存空间、重新设置属性值等。

  • <?php
    class Person{
        public $name;
        public $age;
        public $sex;
        function __construct($name="",$age=1,$sex="male")
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
        public function say()
        {
            echo "我叫".$this->name.",今年".$this->age."岁了";
        }
    
        public function __clone()
        {
            echo "你正在进行克隆<br>";
        }
    
    
    }
    $p1=new Person("小明");
    $p2=clone $p1;//clone-对象复制方法
    echo $p2->say();
    ?>
    

    在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到