php超全局变量特性注解

$_REQUEST

1.它最大的特点就是,$_REQUEST超全局变量为一个复合变量,它可以接受来自于$_GET、$_POST 和 $_COOKIE 传递过来的值。
2.它的设计初衷是为了方便开发者在处理用户输入时,无需关心数据是通过哪种方式提交的,都能统一获取。
3.所以如下:

1
echo $_REQUEST["file"];

我们直接在url里面加上:

1
/?file=xxx

就可以让$_REQUEST变量接收到传递的参数。

$_FILES

  • 区分:

  • 如:

  • $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];//要把临时的文件服务器路径移动到使用以文件原名称定义的文件储存路径。
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63

    * `$_FILES` 是 PHP 的另一个超全局**数组**,用于处理文件上传。

    * `$_FILES['upload_file']['name']` 表示获取用户上传文件的原始文件名。

    * `$_FILES['upload_file']['tmp_name']` 表示获取上传文件在服务器临时存储的文件名。



    # $_SESSIONS

    ## 会话和对象初始化的关系

    1. **PHP 会话的工作原理**

    在 PHP 里,会话(session)是一种用来在多个页面之间保存用户数据的机制。当你开启一个会话时,PHP 会为当前用户分配一个唯一的会话 ID,并且把这个 ID 存储在客户端的 cookie 里或者通过 URL 参数传递。服务器端会根据这个会话 ID 来查找对应的会话数据。

    当你把数据存到 `$_SESSION` 数组时,PHP 会在脚本执行结束时自动将会话数据序列化并保存到服务器的会话文件里。而在下次请求时,PHP 会在脚本开始执行时自动读取会话文件,把会话数据反序列化后再存到 `$_SESSION` 数组中。

    2. **对象的序列化与反序列化**

    - **序列化**:把对象转换为一个可以存储或者传输的字符串格式。在 PHP 中,当你把一个对象存到 `$_SESSION` 数组时,PHP 会自动对这个对象进行序列化操作。序列化过程中,PHP 会记录对象所属的类名以及对象的属性值。
    - **反序列化**:把序列化后的字符串重新转换为对象。当 PHP 从会话文件中读取数据并恢复到 `$_SESSION` 数组时,如果数据里包含对象,就会对其进行反序列化操作。在反序列化时,PHP 需要知道对象所属类的定义,这样才能正确地重建对象。

    3. **`session.auto_start = 1` 的影响**

    当 `session.auto_start` 设置为 `1` 时,PHP 会在脚本开始执行的瞬间就自动启动会话。这意味着会话数据的反序列化操作会在脚本的任何代码执行之前就完成。

    4. **错误原因详解**

    在错误范例中,由于 `session.auto_start = 1`,会话在脚本开始执行时就自动启动了,此时 PHP 会尝试对会话数据进行反序列化。然而,`Person` 类的定义是在会话启动之后才完成的,也就是说,在 PHP 尝试反序列化存储在会话中的 `Person` 对象时,它还不知道 `Person` 类的定义。因为不知道类的定义,PHP 就无法正确地重建 `Person` 对象,进而引发错误。**相当于就是说:我们都还没有一个对象被初始化,记录在`$_SESSION`超全局变量数组中,会话就开始自动反序列化。**

    **示例说明**

    假设你有以下步骤:

    1. 第一次请求页面时,脚本把一个 `Person` 对象存到了会话中,此时 `Person` 类已经定义好了,PHP 能够正常地对 `Person` 对象进行序列化并保存到会话文件。
    2. 第二次请求页面时,由于 `session.auto_start = 1`,会话在脚本开始执行时就自动启动,PHP 开始对会话数据进行反序列化。但这时 `Person` 类还未定义,PHP 找不到 `Person` 类的定义,就无法重建 `Person` 对象,最终导致错误。

    综上所述,为了避免这种错误,要么保证在会话启动前就加载所有相关的类定义,要么不把对象存到会话中,只存储对象的基本属性值。

    ## 关于该错误的避免方法

    * **个人理解:**序列化和反序列化的本质就是对以类为基础初始化的对象进行反序列化,序列化和反序列化的作用就是为了让数据在会话中持久存在。既然我们需要对对象进行序列化和反序列化,那我们一定就需要**类**作为基础,所以当在`php.ini`文件中设置`session.auto_start = 1`的时候,需要先将类定义初始化才行,因为没有类的初始化,何来基于类构建的对象的序列化和反序列化?

    * 具体案例:

    * ### 简单理解避免错误的方法

    #### 1. 保证在会话启动前加载所有相关的类定义

    在 PHP 里,如果 `session.auto_start = 1`,会话会在脚本开始执行时自动启动。当 PHP 从会话文件中恢复对象数据(反序列化)时,它需要知道对象所属类的定义,这样才能正确地重建对象。所以,要保证在会话启动前就加载所有相关的类定义,就如同盖房子前要先有设计图纸一样,有了类定义,PHP 才能依据定义把对象 “搭建” 起来。

    举个例子,若有一个 `Person` 类的对象存于会话中,在会话启动前就需引入 `Person` 类的定义文件:

    ```php
    <?php
    // 在会话启动前加载类定义
    require_once 'Person.php';

    // 此时会话已自动启动,PHP 能找到 Person 类的定义,可正确反序列化对象
    // 后续操作...
    ?>
    #### 2. 不把对象存到会话中,只存储对象的基本属性值 因为对象的反序列化依赖类定义,若不想受类定义加载顺序的影响,就可以不把对象直接存到会话中,而是只存储对象的基本属性值(如字符串、整数等简单数据类型)。这些基本属性值无需类定义就能直接存储和恢复。之后在需要使用对象时,再依据这些属性值重新创建对象。 例如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <?php
    class Person {
    public $name;
    public $age;

    public function __construct($name, $age) {
    $this->name = $name;
    $this->age = $age;
    }

    public function sayHello() {
    echo "Hello, my name is " . $this->name . " and I'm " . $this->age . " years old.";
    }
    }

    // 创建 Person 对象
    $person = new Person("John", 30);

    // 只存储对象的属性值到会话
    $_SESSION['person_name'] = $person->name;
    $_SESSION['person_age'] = $person->age;

    // 在需要使用时重新创建对象
    if (isset($_SESSION['person_name']) && isset($_SESSION['person_age'])) {
    $newPerson = new Person($_SESSION['person_name'], $_SESSION['person_age']);
    $newPerson->sayHello();
    }
    ?>
    这种方式避开了对象反序列化时对类定义的依赖,即使类定义在会话启动后才加载,也不会出现找不到类定义的错误。

session实现用户登录功能

  • 基于这篇文章PHP 会话(Session)实现用户登陆功能

  • 我就对这几个地方进行注释:

    • Cookie的作用就是对Session的IDlifeTime进行储存

    • 只要关闭浏览器,再次请求页面又得重新注册 Session。那么怎么传递 Session ID 呢?
      通过 URL 或者通过隐藏表单来传递,PHP 会自动将 Session ID 发送到 URL 上,URL 形如:http://www.test.cn/index.php?PHPSESSID= bba5b2a240a77e5b44cfa01d49cf9669,其中 URL 中的参数 PHPSESSID 就是 Session ID了

    • 比如如下代码:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <?php
      // 保存一天
      $lifeTime = 24 * 3600;
      // 取得当前 Session 名,默认为 PHPSESSID
      $sessionName = session_name();
      // 取得 Session ID
      $sessionID = $_GET[$sessionName];
      // 使用 session_id() 设置获得的 Session ID
      session_id($sessionID);

      session_set_cookie_params($lifeTime);
      session_start();
      $_SESSION['admin'] = true;
      ?>

      这里为什么要用函数session_id重新设置一遍session_id?

      这是因为:

      PHP 默认情况下,如果没有手动设置 session_id,它会根据自身的规则去查找和识别 Session ID,通常是通过 Cookie 来获取。但在客户端禁用 Cookie 或使用 IE 6.0 等特殊情况下,Cookie 可能无法正常工作,此时从 URL 中获取的 Session ID 就不会被自动识别和使用。

      所以,需要使用 session_id($sessionID) 明确地将从 URL 中获取到的 $sessionID 设置给当前脚本,让 PHP 知道应该使用这个特定的 Session ID 来关联用户的会话,从而实现基于该 Session ID 的会话数据的读取、写入和管理等操作。

  • 另外:

  • 会话session还可以用来储存对象。