php入门学习笔记(3/3):超级全局变量,面相对象

前言

最近在学习文件上传漏洞,因此接触到大量的php代码,借此机会系统地学习了一下php,整理记录如下

一、超级全局变量

Ⅰ. 全局变量

序号变量名描述
1$_GET收集来自method="get"表单中的值
2$_POST收集来自method="post"表单中的值
3$_COOKIE存储cookie信息,常用于识别用户
4$_REQUEST包含了$_GET$_POST$_COOKIE
5$_GLOBALS存有全局变量的全局组合数组
6$_SESSION存储session信息
7$_FILES用来获取通过POST方法上传文件的相关信息
8$_SERVER服务器和执行环境的信息
9_ENV环境变量

Ⅱ. $_GET

<!-- 测试表单 -->
<html>
	<head>
		<meta charset="utf-8">
		<title>PHP</title>
	</head>
	<body>
		<form action="" method="get">
			frist_name: <input type="text" name="name">
			last_name: <input type="text" name="school">
			<input type="submit" value="提交">
		</form>
	</body>
</html>
<?php
    // 当$_GET非空时,打印$_GET
    if(!empty($_GET)){
        print_r($_GET);
    }
?>

Ⅲ. $_POST

<!-- 测试表单 -->
<html>
	<head>
		<meta charset="utf-8">
		<title>PHP</title>
	</head>
	<body>
		<form action="" method="post">
			first_name: <input type="text" name="name">
			last_name: <input type="text" name="school">
			<input type="submit" value="提交">
		</form>
	</body>
</html>
<?php
    if(!empty($_POST)){
        print_r($_POST);
    }
?>

Ⅱ. $_REQUEST

<!-- 测试表单 -->
<html>
    <head>
        <meta charset="utf-8">
        <title>PHP</title>
    </head>
    <body>
        <form action="" method="get">
            first_name_a: <input type="text" name="first_name_a">
            last_name_a: <input type="text" name="last_name_a">
            <input type="submit" value="提交b">
        </form>
        <hr/ >
        <form action="" method="post">
            first_name_b: <input type="text" name="first_name_b">
            last_name_b: <input type="text" name="last_name_b">
            <input type="submit" value="提交b">
        </form>
        <hr/ >
    </body>
</html>
<?php
    if(!empty($_REQUEST)){
        print_r($_REQUEST);
    }
?>

Ⅲ. $_GLOBALS

<!-- 测试表单 -->
<html>
	<head>
		<meta charset="utf-8">
		<title>PHP</title>
	</head>
	<body>
		<form action="" method="post">
			first_name: <input type="text" name="name">
			last_name: <input type="text" name="school">
			<input type="submit" value="提交">
		</form>
	</body>
</html>
<?php
    $var = 'the_var';
    print_r($GLOBALS);
?>

二、面向对象

Ⅰ. 基本知识

1. 创建类

<?php
    class className{
        // 代码块
    }
?>

2. 对象

对象:类的一个实例

调用一个类生成一个实例的过程:实例化

<?php
    class className{
        // 代码块
    }

    $ obj_1 = new className();
    $ obj_2 = new className();
    // 此处的$obj_1, $obj_2为成员变量
?>

3. 成员变量(类属性)

<?php
    class className{
        public $name;
        public $age;
        // 此处的$name, $age为成员变量
    }

    $obj_1 = new className();
    $obj_2 = new className();
?>

4. 成员方法

<?php
    class className{
        public $name;
        public $age;
        
        public function fun_1(){
            return $this->name."<hr/>";
        }
        public function fun_2(){
            return $this->age."<hr/>";
        }
        // 此处的$fun_1, $fun_2为成员方法
        // $this是伪变量, 代表当前实例
    }

    $obj_1 = new className();
    $obj_2 = new className();
    echo $obj_1->fun_1();
    echo $obj_2->fun_2();
?>

5. 魔术方法

序号方法名描述
1__construct构造方法
2__destruct析构方法
<?php
    class className{
        public $name;
        public $age;
        
        public function __construct($name, $age){
            $this->name = $name;
            $this->age = $age;
        }
        // 这里的__construct()在调用类"刚刚开始"时,接受实例化时传入的参数,并将其赋值给某些成员变量
        public function fun_1(){
            return $this->name."<hr/>";
        }
        public function fun_2(){
            return $this->age."<hr/>";
        }
        public function __destruct(){
            echo '类调用结束,即将关闭';
        }
        // 这里的__destruct()在调用类"即将结束前"执行
    }

    $obj_1 = new className('Alice', 18);
    $obj_2 = new className('Bob', 19);
    echo $obj_1->fun_1();
    echo $obj_2->fun_2();
?>

Ⅱ. 类的三大特性

  • 继承:一个类型的对象获得另一个类型的对象的属性和方法
  • 封装:指将客观事物抽象成类,每个类对自身的数据和方法实行保护
  • 多态:指同一个实体同时具有多种形式,主要体现在类的继承体系中

1. 继承

  • 使用extends来继承父类
  • 在子类中使用parent::来访问父类
