繁体   English   中英

PHP:知道实例化是否来自静态方法吗?

[英]PHP: Know if instantiation came from static method?

说我有这样一个类:

class Person
{
    private $value;

    public function __construct()
    {
        $this->value = 'new';
    }

    public static function find( $ident )
    {
        $person = new Person();
        $person->value = 'old';

        return $person;
    }
}

如果我从静态find函数调用,如何阻止构造函数触发或以某种方式改变构造函数以不执行自身的某些构造?

我的示例的上下文与我的实际代码相同,不同之处在于,实际代码的开销非常大,以至于只有一个功能可以执行。 (许多对象可以同时存在,但是,如果静态函数调用__construct方法,则开销和加载时间会过多)。

两者都需要具有public访问器。

您可以将布尔值传递给构造函数以告诉它是否应该执行

class Person
{
    private $value;

    public function __construct($exec)
    {
        if(!$exec)
            return;
        $this->value = 'new';
        echo $this->value;  //testing
    }

    public static function find( $ident )
    {
        $person = new Person(false);
        $person->value = 'old';

        return $person;
    }
}

//$p = new Person(true);
$p = Person::find(0);

使用静态变量更新

class Person
{
    private $value;
    protected static $exec1 = true;

    public function __construct()
    {
        if(!self::$exec1)
            return;
        $this->value = 'new';
        echo $this->value;
    }

    public static function find( $ident )
    {
        self::$exec1 = false;
        $person = new Person();
        self::$exec1 = true;
        $person->value = 'old';

        return $person;
    }
}

$p = Person::find(0);

您可以在构造函数中创建一条if语句,如下所示

class Person
{
    private $value;

    public function __construct($val)
    {
        $this->value = empty($val)?"new":$val;
        if($this->value == "new") {
          //call function to do more
        }
    }

    public static function find( $ident )
    {
        $person = new Person("old");
        return $person;
    }
}

现在,您可以创建新的Person(“ old”)并留下开销,或者创建新的Person()并拥有它。

如果您不能接受@Neysor的想法,因为您无法(无论如何)更改构造函数的签名,请尝试一下(丑陋的技巧)。 请记住,这实际上是您不希望在生产代码中执行的操作。 该演示仅被假定为表明确实有可能使用调用堆栈进行条件执行。

<?php

class Dummy {
    public $was_static = null;

    public function __construct() {
        $this->was_static = false;

        // get current call stack
        $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
        // remove __construct() from stack
        array_shift($stack);
        if ($stack) {
            if ($stack[0]['class'] == __CLASS__) {
                // parent function in stack is a function of Dummy
                $this->was_static = true;
            } elseif ($stack[0]['class'] && is_subclass_of($stack[0]['class'], __CLASS__)) {
                // class the function is part of is a descendent of this class
                $this->was_static = true;
            }            
        }
    }

    public static function make() {
        return new self();
    }
}

class Dummy2 extends Dummy {
    public static function make2() {
        return new self();
    }
}

$d = new Dummy();
var_dump($d->was_static);
$d = Dummy::make();
var_dump($d->was_static);
$d = Dummy2::make2();
var_dump($d->was_static);

/*  OUTPUT:

    bool(false)
    bool(true)
    bool(true)
*/

尽管这是可能的-永远不要这样做! 如果您甚至需要考虑这些事情,那么您的API /体系结构显然需要重新设计。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM