zer0uno
zer0uno

Reputation: 8030

Difference between calling a non-static method statically and not statically

Given the following code:

<?php
class MyClass {
    public function print() {
        echo $this->number . "\n";
    }

    public static function staticPrint() {
        echo "staticPrint\n";
    }
}

class MyExtendedClass extends MyClass {
    protected $number = 100;

    public function extendedPrint() {
        $this->print();
        $this::print(); // What's the difference?
        $this->staticPrint(); // Why is this allowed?
        $this::staticPrint();
        echo "Print done...!\n";
    }
}

$myExtendedClass = new MyExtendedClass();
$myExtendedClass->extendedPrint();

with the following output:

100
100
Print done...!

Is there any difference between $this->print() and $this::print() ?

Upvotes: 1

Views: 1233

Answers (4)

Sasha
Sasha

Reputation: 4004

The short answer is: $instance::method(…) (where $instance is a class instance, not a string) seems to be equivalent to get_class($instance)::method(…) (which in your case means MyExtendedClass::print()).

When you call SomeClassName::method(…), the fact whether the method receives or not receives a $this value is sporadic. It depends on what place you call SomeClassName::method(…) from. Calling SomeClassName::method(…) from within same or other method of the SomeClassName or its descendant will cause the $this from the place of calling to be passed to method; otherwise method probably won't receive any $this value.

Thus, when you call $instance::method(…), the method may or may not receive a $this value. If it receives a $this value, it will be the $this value from the place of calling, but not the $instance (although they may coincide, as when doing $this::method(…) or $instance = $this; …; $instance::method(…)).

http://sandbox.onlinephpfunctions.com/code/93d4ea2dd47dbc2c5ed338a96ca4d00d4ffef77b

Upvotes: 0

I Putu Yoga Permana
I Putu Yoga Permana

Reputation: 4220

IMHO, there is no any difference if you call it from inside your class.

But, if you call it from outside your class, you need instantiate first to call non-static method.

$var = new MyExtendedClass;
$var->print();

Static: (deprecated on PHP 7)

$var = MyExtendedClass::print();

on PHP 7, you need Static keyword on your method, so it can be call statically. Full reference

Upvotes: 1

deceze
deceze

Reputation: 522005

A method which is declared as static will always be called statically:

public static function bar() { var_dump($this); }

Whichever way you call this method, it will result in:

Fatal error: Uncaught Error: Using $this when not in object context

(Or variations thereof depending on your version of PHP.)

A function which does not have the static keyword behaves… differently:

class Foo {
    public function bar() { var_dump($this); }
}

$f = new Foo;
$f::bar();
Deprecated: Non-static method Foo::bar() should not be called statically
Fatal error: Uncaught Error: Using $this when not in object context

Calling the function from outside actually calls it statically.

class Foo {
    public function bar() { var_dump($this); }
    public function baz() { $this::bar(); }
}

$f = new Foo;
$f->baz();
object(Foo)#1 (0) {
}

Calling the function via $this:: calls it in an object context.

The manual only has these vague paragraphs to offer for the :: operator:

When referencing these items from outside the class definition, use the name of the class.

As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static).

It appears that outside a class :: always operates statically, and $f:: substitutes the name of the class. However, within an object context, :: preserves the context, likely to enable correct operation of parent:: calls, which obviously should preserve the object context.

Upvotes: 1

javier_domenech
javier_domenech

Reputation: 6253

In the example you gave No, there is no difference.

Although there are totally different in most circumstances, since in the non-static you are printing the current number value of the object, which could have changed (any set method or similar could have been called).

Whereas with the static call it would print always the same value (default value declared in the class scope, 100).

Upvotes: 0

Related Questions