<?php
    class className{
        public $name;
        public $age;
        public $sex;

        public function __construct($name, $age, $sex){
            $this->name = $name;
            $this->age = $age;
            $this->sex = $sex;
        }
        public function fun_1(){
            return $this->name."<hr/>";
        }
        public function fun_2(){
            return $this->age."<hr/>";
        }
        public function fun_3(){
            return $this->sex."<hr/>";
        }
        public function __destruct(){
            echo '类调用结束,即将关闭';
        }
    }

    // 子类继承父类
    class newClassName_1 extends className{

    }
    // 实例化
    $obj_3 = new newClassName_1('Cindy', 20, 'Female');
    echo $obj_3->fun_3();
?>

2. 封装(访问控制)

  • public:关键词定义在类内、子类及类外都可见
  • protected:关键词定义在类内、子类可见,在类外不可见
  • private:关键词定义在类内可见,在子类和类外均不可见
<?php
    class className{
    public $name;
    // 在类内、子类及类外都可见
    protected $age;
    // 在类内、子类可见,在类外不可见
    private $sex;
    // 在类内可见,在子类和类外均不可见
    
    public function __construct($name, $age, $sex){
        $this->name = $name;
        $this->age = $age;
        $this->sex = $sex;
    }
    public function fun_1(){
        return $this->name."<hr/>";
    }
    public function fun_2(){
        return $this->age."<hr/>";
    }
    public function fun_3(){
        return $this->sex."<hr/>";
    }
    public function __destruct(){
        echo '类调用结束'."<hr/>";
    }
}
?>

3. 多态

  • 实现多态的前提是要先继承,再覆盖(也叫重写)父类方法
<?php
    class className{
        public $name;
        public $age;
        public $sex;

        public function __construct($name, $age, $sex){
            $this->name = $name;
            $this->age = $age;
            $this->sex = $sex;
        }
        public function fun_1(){
            return $this->name."<hr/>";
        }
        public function fun_2(){
            return $this->age."<hr/>";
        }
        public function fun_3(){
            return $this->sex."<hr/>";
        }
        public function __destruct(){
            echo '类调用结束,即将关闭';
        }

    }

    // 子类继承父类,再覆盖父类的方法
    class newClassName_2 extends className{
        public function fun_1(){
            return "我的名字是"."$this->name"."<hr/>";
        }
        public function fun_2(){
            return "我的名字是"."$this->age"."<hr/>";
        }
        public function fun_3(){
            return "我的性别是"."$this->sex"."<hr/>";
        }
    }

    // 实例化
    $obj_4 = new newClassName_2('Dell', 21, 'Male');
    echo $obj_4->fun_3();
?>

Ⅲ. 更多内容

1. 静态成员(static)

  • 使用static来定义静态成员
  • 可以不用实例化便可调用类的静态成员
  • 使用class_name::来访问类静态成员
<?php
    class className{
        public $name;
        public $age;
        public $sex;
        public static $hobby;
        // 静态变量$hobby

        public function __construct($name, $age, $sex){
            $this->name = $name;
            $this->age = $age;
            $this->sex = $sex;
        }
        public function fun_1(){
            return $this->name."<hr/>";
        }
        public function fun_2(){
            return $this->age."<hr/>";
        }
        public function fun_3(){
            return $this->sex."<hr/>";
        }
        public static function fun_4(){
            return className::$hobby."<hr/>";
        }
        // 静态方法fun_4()
        public function __destruct(){
            echo '类调用结束,即将关闭';
        }
    }

    // 可以直接在类的外部对$hobby赋值
    className::$hobby = 'read';
    echo "<hr/>";
    }
    // 可以直接在类的外部调用fun_4()
    echo className::fun_4();
?>

2. 抽象类(abstract)

  • 抽象方法不能有具体的内容,只需要声明了它需要哪些参数
  • 当一个类中存在至少一个被声明为抽象方法的方法时,这个类就是抽象类
  • 抽象类不能被实例化,只能被子类继承。但子类继承抽象类时,必须重写父类中的所有抽象方法
  • 这些被重写的抽象方法的访问控制不能比父类的更严格(可以同等严格,或更宽松)
  • 使用abstract来定义抽象方法/抽象类
<?php
    abstract class className{
        public $name;
        public $age;
        public $sex;

        public function __construct($name, $age, $sex){
            $this->name = $name;
            $this->age = $age;
            $this->sex = $sex;
        }
        public function fun_1(){
            return $this->name."<hr/>";
        }
        public function fun_2(){
            return $this->age."<hr/>";
        }
        public function fun_3(){
            return $this->sex."<hr/>";
        }
        abstract protected function fun_4($input);
        // fun_4()是className()类中的一个抽象方法, 访问控制是protected,不具有具体功能,但要求传入一个$input参数
        public function __destruct(){
            echo '类调用结束,即将关闭';
        }
    }

    // 子类在继承抽象父类时,重写其中的抽象方法fun_4()
    // 可以保留或放宽其访问控制,但不能变得更严格。例如,这里可以使用父类的protected,或是比其更宽松的public,但不能使用更严格的private。
    class newClassName extends className{
        public function fun_4($input){
            return $input."<hr/>";
        }
    }

    $obj = new newClassName("Alice", 18, "Female");
    echo $obj->fun_4("test");
?>

3. 接口(interface)

  • 先使用interface来定义一个接口,接口包含一些固定的方法,不过此时不用定义这些方法的具体内容
  • 使用implements来为类指定一个接口,在这之后,类就必须要实现这个接口中包含的方法
<?php

    // 使用interface来定义一个接口aInterface
    interface aInterface{
        public function add($a, $b);
        public function minus($a, $b);

    }
    // 使用implements操作符为className()类来指定一个接口aInterface
    // 如此,该类中必须要实现以下所有的方法:
    // public function add($a, $b);
    // public function minus($a, $b);
    class className implements aInterface{
        public function add($a, $b){
            return $a + $b;
        }
        public function minus($a, $b){
            if($a >= $b){
                $c = $a - $b;
            }
            else{
                $c = $b - $a;
            }
            return $c;
        }
    }

    $obj = new className();
    echo $obj->add(9, 8);
    echo "<hr/>";
    echo $obj->minus(10, -34);
?>
  • 接口常量:用const创建一个常量,在类中访问时使用interface_name::constant_name来调用
<?php

    interface aInterface{
        const CONS = "我是一个接口常量";
    
        public function add($a, $b);
    }

    class className implements aInterface{
        // 在类中直接使用接口常量
        public $cons = aInterface::CONS;
        
        public function add($a, $b){
            return $a + $b;
        }
    }

    $obj = new className();
    echo $obj->cons;
?>

4. final关键字(final类、final方法)

  • 若一个类被声明为final,那么它就不能被继承
<?php
final class className{

    public function fun(){
        return "我是一个函数";
    }
}

class newClassName extends className{
    static public function fun(){
    }
}

echo newClassName::fun();
// 运行会返回以下报错:类newClassName不能从fianl类className那里继承
// Fatal error: Class newClassName may not inherit from final class (className)
?>
  • 若一个类中的某个方法被声明为final,那么它就不能被重写
<?php
class className{

    final public function fun(){
        return "我没有被重写";
    }
}

class newClassName extends className{
    static public function fun(){
        return "我重写了fun()";
    }
}

echo newClassName::fun();
// 运行会返回以下报错:不能覆盖className中的fianl方法fun()
// Fatal error: Cannot override final method className::fun()
?>

5. 命名空间

  • 命名空间用于解决全局空间内所有常量,及函数它们名字之间的冲突
  • 命名空间内不能包含变量,它们不能被绑定到某个命名空间中
  • 同一命名空间内的成员不能重名,但处于不同命名空间的成员们可以重名(可以类比于文件系统的目录:同一目录路径下的文件不能重名)
  • 使用namespace来声明命名空间

使用以下方式(作为一条独立的语句)定义命名空间时,其范围会在到达下一个命名空间前收拢

<?php
    namespace a;
    function fun(){
        return '我是在命名空间 a 里的fun()'.'<hr/>';
    }
    namespace b;
    function fun(){
        return '我是在命名空间 b 里的fun()'.'<hr/>';
    }
    // 在同一个.php中,只要定义了命名空间,那么命名空间之外不能存在代码,否则会报错Fatal error: No code may exist outside of namespace {}

    // 我们可以把"全局代码"放在一个没有名字的命名空间中,如下
    namespace {
        echo a\fun();
        echo b\fun();
    }

?>
php官方文档更推荐使用以下方式(使用大括号{}),{}就是命名空间的范围
<?php
    namespace c{
        function fun(){
            return '我是在命名空间 c 里的fun()'.'<hr/>';
        }
    }

    namespace d{
        function fun(){
            return '我是在命名空间 d 里的fun()'.'<hr/>';
        }
    }

    namespace {
        echo c\fun();
        echo d\fun();
    }

?>

子命名空间:类比于文件系统中的文件夹,用\来反映命名空间之间的父子关系

<?php
    // 
    namespace c{
        function fun(){
            return '我是在命名空间 c 里的fun()'.'<hr/>';
        }
    }

    namespace c\e{
        function fun(){
            return '我是在命名空间 c 的子命名空间 e 里的fun()'.'<hr/>';
        }
    }

    namespace d\e{
        function fun(){
            return '我是在命名空间 d 的子命名空间 e 里的fun()'.'<hr/>';
        }
    }

    namespace {
        echo c\fun();
        echo c\e\fun();
        echo d\e\fun();
    }

?>

可以使用useas关键字来为命名空间设置别名

<?php
    namespace a\b{
    function fun(){
        return "我是一个函数"."<hr/>";
    }
}  
    namespace{
    use a\b as space;
    echo space\fun();
}
?>

以下实例使用useas关键字来解决引入文件重名的问题

<?php
    // 假设'a\'和'b\'下各有一个'c.php'(都有一个fun()来返回特定字符串,但具体内容不相同)
    // require关键字用于引入文件
    require 'a\c.php';
    require 'b\c.php';
    
    // 为a\c和b\c分别赋予别名x, y
    use a\c as x;
    use b\c as y;
    
    echo x\fun();
    echo y\fun();
}
?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neonline

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值