I am working on a PHP library in Laravel. I want to call a variable that is global to my function and I get this error.
Using $this when not in object context
Where am I missing?
class ConfigurationProvider implements ConfigurationProvider
{
protected $conf;
private function getCredentials()
{
return $this->conf;
}
}
My Controller
public function testApi(){
$object = ConfigurationProvider::getCredentials();
return $object;
}
You're treating getCredentials() as a static method. Static method do not have access to the object. Just static properties.
class ConfigurationProvider implements ConfigurationProvider
{
protected static $conf;
private static function getCredentials()
{
return self::$conf;
}
}
$object = ConfigurationProvider::getCredentials();
Instantiate your object, then call the method
public function testApi()
{
$configProvider = new ConfigurationProvider();
$object = $configProvider->getCredentials();
return $object;
}
Related
I have class with my logic.
class BlogApp
class BlogApp
{
public static $app;
public function __construct()
{
self::$app = Registry::instance();
$this->getParams();
}
class Registry
class Registry
{
use TSingletone;
protected static $properties = [];
public function setProperty($name, $value)
{
self::$properties[$name] = $value;
}
public function getProperty($name)
{
if (isset(self::$properties[$name])) {
return self::$properties[$name];
}
return null;
}
public function getProperties()
{
return self::$properties;
}
I want to use my class BlogApp { } anywhere in the controllers to store properties. For example
BlogApp::$app->setProperty('img_width', 1280);
$wmax = BlogApp::$app->getProperty('img_width');
and my public/index.php
new \App\BlogApp();
but I have exception
Call to a member function getProperty() on null
if I use this one
$d = new BlogApp();
$d::$app->getProperty('img_width');
No problem. But I want
$wmax = BlogApp::$app->getProperty('img_width');
where is my mistake ?
You are creating an object of the Registry within constructor in BlogApp class, so to call the getProperty method, you have to need to create an object of BlogApp.
However, if you want to call the getProperty function with a reference to the class, then don't create an instance of Registry in the BlogApp constructor.
class BlogApp
{
public static $app;
// Create a function call get_instance
public static function get_instance()
{
// create instance of Registry class
self::$app = Registry::instance();
self::getParams();
return self::$app;
}
}
/*
* Call the getProperty funtion with reference of class.
* 1 - Object of the Registry is Creating When you call the static function get_instance.
* 2 - Once the object is created you can call the getProperty function.
*/
$wmax = BlogApp::get_instance()->getProperty('img_width');
I have an Connection class which connects to a specific "Service". You call the specific Service such as mysqli or PDO when instantiating the class.
class Connection
{
private $service;
private $state = null;
public function __construct(Service $service) {
$this->service = $service;
}
public function initialize() {
....
}
public function destruct() {
....
}
//Maybe some getters and setters
}
In the Service class there is an getObject() method, this contains the object which has to be instantiated to make a connection to a Database or something else.
There is also an getInstance() method. This is used for returning the object in the getObject method if it isnt already instantiated.
abstract class Service
{
public static function getInstance() {
$instance = null;
if ($instance == null) {
$instance = self::getObject();
}
return $instance;
}
/**
* #return object Returns the object where the service should start from.
*/
public abstract function getObject();
}
Here is an example of an Service class.
class MySQLService extends Service
{
public function getObject() {
return new mysqli('127.0.0.1', 'root', '', 'db');
}
}
Problem
When using this code like this:
$connection = new Connection(MySQLService::getInstance());
$connection->initialize();
It comes with this error:
Fatal error: Cannot call abstract method Service::getObject() in
C:\Users.\Documents...\Service.php on line 18
Questions
How does it come that this error appears?
How can I solve this error?
How can I call a function from a class that extends the Service class?
In order to get this working you need to declare the getObject methods as the static methods they are.
In Service:
public abstract function getObject()
Should be:
public static function getObject() {}
(Sorry, you can't have a static abstract)
In MySQLService:
public function getObject() {
Should be:
public static function getObject() {
You can then direct the call to the right class by using the following:
public static function getInstance() {
static $instance = null;
if ($instance == null) {
$instance = static::getObject();
}
return $instance;
}
Note - you missed the static keyword from the instance variable too.
class singleton:
class Singleton
{
private static $_myself;
private function __construct(){}
public static function getInstance()
{
if(!isset(self::$_myself))
{
$obj = __CLASS__;
self::$_myself = new $obj;
}
return self::$_myself;
}
}
my class:
class MyApp extends Singleton
{
public function show()
{
echo 'show';
}
}
MyApp::getInstance()->show();
but not working, this error:
Call to undefined method Singleton::show()
somebody can help me?
Because you're returning a Singleton class (as you can see by your error), but should be returning a MyApp class. You can do this by using the late static binding method get_called_class() introduced in PHP 5.3:
public static function getInstance()
{
if(!isset(self::$_myself))
{
//__CLASS__ = Singleton | get_called_class() = MyApp
$obj = get_called_class();
self::$_myself = new $obj;
}
return self::$_myself;
}
self returns the actual class instance (Singleton in this case), so there is no method show. But you could use static instead of self (Differences) and change $_myself from private to protected so it is accessible in child classes.
class Singleton
{
protected static $_myself;
private function __construct(){}
public static function getInstance()
{
if(!isset(static::$_myself))
{
static::$_myself = new static;
}
return static::$_myself;
}
}
The problem is in
$obj = __CLASS__;
self::$_myself = new $obj;
You create a new instance of the class Singleton, not of the class MyApp, so the method is not available.
Now h2ooooooo was faster with his answer than I edited, see his answer regarding what to put instead of __CLASS__.
I want to use a static method of an example class without instantiating class. This method uses a dependencie class and is instantiated with __construct method. How can this dependency class be instantiated. Example:
class user {
protected static $db;
public function __construct() {
self::$db = database::getInstance();
}
public static function get_user() {
$user = self::$db->query("sql");
return $user;
}
}
I know the solution with autoloader or I could just add self::$db = database::getInstance(); in every static method.
Could someone kindly show me better suggestions?
You can add a static setter and getter for the db object and throw an exception if someone tries to access the getter without calling the setter first:
class User
{
protected static $db;
public static function setDB($db)
{
self::$db = $db;
}
protected static function getDB()
{
if (!self::$db) {
throw new Exception('You must `setDB()` the db object before attempting to get it.');
}
return self::$db;
}
public static function getUser()
{
return self::getDB()->query('sql');
}
}
User::setDB(database::getInstance());
User::getUser();
What is the proper way to do this:
// child
class B extends A {
function __construct() {
$this->object = new B; /// (or `new self` ?)
}
}
// parent
class A {
protected $object;
private static function {
$object = $this->object;
// use the new instance of $object
}
}
When I try this in code, I get this error:
Fatal error: Using $this when not in object context What am I doing wrong? (this is referring to Class A instance)
You cannot use $this in a static method; $this can only be used in an instantiated object.
you will have to change $object to a static and call it using self::$object
class B extends A {
function __construct() {
self::$object = new B;
}
}
// parent
class A {
static protected $object;
private static function doSomething(){
$object = self::$object;
// use the new instance of $object
}
}
You can't use $this to refer to the object in a static method, so you have to change it up a bit. Make object a protected static member.
class A {
protected static $object;
private static function() {
$object = self::$object;
// use the new instance of $object
}
}