簡體   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