Доступ к нестатистическому свойству из статического метода

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

Я хочу сделать что-то подобное, но я не могу найти способ, который работает, свойство должно статично...

Ответ 1

Вы можете получить доступ, создав экземпляр нового объекта ($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; но более программно, если имя класса когда-либо изменяется, оно не нуждается в обновлении.

Ответ 2

Вы не можете получить доступ к нестационарным свойствам из статических методов. Нестатические свойства относятся только к экземпляру объектов, где каждый экземпляр объекта имеет отдельное значение свойства.

Я проиллюстрирую на примере этот код не работает:

class Example {
    public $a;

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

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

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

Ответ 3

as marko said Вы не можете получить доступ к нестационарным свойствам из статических методов. если возможно, измените свое свойство на статичное, а затем ваш код будет работать.

Я сделал что-то вроде этого.

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


    }

надеюсь, что это кому-то поможет:)

- веселит

Ответ 4

Похожие сообщения здесь

Единственным способом вызова нестатического метода из статического метода является наличие экземпляра класса, содержащего нестатический метод. По определению, нестатический метод - это тот, который называется ON экземпляром некоторого класса, тогда как статический метод принадлежит самому классу.

Ответ 5

Лучше всего определять спецификации для объекта при его создании, и похоже, что ваша спецификация объекта не соответствует выбранному шаблону.

Как правило, вы должны спросить себя: "Мне нужен только один экземпляр объекта (статический) или более одного?"

Для этого конкретного экземпляра (подключение к базе данных и запрос к нему) использование объекта-объекта для объекта базы данных нецелесообразно, если вам не нужно устанавливать несколько подключений к базе данных /s.

Таким образом, у вас есть прецедент для объекта instanced vs static. Несколько одновременных подключений могут перегружать базу данных в зависимости от конфигурации и количества раз, когда соединение создается за одно исполнение.

Таким образом, имея в виду, существует несколько шаблонов проектирования ООП для PHP, доступных для поддержки архитектуры объекта/с. См. 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);
    }
}

Ответ 6

я попробовал этот код, и он прекрасно работает:

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

используя этот метод вне класса, даже вне класса:

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

так что можно получить доступ к публичным методам в статическом режиме

Ответ 7

Вы можете получить доступ к закрытому или защищенному свойству из статического метода.

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