簡體   English   中英

從靜態方法訪問非靜態屬性

[英]Access a non-static property from a static method

class database{
    protected $db;

    protected function connect(){
        $this->db = new mysqli( /* DB info */ ); // Connecting to a database
    }
}

class example extends database{
    public function __construct(){
        $this->connect();
    }

    public static function doQuery(){
        $query = $this->db->query("theQuery");   // Not working.
        $query = self::$db->query("theQuery");   // Not working.
        $query = parent::$db->query("theQuery"); // Also not working.
    }
}

我想做類似的事情,但我找不到有效的方法,該屬性必須是靜態的...

您可以通過實例化一個新對象( $self = new static; )來訪問。 示例代碼:

class Database{

    protected $db;

    protected function connect(){
        $this->db = new mysqli( /* DB info */ ); // Connecting to a database
    }
}


class Example extends Database{

    public function __construct(){
        $this->connect();
    }

    public static function doQuery(){

        $self = new static; //OBJECT INSTANTIATION
        $query = $self->db->query("theQuery");   // working.

    }
}

這與調用$self = new Example;相同$self = new Example; 但更多的是編程,如果類名被改變,它不需要更新。

您不能從靜態方法訪問非靜態屬性。 非靜態屬性只屬於實例化對象,其中每個實例化對象都有一個單獨的屬性值。

我將舉例說明,此代碼不起作用

class Example {
    public $a;

    public function __construct($a) {
        $this->a = $a;
    }
    public static function getA() {
        return $this->a;
    }
}

$first = new Example(3);
$second = new Example(4);

// is $value equal to 3 or 4?
$value = Example::getA();

正如馬爾科所說,您不能從靜態方法訪問非靜態屬性。 如果可能,將您的屬性更改為靜態,然后您的代碼就可以工作了。

我做了這樣的事情..

class Member_DashBoard extends Page {

  public static $lapsed_id = 4; //Membership lapsed status id


    //calling static function by passing static property
    $status_custom = self::getMembershipStatusLapsed(self::$lapsed_id);//
                $status_custom_id = $status_custom['id'];



      public static function getMembershipStatusLapsed($membershipStatusId) {

        $statusDetails = array();
        $membershipStatus = new Core_MembershipStatus();
        $membershipStatus->id = $membershipStatusId;
        if ($membershipStatus->find(TRUE)) {
          Core_DAO::storeValues($membershipStatus, $statusDetails);
        }

        return $statusDetails;
      }


    }

希望它可以幫助某人:)

- 干杯

您可以從靜態方法訪問私有或受保護的屬性

class foo {
  private $x;
  static public function create()
  {
    $obj = new self();
    $obj->x = 22;
    return $obj;
  }
}

$y = foo::create();
var_dump($y);
// object(foo)[1]
//  private 'x' => int 22

// ----------------------
// this could just as easily be a normal method $bar->modify();

class bar {
  private $x;
  static public function modify(bar $bar)
  {
    $bar->x = 23;
  }
}

$bar = new bar();
bar::modify($bar);
var_dump($bar);
// object(bar)[2]
//  private 'x' => int 23

最好在創建對象時確定對象的規格,聽起來您的對象規格與您選擇的模式不匹配。

通常,您應該問自己,“我是否只需要一個對象(靜態)或多個實例?”

對於此特定實例(連接並查詢數據庫),建議不要為數據庫對象創建實例化對象,除非您需要建立到數據庫的多個連接。

因此,您有一個實例化對象與靜態對象的用例。 多個並發連接可能會使數據庫過載,具體取決於配置以及在單次執行中創建連接的次數。

因此,考慮到這一點,PHP 有幾種 OOP 設計“模式”可用於輔助對象/s 的體系結構。 請參閱http://www.slideshare.net/RobertGonzalez/object-oriented-design-patterns-for-php-presentation以了解更常見的模式。

對於一個工作示例http://ideone.com/6qxvqx

注意我將 mysqli 重命名為 mysqli2 並創建了一個假類來處理查詢,並在連接和對象創建中添加了一些跟蹤。

<?php

interface iDatabase
{
   static public function execute();
   public function instantiatedExecute();
}

abstract class database implements iDatabase
{

    protected static $conn;

    /**
     * create an instance of database that uses the same connection across all instances
     */
    final public function __construct()
    {
        self::connect();
    }

    /**
     * Connect to a database if not already connected
     */
    final protected static function connect()
    {
        if (null === self::$conn || false === (self::$conn instanceof mysqli)) {
            self::$conn = new mysqli( /* DB info */ );
            //add error checking here...
        }
        return self::$conn;
    }

   /**
    * query database connection
    */
   final public function query($query)
   {
       return self::doQuery($query);
   }

   /**
    * static query database connection
    */
   final public static function doQuery($query)
   {

      //sanitize query here if desired
      return self::connect()->query($query);
   }

}

class example extends database
{

    /**
     * example specific static execution
     */
    public static function execute($query)
    {
        self::doQuery($query);
    }

    /**
     * example specific non-static execution
     */
    public function instantiatedExecute($query)
    {
       $this->query($query);
    }
}

類似的帖子在這里

從靜態方法調用非靜態方法的唯一方法是擁有包含非靜態方法的類的實例。 根據定義,非靜態方法是在某個類的實例上調用的方法,而靜態方法屬於類本身。

我試過這段代碼,而且非常好用:

class Router{
public function route($url){
var_dump($url);
}
}

在課外甚至在課外使用此方法:

require_once('Router.php');
Router::route('/test/test');

所以可以在靜態模式下訪問公共方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM