PHP5.3中的抽象静态函数
我是PHP的新手,我正在寻找实现一些数据库访问代码的最佳方法。我试图创建一些简单的数据库访问对象——每个表都有自己的类,类的每个实例代表表中的一行,您知道这个钻取 我有一些代码似乎在工作,但我在网上看到的一些东西让我担心我的方法可能是错误的。既然“我能做到这一点吗?”和“我应该做到这一点吗?”是两个不同的问题,我希望一些PHP老手能插话 我当前的策略是创建一个包含所有公共代码的基本抽象表类,然后让每个表示单个表的类对其进行扩展 我主要关注的是以下代码:PHP5.3中的抽象静态函数,php,design-patterns,Php,Design Patterns,我是PHP的新手,我正在寻找实现一些数据库访问代码的最佳方法。我试图创建一些简单的数据库访问对象——每个表都有自己的类,类的每个实例代表表中的一行,您知道这个钻取 我有一些代码似乎在工作,但我在网上看到的一些东西让我担心我的方法可能是错误的。既然“我能做到这一点吗?”和“我应该做到这一点吗?”是两个不同的问题,我希望一些PHP老手能插话 我当前的策略是创建一个包含所有公共代码的基本抽象表类,然后让每个表示单个表的类对其进行扩展 我主要关注的是以下代码: abstract class Table
abstract class Table {
protected abstract static function get_fields();
protected abstract static function get_primary_key();
protected abstract static function get_table_name();
其思想是,每个实现类将定义字段名、主键、表名等,然后table类将使用这些函数来填充特定的空格,如下所示:
static function insert($values) {
$field_list = array();
$value_list = array();
foreach (static::get_fields() as $field_name) {
if (isset($values[$field_name])) {
$field_list[] = $field_name;
$value_list[] = self::escape($values[$field_name]);
}
}
$field_string = join(", ", $field_list);
$value_string = "'" . join("', '", $value_list) . "'";
$sql = "insert into " . static::get_table_name() . " ($field_string) values ($value_string)";
正如您所看到的,关键是我访问这些静态抽象
函数的方法是在它们前面加上静态::
。据我所知,它正在发挥作用
但是,对的公认答案表明,抽象静态
函数在5.3中仍然是不允许的
所以,我想知道该怎么做。答案错了吗?
抽象静态
函数现在被认为是完全合法的PHP代码吗?我是否在代码中做了一些不可取的事情?还有另一种方法我应该考虑吗? < P>抽象函数在任何语言中都不会是静态的。
静态函数提供功能,即使没有实例
抽象函数不提供任何函数性
从逻辑上讲,您不能使用抽象的静态函数,因为抽象的静态函数将永远提供函数性
B扩展A 当您在B上下文中调用静态函数时,它将在上下文中运行(导致静态) 但是,在上下文中,这个函数是抽象的,不允许调用它。下面是您的示例
abstract class Table implements iTable {
public static function insert() {
$class = get_called_class();
$sql = 'INSERT INTO '.$class::get_class_name();
echo $sql;
}
}
interface iTable {
static function get_class_name();
}
class ConcreteTable extends Table
{
public function ConcreteTable() {}
static function get_class_name() {
return 'ConcreteTable';
}
}
$t = new ConcreteTable();
$t::insert();
这个例子尊重对象范例,并且您确信即使PHP停止支持后期静态绑定(我认为这是PHP特有的),它也能工作
编辑:两个答案都表明,抽象类引入接口以及从抽象类扩展的类是未知的。遵循模板模式,即使使用静态函数,这在PHP中也是可能的(尽管有一个很好的理由,它会给出严格的标准警告)。概念证明:
abstract class Table
{
abstract static function get_class_name();
public static function insert() {
printf('INSERT INTO %s', static::get_class_name());
}
}
class ConcreteTable extends Table
{
public static function get_class_name() {
return 'ConcreteTable';
}
}
ConcreteTable::insert();
如果删除此处的静态关键字,您实际上会得到有用的(也是一种标准的操作方式)代码:
所以,对于我是否在做一些不可取的事情这个问题,这将是一个“是”的回答。你对PHP为什么会让我逍遥法外有什么见解吗?或者你对另一种不那么自相矛盾的方法有什么建议吗?你使用的对象范例是错误的。我同意abstract关键字,但这3个函数总是在实例上工作,它们不应该是静态的。为什么它们不应该是静态的?用户对象的字段列表将在所有用户对象中保持一致;它不依赖于实例。类似地,我认为我应该能够调用类上的“insert”或“select”,而不是实例化的对象。如果永远不会调用(也永远不会调用)静态插入函数,为什么要将其放在上下文中?因为该插入函数的代码在所有B类中基本相同——所有更改都是表名和字段名。在这里,继承模型对我来说非常有意义。你觉得我忽略了一个更合理的方法吗?如果你说“你知道交易”,我可以肯定一件事:交易是不使用静态函数。如果您认为是这样的话,那一定是null checkers协议,因为静态函数不能很好地处理您喜欢使用的继承。此外,我建议你读一读诗集,我是说,你知道这本书的内容,对吧?@hakre:这种敌意和屈尊从何而来?“你知道演练”是指一种相当标准的数据库内容建模方法,我认为这种方法不值得重复。请提供参考,说明你所描述的是一种相当标准的方法。PHP有很多ORM框架,包括(但不限于)和。这是一个非常复杂的轮子;你确定要重新发明它吗?@凤凰城:老实说?主啊,没有。但我的选择令人不快;我们没有一个适合生产服务器的系统管理员,而PHP安装就在那里。。。我会很好地称之为“功能灯”。安装任何有趣的东西对我来说都太白痴了。我宁愿自己做轮子,尽管它可能不完美,也不愿在雪橇上拖拉。嗯,为什么里面有明显多余的
新的——你只需要一根绳子,例如$t='ConcretTable'代码>为什么不让它依赖于使用\uuuu函数\uuuu
常量读取的某个函数名?或者更常见的情况是:将表名添加为受保护的属性(或SQL查询)?邀请一个接口到参与方似乎给了我想要的行为,而没有任何逻辑悖论干扰我的代码。我向你表示感谢。:-)@hakre:new
只是一个名为类()的Java habitget,它可以代替命名类所代表的表的需要。因此,您可以有一个getTableName(),它返回get_,称为_class(),可以由单个类重写以自定义表名
abstract class Table
{
protected $table = NULL;
public function insert() {
printf('INSERT INTO %s', $this->table);
}
}
class ConcreteTable extends Table
{
protected $table = 'ConcreteTable';
}
$table = new ConcreteTable();
...
$table->insert();