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

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

Related

How to access non-static method from within a static method?

I have two methods in a class, one of which is static. I want to access the non-static method from within the static method. Is that possible? I tried this:
class Foo {
public function qux(){
}
public static function waldo(){
self::qux(); // Non-static method Foo::qux() should not be called statically
}
}
Is making qux a static method the only way to achieve this? What if the user doesn't want qux() to be a static method?
This should work as you need:
class Foo {
public function qux(){
}
public static function waldo(){
$foo = new Foo();
$foo->qux();
}
}
There is no other way to call a dynamic method/function without creating the object itself first.
Of course, if you will use the object only one-time and call all methods or functions immediately, you could use something like this:
class Foo {
public function qux(){
}
public static function waldo(){
(new Foo())->qux();
}
}
class Foo {
public function qux(){
}
public static function waldo(){
$obj = new Static();
$obj->qux();
}
}

PHP: calling on an instance's private method inside an instance's static class

What I'm trying to do is the following:
class A {
public function __construct($a) {
// stuff here
}
public static function request() {
$instance = new self("hi");
$instance->bye(); // this weirdly only sometimes throws errors
}
private function bye() {
// stuff here
}
}
A::request();
The line of interest is $instance->bye() - is this allowed within the static context in a way but when called on an instance and inside the same class as the constructor? Or is this not a good practice in general? It's strange that this only throws errors sometimes of calling on a private method with no context.
Any help appreciated!
Turns out this is fine and PHPStorm debugger was creating the issue and screwing up the context hence why the error only happened sometimes which apparently happens on our systems ¯_(ツ)_/¯
Calling a regular method from a static method should never be done.
As there may be no instance at all (Ex: Calling A::request() directly), it will throw an error.
A static method will be the same for all instances of the class, so it won't be able to access non-static properties.
What could but shouldn't be done is calling an object of the same type private method from a static method:
<?php
class A {
private function foo()
{
print("bar");
}
static public function bar($a)
{
$a->foo();
}
}
$a = new A();
A::bar($a);
?>
From http://php.net/manual/en/language.oop5.visibility.php

Is there any ways to call non-static method within static method

I would like to call non-static method within static method. for example
Instead of calling method the following
$user = new User();
$userdata = $user->data($argument);
I would like to call as the following
$usedata = User::data($argument);
Firstly I build with the following setting
Class User{
public static function __callStatic($methodname, $argument) {
$objName = __CLASS__;
$obj = new $objName;
return $obj->find($argument);
}
public function find($argument) {
return $argument*2;
}
}
echo User::find(2);
But It show Warning message but code is successfully executed. Is there any other better solution for this scenario ? Sorry for any grammar mistake that I made since I am not native speaker and I am not very fluent with english.
If your find() method don't use the class context ($this), and that you need to call this method statically, then just declare it as static.

Oddity of static:: calling a method that contains $this

In this example I get the fatal error "Fatal error: Using $this when not in object context" as expected
class ctis_parent{
public function objFunc(){
var_dump('Called succes');
}
public static function call(){
$this->objFunc();
}
public function __construct(){
self::call();
}
}
new ctis_parent();
But if remove static keyword from definition of call() method all work fine, why?
class ctis_parent{
public function objFunc(){
var_dump('Called succes');
}
public function call(){
$this->objFunc();
}
public function __construct(){
self::call();
}
}
new ctis_parent();
//string 'Called succes' (length=13)
A static function, by definition doesn't need the class being instantiated, so it doesn't have access to the $this-> reference, which points to the current instance. If an instance doesn't exist, it can't be pointed to. Makes sense.
Because you're using $this when you're not in an object. Well, you're not REALLY, but with the static declaration, people could do:
ctis_parent::call();
Where, $this would be illegal.
See the docs for static.

Static and Non-Static Calling in PHP

ok I have this code, that I'm studying
class scope{
function printme(){
return "hello";
}
public static function printme(){
return "hello";
}
}
$s = new scope();
echo $s->printme(); //non-static call
echo "<br>";
echo scope::printme(); //static call
Now, this is not really the code of my project but these are the things I want to do
I want to create a class the will contain static and non-static functions.
I want a function to be available both on static and non-static calls.
As non-static function has a lot of operations on it, I also need to call it as a static function so that I will not need to instantiate the class. Is this possible? or I really needed to rewrite the function to another function or class?
NOTE: tell me if I'm doing some bad programming already.
Here is the rule:
A static method can be used in both static method and non-static method.
A non-static method can only be used in a non-static method.
If the instance of your class is rarely needed, you can have the static method create an instance, call the non-static method and return the value.
class Scope {
public function mynonstatic() {
}
public static function mystatic() {
$s = new Scope();
return $s->mynonstatic();
}
}
Remember that a static method is really just a global function with reduced scope. They are useful, but are should not be created without good reason.
As non-static function has a lot of operations on it, I also need to
call it as a static function so that I will not need to instantiate
the class. Is this possible? or I really needed to rewrite the
function to another function or class?
If you need it static, then make it static. If you need it not, then keep it the way it is. It is possible from within non-static function to call static function.
class Foo
{
public function bar()
{
Foo::zex();
// or self::zex() or even $this->zex();
}
public static function zex()
{
}
}
$foo = new Foo;
$foo->bar();
Ant the other way around.
class Foo
{
public function bar()
{
}
public static function zex()
{
$foo = new Foo;
$foo->bar();
}
}
When you should do it or should you do it at all is another question. The most common use of the latter is probably the Singleton pattern.

Categories