php,静态方法重载
问题描述:
我有一个对象的方法,有时我需要调用静态,有时不需要。php,静态方法重载
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()
(这是很难看的)。
我可以推荐你去观看“Clean Code Talks”的讲座。即使这不会说服你改变你的风格,它会给你像依赖注入和单元测试的概念了坚实的介绍:
- Unit Testing
- Inheritance, Polymorphism, & Testing
- Global State and Singletons
- Don't Look For Things!
此外,你真的应该停止使用旧的mysql_*
函数作为访问MySQL的API。他们超过10岁,不再维护,社区已开始deprecation的过程。
+0
+1,在这个代码库的长期维护期间,你只会被这个双重使用代码咬伤。 – davidethell 2012-03-21 10:29:45
答
更优雅的方式可能是将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();
有这样的切换方法是非常糟糕的做法。我建议只提交方法是静态的或不是。 – deceze 2012-03-21 09:45:09
你可以尝试if(isset($ this)){} – 2013-10-16 12:07:25