I am writing a PHP class and have included a couple static functions for quick access as they are common for use and are simple in function. However they do use an object in them for database access. I will likely be using these static methods from both a static and non-static context throughout my code so I want to be able to test whether the function was called from a static or non-static context so that I can avoid creating a duplicate object if the function was called from a non-static context (this instance object and the one within the function to be used statically). Is there any way that I can test this i开发者_运维技巧n the function so that I can use the instance object if the function is called from a non-static context and create it's own object if the function is called from a static context?
Code Example:
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.
}
}
When a method is declared as static, not only is the magic variable $this unavailable (returns NULL), but it is impossible to tell if the function was actually called from a static context. A backtrace implies that for a static method, calling $object->method() is internally translated to className::method() at run time.
http://php.net/manual/en/language.oop5.static.php
You can check for non-static access only if you do not force the method to be static-only. Leave out the static
keyword from the function declaration and test with:
public function myFunction(){
if(!isset($this)) {
(It can still be called as static function, even though you did not declare it as such.)
Bottom line - don't make classes which contain only static functions. It is not OOP, it is just your old procedural code masquerading as oop
If you are executing functions statically, there is no $this, as there is no object.
You will end up making the private $db
a static variable too , and use it as self::$db
.
That said, i would recommend to drop this pattern and write something like :
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.
}
}
And you use this class like this :
$db = new DBConnection( /* your password , user , host , etc. */);
$stuff = new FooBar( $db );
$stuff->some_function();
$blah = new DifferentClass( $db );
This way you share the same connection with all the classes that require it. And now the class FooBar
is not responsible for making connection or has to know your connection details.
Solution 1: Make the $db
variable private, and use it via a getter.
Solution 2: Implement a singleton pattern on the dbal side.
Even when calling a static method from an instance (not recommended), you do not have
access to $this
, so your class will fatal.
class sns {
public static function moo() {
var_dump($this->fng);
}
public function goo() {
var_dump($this);
}
}
sns::moo();
$_ = new sns;
$_->moo();
$_->goo();
As another poster has indicated from the php manual.
$db
however can be defined statically instead so it only needs to be created once regardless of whether the object is an instance or not.
精彩评论