php,静态方法重载


php, static method overloading

我有一个带有方法的对象,有时我需要将其调用为静态,有时则不需要。

class MYOBJECT
{
  private $group_id;
  public function SetGroupId($_id) { $this->group_id = $_id; }
  public static function GetGroupName($_id=NULL)
  {
    // is there any way to implement condition like this?
    if( _called_as_static ) $id = $_id;
    else $id = $this->group_id;
    $query mysql_query("SELECT name FROM group WHERE id = $id");
    list($name) = mysql_fetch_array($query);
    return $name;
  }
}
$obj = new MYOBJECT;
$obj->SetGroupId(4);
// should work both ways
$name = $obj->GetGroupName();
$name = MYOBJECT::GetGroupName(4);

我是这样解决的:

public static function MYOBJECT::GetGroupName($_id=NULL)
{
  if( is_object($_id) ) $_id = $_id->GetGroupId();
  ...
}
$name = MYOBJECT:GetGroupName(4);
$name = $obj->GetGroupName($obj);

但是,还有什么更优雅的吗?

您应该避免在一般情况下使用静态调用[article]。

在这种情况下,你们甚至会让情况变得更糟,因为你们显然期望同一个函数有两种不同的行为。这就是拥有两个独立功能的充分理由。此外,并没有"更优雅"的方法可以做到这一点。唯一可以改变的是假设,无论何时用参数调用函数,它都是静态的。其他替代方案包括反射(较慢)或debug_backtrace()(非常难看)。

我可以推荐您观看"清洁代码讲座"中的一些讲座。即使这不能说服你改变你的风格,它也会给你一个坚实的概念介绍,比如依赖注入和单元测试:

  • 单元测试
  • 遗传,多态性,&测试
  • 全球状态与辛格尔顿
  • 不要找东西

此外,您真的应该停止使用旧的mysql_*函数作为访问MySQL的API。他们已经超过10岁了,不再被维护,社区已经开始了贬低的过程。

您应该仔细研究一下替代方案:PDO和MySQLi。它们都提供了使用准备好的语句的能力。

一种更优雅的方法可能是将group_id=>group_name隔离为一个静态方法。而不仅仅是重复使用所述方法

<?php
class MYOBJECT
{
  private $group_id;
  public function SetGroupId($_id) { $this->group_id = $_id; }
  public function GetGroupName() { 
    return self::GetGroupNameByID($this->group_id);
  }
  public function GetGroupId() { return $this->group_id; }
  public static function GetGroupNameByID($_id)
  {
    // Check if $_id is MYOBJECT
    $id = $_id instanceof self ? $_id->GetGroupID() : $_id;
    $query mysql_query("SELECT name FROM group WHERE id = $id");
    list($name) = mysql_fetch_array($query);
    return $name;
  }
}
$name = MYOBJECT::GetGroupNameByID(4);
$name = MYOBJECT::GetGroupNameByID($obj);
$name = $object->GetGroupName();