【问题标题】:var_dump(): Property access is not allowed yetvar_dump(): 还不允许访问属性
【发布时间】:2020-02-25 09:09:46
【问题描述】:

我有一个简单的对象映射实现

class Database
{
    protected string $Host = '';
    protected string $Port = '';
    protected string $Database = '';
    protected string $User = '';
    protected string $Password = '';
    protected object $Instance;
    protected string $sql = '';

    public function __construct()
    {
        $this->Host     = getenv("DB_HOST");
        $this->User     = getenv("DB_USERNAME");
        $this->Password = getenv("DB_PASSWORD");
        $this->Database = getenv("DB_DATABASE");
        $this->Port     = getenv("DB_PORT");
    }

    public function connect()
    {
        $con = mysqli_connect($this->Host, $this->User, $this->Password, $this->Database, $this->Port);

        if (mysqli_connect_errno()) {
            die($this->getError());
        } else {
            $this->Instance = $con;
        }

        return $this->Instance;
    }

    public function unconnect()
    {
        if ($this->Instance->close() === false) {
            die($this->getError());
        }
    }

    public function getPrimaryKey(string $table)
    {
        $this->connect();
        $this->sql = "SHOW COLUMNS FROM " . $table . ";";
        $results   = $this->Instance->query($this->sql);
        foreach ($results as $row) {
            if ($row["Key"] == "PRI") {
                $this->unconnect();
                return $row["Field"];
            }
        }
    }
}

class ObjectMapping
{
    protected string $ClassName = '';
    protected object $Database;
    protected object $Object;
    protected string $PrimaryKey = '';
    protected array  $ForeignKeys = [];

    public function __construct($object)
    {
        $this->Object = $object;

        $this->Database    = new Database();
        $classPathArray    = explode("\\", get_class($object));
        $this->ClassName   = $classPathArray[count($classPathArray) - 1];
        $this->PrimaryKey  = $this->Database->getPrimaryKey(strtolower($this->ClassName));
    }


    public function find(string $id)
    {
        var_dump($this->Object);
        exit;
    }
}

class Model
{
    protected $Mapper;

    public function __construct()
    {
        $this->Mapper = new ObjectMapping($this);
    }

    public function find($id)
    {
        $mappedObject = $this->Mapper->find($id);

        return $mappedObject;
    }
}

class Coupons extends Model
{
    public function __construct()
    {
        parent::__construct();
    }

    public function __destruct() {}
}

$coupon = new Coupons();

$coupon = $coupon->find(11);

给定上面的代码,我在转储变量var_dump($this->Object);时出错

这个错误

var_dump(): 还不允许访问属性

在跟踪时,我只会在 Database 类上调用 $this->unconnect(); 时得到这个。

参见方法getPrimaryKey()

谁有解决办法?

【问题讨论】:

  • 顺便说一句,这不是 php 7.4 相关问题。此处仅涉及类型化的属性,这不是导致此问题的原因。
  • 除此之外,如果某些对象引用不存在,则此错误将显示 someFunc(&obj) { return $obj; } 然后 someFunc($users); 如果 $users 不是错误显示的对象。我认为这是检查对象是否完全构建并且它的属性和方法是否可调用的 php 方式。

标签: php mysqli


【解决方案1】:

您正在尝试使用 mysqli 对象,该对象已使用 close() 方法关闭。 mysqli 扩展的源代码有一些检查 mysqli 对象的status 是否足够高以访问属性值。来自/ext/mysqli/mysqli_prop.c file

#define CHECK_STATUS(value) \
if (!obj->ptr || ((MYSQLI_RESOURCE *)obj->ptr)->status < value ) { \
    php_error_docref(NULL, E_WARNING, "Property access is not allowed yet"); \
    ZVAL_FALSE(retval); \
    return retval; \
} \

当状态不够高时(如MYSQLI_STATUS_VALID,取决于属性),您将收到此警告。

要解决您的问题,请勿尝试在 mysqli 对象已关闭时使用它。关闭连接后,您只需将$this-&gt;Instance 设置为null

【讨论】:

    【解决方案2】:

    编辑

    从 PHP 7.4.3 开始,这是一个 fixed bug


    除了 @Progman 所说的。这是PHP Documentation的引述

    非持久 MySQL 连接和结果集是自动的 PHP 脚本完成时销毁

    所以你实际上不需要关闭连接,但如果你这样做了,你可以在 __destruct 方法中关闭它。

    public function __destruct() {
        $this->Instance->close();
    }
    

    注意:如果启用了xdebug,它会将$this-&gt;Object 的 var_dump() 输出限制为 3 级深度。

    要更改默认值,您可以在xdebug.ini 文件中设置xdebug.var_display_max_depth

    xdebug.var_display_max_depth = -1
    

    -1 表示最大值为 1023。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      • 2019-01-06
      • 2012-03-10
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      • 2014-05-23
      相关资源
      最近更新 更多