我有一个简单的对象映射实现
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()
。
有人解决吗?
答案 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。