我正在编写一个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.
}
}
答案 0 :(得分:8)
当方法声明为static时, 不仅是魔法变量$ this 不可用(返回NULL),但确实如此 无法判断这个功能是否合适 实际上是从静态上下文调用的。 回溯意味着对于静态 方法,调用$ object-> method()是 内部翻译为 运行时的className :: method()。
答案 1 :(得分:3)
只有在不强制该方法仅为静态时,才能检查非静态访问。从函数声明中省略static
关键字并使用:
public function myFunction(){
if(!isset($this)) {
(它仍然可以被称为静态函数,即使你没有这样声明它。)
答案 2 :(得分:1)
底线 - 不要创建仅包含静态函数的类。它不是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
不负责建立连接或必须知道您的连接详细信息。
答案 3 :(得分:0)
解决方案1:将$db
变量设为私有,并通过getter使用它。
解决方案2:在dbal侧实施单例模式。
答案 4 :(得分:0)
即使从实例调用静态方法(不推荐),也没有
访问$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
可以静态定义,因此无论对象是否是实例,都只需要创建一次。