WhiteBlue
WhiteBlue

Reputation: 313

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

I want to do something like that but I cant find a way that works, The property has to static...

Upvotes: 17

Views: 20895

Answers (7)

Marko D
Marko D

Reputation: 7576

You cannot access non-static properties from static methods. Non-static properties belong only to instantiated objects, where every instantiated object has a separate property value.

I will illustrate on an example, this code doesn't work:

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

Upvotes: 10

Mahbub
Mahbub

Reputation: 4932

You may access by instantiating a new object ($self = new static;). The sample 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.

    }
}

This is the same as calling $self = new Example; but more programmatically, if the class name is ever changed it does not need updating.

Upvotes: 23

GDmac
GDmac

Reputation: 880

You can access a private or protected property from a static method

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

Upvotes: 2

Mahdi Abedi
Mahdi Abedi

Reputation: 146

i tried this code and and wonderfully it's working:

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

using this method outside the class even outside the class:

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

so it's possible to access public methods in static mode

Upvotes: 0

Will B.
Will B.

Reputation: 18416

It is best to determine the specifications for the object when creating it and it sounds like your specification of the object doesn't match the pattern you chose.

Generally you should ask yourself, "Do I only need to have a single instance of an object (static) or more than one?"

For this particular instance (connect to and query a database), having an instantiated object for the database object is not advisable unless you need to establish multiple connections to the database/s.

Thusly you have a use-case for an instanced vs static object. Multiple concurrent connections could overload the database, depending on the configuration and how many times a connection is created in a single execution.

So with that in mind there are several OOP design "patterns" for PHP available to aid in the architecture of object/s. See http://www.slideshare.net/RobertGonzalez/object-oriented-design-patterns-for-php-presentation for a good walk through of the more common patterns.

For a working example http://ideone.com/6qxvqx

Note I renamed mysqli to mysqli2 and created a fake class to handle query and added some tracking to the connection and object creation.

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

Upvotes: 1

Developer
Developer

Reputation: 3998

as marko said You cannot access non-static properties from static methods. if possible change your property to static and then your code works.

I did something like this..

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


    }

hope it helps someone :)

--cheers

Upvotes: 4

happygilmore
happygilmore

Reputation: 3095

Similar post here

The only way to call a non-static method from a static method is to have an instance of the class containing the non-static method. By definition, a non-static method is one that is called ON an instance of some class, whereas a static method belongs to the class itself.

Upvotes: 0

Related Questions