17 votes

Accéder à une propriété non statique à partir d'une méthode statique

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

Je voudrais faire quelque chose comme ça mais je n'arrive pas à trouver un moyen qui fonctionne....

23voto

Mahbub Points 1931

Vous pouvez y accéder en instanciant un nouvel objet ( $self = new static; ). L'exemple de code :

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.

    }
}

Cela revient à appeler $self = new Example; mais de manière plus programmatique, si le nom de la classe est modifié, il n'est pas nécessaire de le mettre à jour.

10voto

Marko D Points 3926

Vous ne pouvez pas accéder aux propriétés non statiques à partir de méthodes statiques. Les propriétés non statiques n'appartiennent qu'aux objets instanciés, où chaque objet instancié possède une valeur de propriété distincte.

Je vais illustrer mon propos par un exemple, ce code ne fonctionne pas :

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();

4voto

Developer Points 401

Comme l'a dit Marko Vous ne pouvez pas accéder à des propriétés non statiques à partir de méthodes statiques. Si possible, changez votre propriété en statique et votre code fonctionnera.

J'ai fait quelque chose comme ça

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

    }

J'espère que cela aidera quelqu'un :)

--chanteurs

2voto

GDmac Points 423

Vous pouvez accéder à une propriété privée ou protégée à partir d'une méthode statique

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

1voto

fyrye Points 759

Il est préférable de déterminer les spécifications de l'objet lors de sa création et il semble que les spécifications de l'objet ne correspondent pas au modèle que vous avez choisi.

En règle générale, vous devez vous poser la question suivante : "Ai-je besoin d'une seule instance d'un objet (statique) ou de plusieurs ?".

Pour ce cas particulier (se connecter à une base de données et l'interroger), il n'est pas conseillé d'avoir un objet instancié pour l'objet base de données, à moins que vous ne deviez établir plusieurs connexions avec la ou les base(s) de données.

Vous avez donc un cas d'utilisation d'un objet instancié par rapport à un objet statique. Plusieurs connexions simultanées peuvent surcharger la base de données, en fonction de la configuration et du nombre de fois qu'une connexion est créée au cours d'une seule exécution.

C'est pourquoi il existe plusieurs modèles de conception OOP pour PHP afin de faciliter l'architecture des objets. Voir http://www.slideshare.net/RobertGonzalez/object-oriented-design-patterns-for-php-presentation pour une bonne présentation des modèles les plus courants.

Pour un exemple concret http://ideone.com/6qxvqx

Note J'ai renommé mysqli en mysqli2 et j'ai créé une fausse classe pour gérer les requêtes et j'ai ajouté un certain suivi à la connexion et à la création d'objets.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X