Reputation: 313
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
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
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
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
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
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
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
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