Class Construct Static Undefined method - php

I am baffled why I get this error:
class smTitan {
private static $_instance = null;
public static function this($att){
if (!self::$_instance) self::$_instance = new self();
if ($att !== NULL) {
self::$_instance->_att = $att;
self::$_instance->_results = new WP_Query( $att );
}
return self::$_instance;
}
}
We extend it
class ourmissionHelper extends smTitan {
public function getPostView() {
}
}
Call it:
ourmissionHelper::this(array("post_type"=>"about"))->getPostView();
and I get this error:
Fatal error: Call to undefined method smTitan::getPostView()
That makes no since to me, getPostView is part of ourmissionHelper which extends smTitan, so it should be able to access it, but its treating the first class from the this() construct as the only instance... Any ideas, other than copying over the class to get this to work?

self always refers to the class that it is written in, never any extending classes. You want a late-binding static reference to your class, which is only possible since PHP 5.3 using the static keyword. So, new static() instead of new self().

Related

Is there a way to check if class member access on instantiation?

So in PHP 5.4 and up you can call a method on instantiation like so.
$class = new Foo()->methodName();
I would like to check when the class is instantiated if it was done so with a method at the same time.
Is it possible to check if the class was instantiated without a method at the same time and default to a method if not?
you can use instanceOf on the object for which you wanted to check the class.
Constructor of the class cannot return a value in php, so you can't use singleton incapsulated in constructor and have it looks nice. Of cource, you can make something like this
// NOT FOR USE
class Foo {
private static $instance;
public function __construct($skipIncapsulate = false) {
if (!$skipIncapsulation && !self::$instance)
{
self::instance = new self(true);
}
}
public function bar() {
// Do what you want with self::$instance
}
}
N.B. Do not use the example above, it is ugly solution, which also incapsulates unnecessary logic in controller, and while working with the class
Better use a usual singleton like this
class Foo {
private static $instance;
private function __construct()
{}
public static getInstance()
{
return self::$instance ?? self::$instance = new self();
}
}
Nevertheless you can create a new class FooManager, which will delegate the if the Foo class is defined
class FooManager {
private static $foo;
public function __construct()
{
self::$foo = self::$foo ?? self::$foo = new Foo();
}
public function getFoo()
{
return self::$foo;
}
}
// usage in your code
(new FooManager)->getFoo()->bar();
// You can add __call method to use (new FooManager)->foo->bar()
This will simplify working with your code. Incapsulating static self-instance in constructor is not the good practice

Why I get Non-static method should not be called statically?

I'm learning Laravel and the way I learn a new framework is going deep and found how/why magic happened in that.
So I learn facades and love them and wanna found how Laravel do the magic and found a way to have similar feature is __callStatic magic method. and here is my code :
class Facade {
public static function __callStatic($method,$args){
$instance = static::getFacade();
return call_user_func_array([$instance, $method], $args);
}
}
class DB extends Facade {
public static function getFacade(){
return new self();
}
public function init(){
echo 'INIT DB';
}
}
DB::init();
the code has a right output but I get this error:
Non-static method DB::init() should not be called statically :21
I don't understand why I got this and also Why I don't get this error in Laravel application that does this.
As init() is your public method and not static, you can call it via its object.
Try to call it by creating object of class DB.
$obj = new DB();
$obj->init();
Hope it will help you.
This method doen't have static keyword so you've to call it using the instance of that class and have to use this -> operator instead of ::
//this is a static method with static keyword preceding function
public static function getFacade(){
^^^^^^
return new self();
}
// this is non-static method with no static keyword
public function init(){
echo 'INIT DB';
}
Non-Static: create an instance and then call it using ->
$instance = new DB();
$instance->init();
Static: No need to create instance just call it using ::
DB::getFacade()
Because __callStatic method only catches inaccessible or non-exist methods so if you change
public function init(){
echo 'INIT DB';
}
To protected it will work
protected function init(){
echo 'INIT DB';
}
Also I asked a question before about this and I think it might be helpful for you
Here is my question

Accessing parent property inside parent class throws error - using $this when not in object context

