17
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.
    }
}

我想做这样的事情,但我找不到可行的方法,该属性必须是静态的......

4

7 回答 7

22

您可以通过实例化一个新对象 ( $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;但更以编程方式调用,如果类名发生更改,则不需要更新。

于 2016-10-15T05:08:51.273 回答
9

您不能从静态方法访问非静态属性。非静态属性只属于实例化对象,其中每个实例化对象都有一个单独的属性值。

我将举例说明,此代码不起作用

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();
于 2013-02-27T17:33:36.890 回答
4

正如 Marko 所说,您不能从静态方法访问非静态属性。如果可能,将您的属性更改为静态,然后您的代码就可以工作。

我做了这样的事情..

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;
      }


    }

希望它可以帮助某人:)

- 干杯

于 2013-06-26T09:53:28.327 回答
2

您可以从静态方法访问私有或受保护的属性

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

于 2019-03-20T22:08:20.997 回答
1

最好在创建对象时确定对象的规格,听起来您的对象规格与您选择的模式不匹配。

一般来说,你应该问自己,“我只需要一个对象的一个​​实例(静态)还是多个?”

对于此特定实例(连接并查询数据库),除非您需要建立与数据库的多个连接,否则不建议为数据库对象实例化对象。

因此,您有一个实例化对象与静态对象的用例。多个并发连接可能会使数据库过载,具体取决于配置以及在单次执行中创建连接的次数。

因此,考虑到这一点,有几种用于 PHP 的 OOP 设计“模式”可用于帮助对象/s 的体系结构。请参阅http://www.slideshare.net/RobertGonzalez/object-orientated-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);
    }
}
于 2014-09-11T20:01:10.357 回答
0

类似的帖子在这里

从静态方法调用非静态方法的唯一方法是拥有一个包含非静态方法的类的实例。根据定义,非静态方法是在某个类的实例上调用的方法,而静态方法属于类本身。

于 2013-02-27T17:40:27.543 回答
0

我尝试了这段代码,并且非常好用:

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

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

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

因此可以在静态模式下访问公共方法

于 2018-11-25T18:50:38.723 回答