Проверить, выполняется ли функция из статического контекста
Я пишу класс 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.
}
}
5 ответов
когда метод объявлен как static, не только волшебная переменная $this недоступно (возвращает NULL), но это невозможно сказать, была ли функция фактически вызывается из статического контекста. Трассировка означает, что для статического метод, вызывающий $object - >method () внутренне переведены на className:: method () во время выполнения.
вы можете проверить нестатический доступ, только если вы не заставляете метод быть только статическим. Оставьте static
ключевое слово из объявления функции и теста с:
public function myFunction(){
if(!isset($this)) {
(его все еще можно назвать статической функцией, даже если вы не объявили ее таковой.)
Итог - Не создавайте классы, которые содержат только статические функции. Это не ООП, это просто ваш старый процедурный код, маскирующийся под ООП
если вы выполняете функции статически, нет $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 );
таким образом, Вы разделяете одно и то же соединение со всеми классами, которые его требуют. А теперь класс!--4--> не несет ответственности за подключение или должен знать ваши детали подключения.
Решение 1: Сделайте $db
переменная private и используйте ее через геттер.
решение 2: реализуйте одноэлементный шаблон на стороне dbal.
даже при вызове статического метода из экземпляра (не рекомендуется), вы не имеете
доступ к $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
однако можно определить статически, поэтому его нужно создать только один раз, независимо от того, является ли объект экземпляром или нет.