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

时间:2020-01-01 16:35:58

标签: php mysqli

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

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()

有人解决吗?

2 个答案:

答案 0 :(得分: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,具体取决于属性),您会收到此警告。

要解决您的问题,请勿在{{1​​}}对象关闭时尝试对其进行处理。关闭连接后,只需将mysqli设置为$this->Instance

答案 1 :(得分:1)

编辑

从PHP 7.4.3开始,这是fixed bug


除了 @Progman 所说的以外。这是PHP Documentation

的引文

非持久性MySQL连接和结果集自动生成 PHP脚本完成后销毁

因此,您实际上不需要关闭连接,但如果需要,则可以在__destruct方法内部将其关闭。

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

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

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

xdebug.var_display_max_depth = -1

-1表示最大值1023。