Parent Class
class admarvel_generic_network
{
protected $attributeSettings;
public function __construct()
{
$this->attributeSettings = "something";
}
public static function parentGetAd()
{
print_r($this->attributeSettings); //throws FATAL ERROR Using $this when not in object context
}
}
Child Class - Initiating object of same class within static function
class Agencies_selectablemedia_test extends admarvel_generic_network
{
public static function getAd($frengoAdParams)
{
$adnw = new Agencies_selectablemedia_test();
$ad = $adnw->parentGetAd();
return $ad;
}
}
//Entry point
$ad_contents = Agencies_selectablemedia_test::getAd($params);
echo $ad_contents;
I get a fatal error, as highlighted in the code above.
I checked that if I make the following changes in child and parent class -
Parent Class
public static function parentGetAd($obj)
{
print_r($obj->attributeSettings); //this works
}
Child Class
public static function getAd($frengoAdParams)
{
$adnw = new Agencies_selectablemedia_test();
$ad = admarvel_generic_network::parentGetAd($adnw); //used scope resolution operator and passed object as parameter.
return $ad;
}
Could someone explain the above? I would like to understand why I cannot use $this->attributeSettings in the parent class's parentGetAd() function.
The reason why you cannot access $this->attributeSettings is that your are in a static method. So you aren't in the context of an object.
public static function parentGetAd($obj)
If you are declaring the method like this
public function parentGetAd($obj) {
}
you should be able to access $this->attributeSettings.

PHP OOP , How to assign not static property to static method?

could someone explain how to use not static property in static method in php, this is wrong code, but i want to know how to fix this, thank you
<?php
class SomeClass
{
public $_someMember;
public function __construct()
{
$this->_someMember = 1;
}
public static function getSomethingStatic()
{
return $this->_someMember * 5; // here's the catch
}
}
echo SomeClass::getSomethingStatic();
?>
You can't directly. You need to create an object instance. You can make one and pass it to a static method, or make one in static method's body.
Regular (non-static) properties require object instance of given class (type).
Static methods are called by referring to the class itself, not an object.
You can however use static properties or constants for static methods needs without creating object instance at all.
You have to instantiate object
<?php
class SomeClass
{
public $_someMember;
public function __construct()
{
$this->_someMember = 1;
}
public static function getSomethingStatic()
{
$object = new self();
return $object->_someMember * 5; // here's the catch
}
}
echo SomeClass::getSomethingStatic();
You can statically create an instance of the class that the method is being called on via:
$instance = new static();
You can also statically create instances of the class that actually defines the method via:
$instance = new self();
As an example, take these classes First and Second.
class First
{
public static function getStatic()
{
return new static();
}
public static function getSelf()
{
return new self();
}
}
class Second extends First{ }
When we use Second::getStatic(), we will get an instance of Second.
When we use Second::getSelf(), we will get an instance of First.
When we call either method via First, we will get an instance of First.
This means you can change your method to:
public static function getSomethingStatic()
{
$instance = new static(); // or new self() if you always want to use 'SomeClass'
// and never an extending class.
return $instance->_someMember;
}

Error when Extending a class

Im having problems extending a Class.
This is what I was trying to do:
class Core
{
protected $db;
public function __construct()
{
$this->set_db_class();
}
private function set_db_class ()
{
include_once ( './classes/Database.php' );
$this->db = new Database();
}
}
class Functions extends Core
{
public function __construct()
{
parent::__construct();
}
public static function create_user ()
{
$this->db->query ( "INSERT ..." );
}
}
So, that's the estructure, but my problem is that I'm getting the following error:
Fatal error: Using $this when not in object context in /Applications/XAMPP/xamppfiles/htdocs/own/newsite/classes/class.Functions.php on line 10
What can I do to solve this?
Declare create_user as non-static and call it from an instance, otherwise (as the error message says) you cannot access $this, since $this is always a reference to the current instance. In a static context, there isn't one.
$functions = new Functions();
$functions->create_user();
instead of
Functions::create_user();
If you want to bundle functions that are not logically related to each other, use a namespace and not a class. You can go with an all-static class (every tiny property and method is static so that you don't need an instance at any time), but that's a horrible solution and not what classes should be used for.

Categories