我正在编写一个PHP类,并包含了一些用于快速访问的静态函数,因为它们通常使用并且函数简单。但是,它们确实使用其中的一个对象来访问数据库。在整个代码中,我可能会从静态和非静态上下文中使用这些静态方法,因此我希望能够测试是否从静态或非静态上下文中调用函数,以便避免在从非静态上下文中调用函数(此实例对象和要静态使用的函数中的实例对象)时创建重复对象。是否有任何方法,我可以在函数中测试这一点,以便我可以使用实例对象,如果函数从非静态上下文中调用,并创建它自己的对象,如果函数从静态上下文中调用?
代码示例:
class MyClass {
private $db;
function __constuct(){
$this->db = new DBConnect();
}
public static function myFunction(){
if(/* Is static */){
$db = new DBConnect();
} else {
$db =& $this->db;
}
// Do processing with $db, etc.
}
}
http://php.net/manual/en/language.oop5.static.php当一个方法被声明为静态时,不仅魔术变量$this不可用(返回NULL),但它是无法判断函数是否实际上是从静态上下文中调用的。回溯意味着对于静态代码方法,调用$object-> Method()是内部翻译为className::method()在运行时
只有在不强制方法仅为静态的情况下才能检查非静态访问。从函数声明中去掉static
关键字,并使用:
public function myFunction(){
if(!isset($this)) {
(它仍然可以作为静态函数调用,即使您没有这样声明它)
底线-不要创建只包含静态函数的类。它不是OOP,它只是你旧的过程代码伪装成OOP
如果你静态执行函数,没有$this,因为没有对象。您最终也将使private $db
成为静态变量,并将其用作self::$db
。
也就是说,我建议放弃这种模式,并编写如下:
class Foobar
{
protected $_connection = null;
public function __construct( DBConnect $db )
{
$this->_connection = $db;
}
public function some_function()
{
$db = $this->_connection;
// Do processing with $db, etc.
}
}
你像这样使用这个类:
$db = new DBConnection( /* your password , user , host , etc. */);
$stuff = new FooBar( $db );
$stuff->some_function();
$blah = new DifferentClass( $db );
这样就可以与所有需要它的类共享相同的连接。现在FooBar
类不负责连接或者必须知道您的连接细节。
解决方案1:将$db
变量设为私有,并通过getter使用它
解决方案2:在数据库端实现一个单例模式
即使从实例调用静态方法(不推荐),也不需要访问$this
,所以你的类是致命的。
class sns {
public static function moo() {
var_dump($this->fng);
}
public function goo() {
var_dump($this);
}
}
sns::moo();
$_ = new sns;
$_->moo();
$_->goo();
正如另一个海报从php手册中指出的。
然而, $db
可以静态定义,所以它只需要创建一次,而不管对象是否是实例。