PHP静态变量与自变量及继承
我有一个PHP模型类,它由用户和Post扩展。它们都共享一个构造函数。我为每个对象的“模式”都有一个静态变量,这样当第一个对象被实例化时,每个对象类型只能从数据库中获得一次“描述”。我想我可以在创建每个对象时使用static::schema来引用变量,但是如果我创建user然后post,post就是引用user_schema变量。如果我使用self::或static::,它就会这样做。我对差异的理解错了吗?为了得到我想要的结果,我做错了什么 下面是模型内部的构造函数和getSchema函数(类Post和用户都进行了扩展)。但是,如果在创建用户后在Post上调用getSchema,它将返回用户模式PHP静态变量与自变量及继承,php,oop,static,Php,Oop,Static,我有一个PHP模型类,它由用户和Post扩展。它们都共享一个构造函数。我为每个对象的“模式”都有一个静态变量,这样当第一个对象被实例化时,每个对象类型只能从数据库中获得一次“描述”。我想我可以在创建每个对象时使用static::schema来引用变量,但是如果我创建user然后post,post就是引用user_schema变量。如果我使用self::或static::,它就会这样做。我对差异的理解错了吗?为了得到我想要的结果,我做错了什么 下面是模型内部的构造函数和getSchema函数(类P
public function __construct($params = array())
{
$this->_tableName = static::getTableName();
$this->_className = static::getClassName();
$this->getSchema();
}
public function getSchema()
{
if (!static::$_schema) {
$query = "DESCRIBE {$this->_tableName};";
$sth = self::$db->prepare($query);
$sth->execute(static::$bindings);
$fields = $sth->fetchAll();
foreach ($fields as $info) {
static::$_schema[$info->Field] = array(
'type' => $info->Type,
'null' => $info->Null,
'key' => $info->Key,
'default' => $info->Default,
'extra' => $info->Extra
);
if ($info->Key === 'PRI') {
$this->_idField = $info->Field;
}
}
}
return static::$_schema;
}
后期静态绑定
PHP是一个非常棒的概念,当你了解它的时候。实际上,它允许您编写一个对象来处理子(扩展)类中包含的数据。然后可以更改出子类,因此父(基)类将执行不同的操作
简而言之,后期静态绑定是一个继承感知的调用。[我的引文,请随意在其他地方使用]
“模型”
简单回顾一下模型是一个层。它是MVC中的层。任何人告诉你他们有一个“用户模型”或“后模型”,都不知道他们在说什么
请随意重新限制并开始将这些(应该是什么)“哑对象”称为实体。您有一个User
实体和一个Post
实体
延伸
扩展对象时,您说的是ExtendingObject
is-aParentObject
。通过从模型
扩展用户
,您的意思是用户
是一个模型
,我们根据定义已经建立的模型是无效的。您最好使用一个通用的DB
对象,并通过
建设者
您的构造函数应该没有业务逻辑。创建对象时,就是在特定状态下创建对象。这可以通过构造函数参数、类型提示和无效标量参数的异常来实现。一旦创建了对象,然后对其运行一个方法,如getSchema()
因此,要重新设置上限:
不是用户
型号
- 模型是一个层,而不是一个对象
- 通过依赖项注入传入其他对象并遵守
- 您的构造函数应该没有业务逻辑
User
或Post
),在基类Model
中提供正确的表名
到目前为止,您有一个模型
对象,因为它是抽象的,所以无法直接实例化。因此,必须对其进行扩展以供使用。好极了,让我们来创建您的POST对象
class Post extends Model
{
const TABLE_NAME = "POST TABLE";
}
创建Post
对象时,它将使用从Model
继承的构造函数。在Model
构造函数中,它使用static::
而不是self::
来回显表名。如果它使用了self::
,它会回显“createdtable:”。相反,因为使用了static::
,继承感知版本的self::
,所以它使用继承的变量
因此调用$post=newpost的结果代码>将被“创建表:post”
假设您也创建了一个用户
对象:
class User extends Model
{
const TABLE_NAME = 'User';
}
创建每个对象时,都会回显其自己的表名:
$x = new User; // echoes User Table
$x = new Post; // echoes Post Table
结论
您不必对常量执行此操作(尽管我会这样做)。您可以使用类属性来实现这一点。但不要公开它们(全局可变状态是不好的)
有了以上信息,您应该能够轻松地拥有一个getSchema()
方法,该方法在getSchema()中使用static::SCHEMA\u NAME
Post
和User
的方法问题在于$\u模式只在User中定义,而不在Post中定义,因此始终使用相同的变量。解决方法之一是生成$\u模式和数组,并生成键get\u类($this)。所以在这个场景中使用self还是static都无关紧要?我假设static绑定到被调用的类。你的第一句话是真的。静态只是改变它查找你想要的东西的位置。若您在User中有一个函数,并使用self::它将在User中查找。如果您使用static,它将首先在Post中查找。但是,如果没有在那里定义_schema,它将退回到User.But User和Post这两个扩展模型,在这里定义了_schema变量和getSchema函数。所以我假设通过继承,每一个都会得到它自己的模式变量实例,但我猜它们都只是回到了模型,这个模型是由用户的模式设置的,因为这是我首先实例化的?
$x = new User; // echoes User Table
$x = new Post; // echoes Post Table