You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP Session存储含私有属性的对象数组刷新后失效问题

问题根源

问题核心是类属性声明错误,和Session序列化机制本身无关。
你在Month类中将$mes、$year声明为了private static静态属性:

class Month{
    private static $mes;
    private static $year;
    // 其余代码省略
}

静态属性归属于类本身,不归属于单个对象实例,PHP在序列化/反序列化Session中的对象时,只会处理实例属性,不会保存和恢复静态属性的值:

  • 首次访问页面时,构造函数给$this->mes、$this->year赋值时,类中没有声明对应的实例属性,PHP会自动为对象创建动态公共属性,所以首次var_dump看到的属性是无类访问标记的["mes"]=> string(1) "4"格式,方法调用也能正常读值。
  • 刷新页面时,PHP从Session存储中反序列化恢复Month对象,之前动态生成的公共属性不会被还原(类中仅声明了静态私有属性,无对应实例属性),反序列化后的对象实例属性为空,调用getMes()、toString()等方法时无法取到正确值,功能随即异常。
    你之前将属性改为public即可正常运行,本质是误将静态属性改成了实例属性,符合序列化要求——private修饰的实例属性本身完全可以正常序列化存入Session,和访问权限修饰符没有关系。
修复方案
  1. 修正Month类的属性声明,去掉static关键字,将静态属性改为私有实例属性:
<?php
class Month{
    // 移除static关键字,声明为私有实例属性
    private $mes;
    private $year;

    static function void(){
        return new self(null, null);
    }

    function __construct($mes, $year){
        $this->mes = $mes;
        $this->year = $year;
    }

    // GETTERS 
    public function getMes(){
        return $this->mes;
    }

    public function getYear(){
        return $this->year;
    }

    //SETTERS
    public function setMes($mes){
        $this->mes = $mes;
    }

   public function setYear($year){
        $this->year = $year;
    }

    //Métodos
    public function toString(){
        switch ($this->mes) {
            case 1:
                return "Enero - ".$this->year;
            case 2:
                return "Febrero - ".$this->year;
            case 3:
                return "Marzo - ".$this->year;
            case 4:
                return "Abril - ".$this->year;
            case 5:
                return "Mayo - ".$this->year;
            case 6:
                return "Junio - ".$this->year;
            case 7:
                return "Julio - ".$this->year;
            case 8:
                return "Agosto - ".$this->year;
            case 9:
                return "Septiembre - ".$this->year;
            case 10:
                return "Octubre - ".$this->year;
            case 11:
                return "Noviembre - ".$this->year;
            case 12:
                return "Diciembre - ".$this->year;
            default:
                return "";
        }
    }
}
  1. 清理旧的错误Session数据:
  • 可临时在session_start()后添加一行$_SESSION = [];,刷新一次页面清除旧缓存后再删除该行代码即可;
  • 也可以直接清除浏览器对应站点的Cookie,让服务端生成全新Session。
验证说明

修改完成后,无论首次访问还是刷新页面,var_dump输出的对象属性都会是带私有标记的["mes":"Month":private]格式,调用getMes()、toString()方法均可正常取值,不需要将属性改为public,也不需要额外编写自定义序列化逻辑,PHP原生支持私有属性的对象在Session中正常存取。

内容的提问来源于stack exchange,提问作者icortazar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 03:12:34