Calling non-static method with double-colon(::) - php

Why can't I use a method non-static with the syntax of the methods static(class::method) ? Is it some kind of configuration issue?
class Teste {
public function fun1() {
echo 'fun1';
}
public static function fun2() {
echo "static fun2" ;
}
}
Teste::fun1(); // why?
Teste::fun2(); //ok - is a static method

PHP is very loose with static vs. non-static methods. One thing I don't see noted here is that if you call a non-static method, ns statically from within a non-static method of class C, $this inside ns will refer to your instance of C.
class A
{
public function test()
{
echo $this->name;
}
}
class C
{
public function q()
{
$this->name = 'hello';
A::test();
}
}
$c = new C;
$c->q();// prints hello
This is actually an error of some kind if you have strict error reporting on, but not otherwise.

This is a known "quirk" of PHP. It's by design to prevent back-propagation for figuring out if some time ago we actually instantiated an object or not (remember, PHP is interpreted, not compiled). However, accessing any non-static member the via scope resolution operator if the object is not instantiated will issue a fatal error.
Courtesy of PHP.net:
class User {
const GIVEN = 1; // class constants can't be labeled static nor assigned visibility
public $a=2;
public static $b=3;
public function me(){
echo "print me";
}
public static function you() {
echo "print you";
}
}
class myUser extends User {
}
// Are properties and methods instantiated to an object of a class, & are they accessible?
//$object1= new User(); // uncomment this line with each of the following lines individually
//echo $object1->GIVEN . "</br>"; // yields nothing
//echo $object1->GIVE . "</br>"; // deliberately misnamed, still yields nothing
//echo $object1->User::GIVEN . "</br>"; // yields nothing
//echo $object1->a . "</br>"; // yields 2
//echo $object1->b . "</br>"; // yields nothing
//echo $object1->me() . "</br>"; // yields print me
//echo $object1->you() . "</br>"; // yields print you
// Are properties and methods instantiated to an object of a child class, & are accessible?
//$object2= new myUser(); // uncomment this line with each of the following lines individually
//echo $object2->GIVEN . "</br>"; // yields nothing
//echo $object2->a . "</br>"; // yields 2
//echo $object2->b . "</br>"; // yields nothing
//echo $object2->me() . "</br>"; // yields print me
//echo $object2->you() . "</br>"; // yields print you
// Are the properties and methods accessible directly in the class?
//echo User::GIVEN . "</br>"; // yields 1
//echo User::$a . "</br>"; // yields fatal error since it is not static
//echo User::$b . "</br>"; // yields 3
//echo User::me() . "</br>"; // yields print me
//echo User::you() . "</br>"; // yields print you
// Are the properties and methods copied to the child class and are they accessible?
//echo myUser::GIVEN . "</br>"; // yields 1
//echo myUser::$a . "</br>"; // yields fatal error since it is not static
//echo myUser::$b . "</br>"; // yields 3
//echo myUser::me() . "</br>"; // yields print me
//echo myUser::you() . "</br>"; // yields print you
?>

This is PHP 4 backwards compatibility. In PHP 4 you could not differ between an object method and the global function written as a static class method. Therefore both did work.
However with the changes in the object model with PHP 5 - http://php.net/oop5 - the static keyword has been introduced.
And then since PHP 5.1.3 you get proper strict standard warnings about those like:
Strict Standards: Non-static method Foo::bar() should not be called statically
And/Or:
Strict Standards: Non-static method Foo::bar() should not be called statically, assuming $this from incompatible context
which you should have enabled for your development setup. So it's merely backwards compatibility to a time where the language couldn't differ enough so this was "defined" at run-time.
Nowadays you can define it already in the code, however the code will not break if you still call it "wrong".
Some Demo to trigger the error messages and to show the changed behavior over different PHP versions: http://3v4l.org/8WRQH

PHP 4 did not have a static keyword (in function declaration context) but still allowed methods to be called statically with ::. This continued in PHP 5 for backwards compatibility purposes.

You can do this, but your code will error if you use $this in the function called fun1()

Warning
In PHP 7, calling non-static methods statically is deprecated, and will generate an E_DEPRECATED warning. Support for calling non-static methods statically may be removed in the future.
Link

Starting on PHP8, this no longer works.
The ability to call non-static methods statically was finally removed in PHP 8.
The ability to call non-static methods statically has been removed. Thus is_callable() will fail when checking for a non-static method with a classname (must check with an object instance).
It was originally deprecated on PHP 7.
Static calls to methods that are not declared static are deprecated, and may be removed in the future.

In most languages you will need to have an instance of the class in order to perform instance methods. It appears that PHP will create a temporary instance when you call an instance method with the scope resolution operator.

Not sure why PHP allows this, but you do not want to get into the habit of doing it. Your example only works because it does not try to access non-static properties of the class.
Something as simple as:
<?php
class Foo {
private $color;
public function bar() {
echo 'before';
$this->color = "blue";
echo 'after';
}
}
Foo::bar();
would result in a fatal error

I have noticed that if you call non-static method self::test() from within a class, no warning for strict standard will be issued, like when you call Class::test(). I believe that this is not related to LSB, since my class was not extended (tested on php 5.5)?

One way for calling the same method both statically and non-statically is using the magic methods __call and __callStatic.
The FluentMath class (code down below) is an example where you can invoke the methods add or subtract both statically and not:
$res1 = FluentMath::add(5) // add method called statically
->add(3) // add method called non-statically
->subtract(2)
->result();
$res2 = FluentMath::subtract(1)->add(10)->result();
FluentMath class
class FluentMath
{
private $result = 0;
public function __call($method, $args)
{
return $this->call($method, $args);
}
public static function __callStatic($method, $args)
{
return (new static())->call($method, $args);
}
private function call($method, $args)
{
if (! method_exists($this , '_' . $method)) {
throw new Exception('Call undefined method ' . $method);
}
return $this->{'_' . $method}(...$args);
}
private function _add($num)
{
$this->result += $num;
return $this;
}
private function _subtract($num)
{
$this->result -= $num;
return $this;
}
public function result()
{
return $this->result;
}
}
If you want the full explanation of how that class works please check:
https://www.danielefavi.com/blog/php-fluent-api-class
https://github.com/danielefavi/php-fluent-api-class/

Related

PHP : Calling classes - Whats the diference? [duplicate]

There are two distinct ways to access methods in PHP, but what's the difference?
$response->setParameter('foo', 'bar');
and
sfConfig::set('foo', 'bar');
I'm assuming -> (dash with greater than sign or chevron) is used for functions for variables, and :: (double colons) is used for functions for classes. Correct?
Is the => assignment operator only used to assign data within an array? Is this in contrast to the = assignment operator which is used to instantiate or modify a variable?
When the left part is an object instance, you use ->. Otherwise, you use ::.
This means that -> is mostly used to access instance members (though it can also be used to access static members, such usage is discouraged), while :: is usually used to access static members (though in a few special cases, it's used to access instance members).
In general, :: is used for scope resolution, and it may have either a class name, parent, self, or (in PHP 5.3) static to its left. parent refers to the scope of the superclass of the class where it's used; self refers to the scope of the class where it's used; static refers to the "called scope" (see late static bindings).
The rule is that a call with :: is an instance call if and only if:
the target method is not declared as static and
there is a compatible object context at the time of the call, meaning these must be true:
the call is made from a context where $this exists and
the class of $this is either the class of the method being called or a subclass of it.
Example:
class A {
public function func_instance() {
echo "in ", __METHOD__, "\n";
}
public function callDynamic() {
echo "in ", __METHOD__, "\n";
B::dyn();
}
}
class B extends A {
public static $prop_static = 'B::$prop_static value';
public $prop_instance = 'B::$prop_instance value';
public function func_instance() {
echo "in ", __METHOD__, "\n";
/* this is one exception where :: is required to access an
* instance member.
* The super implementation of func_instance is being
* accessed here */
parent::func_instance();
A::func_instance(); //same as the statement above
}
public static function func_static() {
echo "in ", __METHOD__, "\n";
}
public function __call($name, $arguments) {
echo "in dynamic $name (__call)", "\n";
}
public static function __callStatic($name, $arguments) {
echo "in dynamic $name (__callStatic)", "\n";
}
}
echo 'B::$prop_static: ', B::$prop_static, "\n";
echo 'B::func_static(): ', B::func_static(), "\n";
$a = new A;
$b = new B;
echo '$b->prop_instance: ', $b->prop_instance, "\n";
//not recommended (static method called as instance method):
echo '$b->func_static(): ', $b->func_static(), "\n";
echo '$b->func_instance():', "\n", $b->func_instance(), "\n";
/* This is more tricky
* in the first case, a static call is made because $this is an
* instance of A, so B::dyn() is a method of an incompatible class
*/
echo '$a->dyn():', "\n", $a->callDynamic(), "\n";
/* in this case, an instance call is made because $this is an
* instance of B (despite the fact we are in a method of A), so
* B::dyn() is a method of a compatible class (namely, it's the
* same class as the object's)
*/
echo '$b->dyn():', "\n", $b->callDynamic(), "\n";
Output:
B::$prop_static: B::$prop_static value
B::func_static(): in B::func_static
$b->prop_instance: B::$prop_instance value
$b->func_static(): in B::func_static
$b->func_instance():
in B::func_instance
in A::func_instance
in A::func_instance
$a->dyn():
in A::callDynamic
in dynamic dyn (__callStatic)
$b->dyn():
in A::callDynamic
in dynamic dyn (__call)
:: is used in static context, ie. when some method or property is declared as static:
class Math {
public static function sin($angle) {
return ...;
}
}
$result = Math::sin(123);
Also, the :: operator (the Scope Resolution Operator, a.k.a Paamayim Nekudotayim) is used in dynamic context when you invoke a method/property of a parent class:
class Rectangle {
protected $x, $y;
public function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
}
class Square extends Rectangle {
public function __construct($x) {
parent::__construct($x, $x);
}
}
-> is used in dynamic context, ie. when you deal with some instance of some class:
class Hello {
public function say() {
echo 'hello!';
}
}
$h = new Hello();
$h->say();
By the way: I don't think that using Symfony is a good idea when you don't have any OOP experience.
Actually by this symbol we can call a class method that is static and not be dependent on other initialization...
class Test {
public $name;
public function __construct() {
$this->name = 'Mrinmoy Ghoshal';
}
public static function doWrite($name) {
print 'Hello '.$name;
}
public function write() {
print $this->name;
}
}
Here the doWrite() function is not dependent on any other method or variable, and it is a static method. That's why we can call this method by this operator without initializing the object of this class.
Test::doWrite('Mrinmoy');
// Output: Hello Mrinmoy.
But if you want to call the write method in this way, it will generate an error because it is dependent on initialization.
The => operator is used to assign key-value pairs in an associative array. For example:
$fruits = array(
'Apple' => 'Red',
'Banana' => 'Yellow'
);
It's meaning is similar in the foreach statement:
foreach ($fruits as $fruit => $color)
echo "$fruit is $color in color.";
The difference between static and instantiated methods and properties seem to be one of the biggest obstacles to those just starting out with OOP PHP in PHP 5.
The double colon operator (which is called the Paamayim Nekudotayim from Hebrew - trivia) is used when calling an object or property from a static context. This means an instance of the object has not been created yet.
The arrow operator, conversely, calls methods or properties that from a reference of an instance of the object.
Static methods can be especially useful in object models that are linked to a database for create and delete methods, since you can set the return value to the inserted table id and then use the constructor to instantiate the object by the row id.
Yes, I just hit my first 'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'. My bad, I had a $instance::method() that should have been $instance->method(). Silly me.
The odd thing is that this still works just fine on my local machine (running PHP 5.3.8) - nothing, not even a warning with error_reporting = E_ALL - but not at all on the test server, there it just explodes with a syntax error and a white screen in the browser. Since PHP logging was turned off at the test machine, and the hosting company was too busy to turn it on, it was not too obvious.
So, word of warning: apparently, some PHP installations will let you use a $instance::method(), while others don't.
If anybody can expand on why that is, please do.

Method static by default? [duplicate]

Why can't I use a method non-static with the syntax of the methods static(class::method) ? Is it some kind of configuration issue?
class Teste {
public function fun1() {
echo 'fun1';
}
public static function fun2() {
echo "static fun2" ;
}
}
Teste::fun1(); // why?
Teste::fun2(); //ok - is a static method
PHP is very loose with static vs. non-static methods. One thing I don't see noted here is that if you call a non-static method, ns statically from within a non-static method of class C, $this inside ns will refer to your instance of C.
class A
{
public function test()
{
echo $this->name;
}
}
class C
{
public function q()
{
$this->name = 'hello';
A::test();
}
}
$c = new C;
$c->q();// prints hello
This is actually an error of some kind if you have strict error reporting on, but not otherwise.
This is a known "quirk" of PHP. It's by design to prevent back-propagation for figuring out if some time ago we actually instantiated an object or not (remember, PHP is interpreted, not compiled). However, accessing any non-static member the via scope resolution operator if the object is not instantiated will issue a fatal error.
Courtesy of PHP.net:
class User {
const GIVEN = 1; // class constants can't be labeled static nor assigned visibility
public $a=2;
public static $b=3;
public function me(){
echo "print me";
}
public static function you() {
echo "print you";
}
}
class myUser extends User {
}
// Are properties and methods instantiated to an object of a class, & are they accessible?
//$object1= new User(); // uncomment this line with each of the following lines individually
//echo $object1->GIVEN . "</br>"; // yields nothing
//echo $object1->GIVE . "</br>"; // deliberately misnamed, still yields nothing
//echo $object1->User::GIVEN . "</br>"; // yields nothing
//echo $object1->a . "</br>"; // yields 2
//echo $object1->b . "</br>"; // yields nothing
//echo $object1->me() . "</br>"; // yields print me
//echo $object1->you() . "</br>"; // yields print you
// Are properties and methods instantiated to an object of a child class, & are accessible?
//$object2= new myUser(); // uncomment this line with each of the following lines individually
//echo $object2->GIVEN . "</br>"; // yields nothing
//echo $object2->a . "</br>"; // yields 2
//echo $object2->b . "</br>"; // yields nothing
//echo $object2->me() . "</br>"; // yields print me
//echo $object2->you() . "</br>"; // yields print you
// Are the properties and methods accessible directly in the class?
//echo User::GIVEN . "</br>"; // yields 1
//echo User::$a . "</br>"; // yields fatal error since it is not static
//echo User::$b . "</br>"; // yields 3
//echo User::me() . "</br>"; // yields print me
//echo User::you() . "</br>"; // yields print you
// Are the properties and methods copied to the child class and are they accessible?
//echo myUser::GIVEN . "</br>"; // yields 1
//echo myUser::$a . "</br>"; // yields fatal error since it is not static
//echo myUser::$b . "</br>"; // yields 3
//echo myUser::me() . "</br>"; // yields print me
//echo myUser::you() . "</br>"; // yields print you
?>
This is PHP 4 backwards compatibility. In PHP 4 you could not differ between an object method and the global function written as a static class method. Therefore both did work.
However with the changes in the object model with PHP 5 - http://php.net/oop5 - the static keyword has been introduced.
And then since PHP 5.1.3 you get proper strict standard warnings about those like:
Strict Standards: Non-static method Foo::bar() should not be called statically
And/Or:
Strict Standards: Non-static method Foo::bar() should not be called statically, assuming $this from incompatible context
which you should have enabled for your development setup. So it's merely backwards compatibility to a time where the language couldn't differ enough so this was "defined" at run-time.
Nowadays you can define it already in the code, however the code will not break if you still call it "wrong".
Some Demo to trigger the error messages and to show the changed behavior over different PHP versions: http://3v4l.org/8WRQH
PHP 4 did not have a static keyword (in function declaration context) but still allowed methods to be called statically with ::. This continued in PHP 5 for backwards compatibility purposes.
You can do this, but your code will error if you use $this in the function called fun1()
Warning
In PHP 7, calling non-static methods statically is deprecated, and will generate an E_DEPRECATED warning. Support for calling non-static methods statically may be removed in the future.
Link
Starting on PHP8, this no longer works.
The ability to call non-static methods statically was finally removed in PHP 8.
The ability to call non-static methods statically has been removed. Thus is_callable() will fail when checking for a non-static method with a classname (must check with an object instance).
It was originally deprecated on PHP 7.
Static calls to methods that are not declared static are deprecated, and may be removed in the future.
In most languages you will need to have an instance of the class in order to perform instance methods. It appears that PHP will create a temporary instance when you call an instance method with the scope resolution operator.
Not sure why PHP allows this, but you do not want to get into the habit of doing it. Your example only works because it does not try to access non-static properties of the class.
Something as simple as:
<?php
class Foo {
private $color;
public function bar() {
echo 'before';
$this->color = "blue";
echo 'after';
}
}
Foo::bar();
would result in a fatal error
I have noticed that if you call non-static method self::test() from within a class, no warning for strict standard will be issued, like when you call Class::test(). I believe that this is not related to LSB, since my class was not extended (tested on php 5.5)?
One way for calling the same method both statically and non-statically is using the magic methods __call and __callStatic.
The FluentMath class (code down below) is an example where you can invoke the methods add or subtract both statically and not:
$res1 = FluentMath::add(5) // add method called statically
->add(3) // add method called non-statically
->subtract(2)
->result();
$res2 = FluentMath::subtract(1)->add(10)->result();
FluentMath class
class FluentMath
{
private $result = 0;
public function __call($method, $args)
{
return $this->call($method, $args);
}
public static function __callStatic($method, $args)
{
return (new static())->call($method, $args);
}
private function call($method, $args)
{
if (! method_exists($this , '_' . $method)) {
throw new Exception('Call undefined method ' . $method);
}
return $this->{'_' . $method}(...$args);
}
private function _add($num)
{
$this->result += $num;
return $this;
}
private function _subtract($num)
{
$this->result -= $num;
return $this;
}
public function result()
{
return $this->result;
}
}
If you want the full explanation of how that class works please check:
https://www.danielefavi.com/blog/php-fluent-api-class
https://github.com/danielefavi/php-fluent-api-class/

Does Php support method overloading

Does php support method overloading. While trying below code it suggests it supports method overloading. Any views
class test
{
public test($data1)
{
echo $data1;
}
}
class test1 extends test
{
public test($data1,$data2)
{
echo $data1.' '.$data2;
}
}
$obj = new test1();
$obj->test('hello','world');
As i have overload the method it gives the output as "hello world".
Above code snippet suggests php supports method overloading. So my question is does php support method overloading.
You should make the difference between method overriding (your example) and method overloading
Here is a simple example how to implement method overloading in PHP using __call magic method:
class test{
public function __call($name, $arguments)
{
if ($name === 'test'){
if(count($arguments) === 1 ){
return $this->test1($arguments[0]);
}
if(count($arguments) === 2){
return $this->test2($arguments[0], $arguments[1]);
}
}
}
private function test1($data1)
{
echo $data1;
}
private function test2($data1,$data2)
{
echo $data1.' '.$data2;
}
}
$test = new test();
$test->test('one argument'); //echoes "one argument"
$test->test('two','arguments'); //echoes "two arguments"
So my question is does php support method overloading(?).
Yes, but not in that way, and, in your example, it not suggests that this kind of overloading is correct, at least with the version 5.5.3 of it and error_reporting(E_ALL).
In that version, when you try to run this code, it gives you the following messages:
Strict Standards: Declaration of test1::test() should be compatible
with test::test($data1) in /opt/lampp/htdocs/teste/index.php on line 16
Warning: Missing argument 1 for test::test(), called in /opt/lampp/htdocs/teste/index.php
on line 18 and defined in /opt/lampp/htdocs/teste/index.php on line 4
Notice: Undefined variable: data1 in /opt/lampp/htdocs/teste/index.php on line 6
hello world //it works, but the messages above suggests that it's wrong.
You forgot to add 'function' before test in both cases. Method is called of child class because when you call a method from child class object it first check if that method exist in child class, if not then it look into inherited parent class with visibility public or protected check and if method is exist than return the result according to that.

Does static method in PHP have any difference with non-static method?

class t {
public function tt()
{
echo 1;
}
}
t::tt();
See?The non-static function can also be called at class level.So what's different if I add a static keyword before public?
Except that, if you try to use $this in your method, like this :
class t {
protected $a = 10;
public function tt() {
echo $this->a;
echo 1;
}
}
t::tt();
You'll get a Fatal Error when calling the non-static method statically :
Fatal error: Using $this when not in object context in ...\temp.php on line 11
i.e. your example is a bit too simple, and doesn't really correspond to a real-case ;-)
Also note that your example should get you a strict warning (quoting) :
Calling non-static methods statically
generates an E_STRICT level warning.
And it actually does (At least, with PHP 5.3) :
Strict Standards: Non-static method t::tt() should not be called statically in ...\temp.php on line 12
1
So : not that good ;-)
Still, statically calling a non-static method doesnt't look like any kind of good practice (which is probably why it raises a Strict warning), as static methods don't have the same meaning than non-static ones : static methods do not reference any object, while non-static methods work on the instance of the class there're called on.
Once again : even if PHP allows you to do something (Maybe for historical reasons -- like compatibility with old versions), it doesn't mean you should do it !
The Static Keyword
Because static methods are callable without an instance of the object created, the pseudo-variable $this is not available inside the method declared as static.
Static properties cannot be accessed through the object using the arrow operator ->.
Calling non-static methods statically generates an E_STRICT level warning.
Just because you can call non-static methods statically doesn't mean you should. It's bad form.
In general a static method is also called class method while a non-static method is also called object method or instance method.
The difference between a class method and an object method is that class methods can only access class properties (static properties) while object methods are used to access object properties (properties of the very same class instance).
Static methods and properties are used to share common data over or for all instances of that specific class.
You could, for example, use a static property to keep track of the number of instances:
class A {
private static $counter = 0;
public function __construct() {
self::counter = self::counter + 1;
}
public function __destruct() {
self::counter = self::counter - 1;
}
public static function printCounter() {
echo "There are currently ".self::counter." instances of ".__CLASS__;
}
}
$a1 = new A();
$a2 = new A();
A::printCounter();
unset($a2);
A::printCounter();
Note that the static property counter is private so it can only be accessed by the class itself and instances of that class but not from outside.
A main difference that has not been mentioned relates to polymorphic behavior.
Non static methods, when redeclared in a derived class, override the base class method, and allow polymorphic behavior based on the type of the instance they are called on. This is not the case for static methods.
PHP 5.3 introduced the concept of late static binding which can be used to reference the called class in a context of static inheritance.
Yes, the critical difference is that methods declared static do not have access to the object-context variable, $this.
Additionally, invocation of a non-static method when not in object context will trigger an E_STRICT error event. When enabled, that event’s default behavior is to output a message to the error log (or STDERR), but it will allow the program to continue running.
Also, any attempt to reference $this when not in an object context will trigger an E_ERROR event. That event’s behavior is to output a message to the error log (or STDERR) and to exit the program with status 255.
For example:
<?php
error_reporting(-1);
//error_reporting(E_ALL);
class DualNature {
public static function fnStatic() {
if ( isset( $this ) ) {
// never ever gets here
$myValue = $this->_instanceValue;
} else {
// always gets here
$myValue = self::$_staticValue;
}
return $myValue;
}
public function fnInstance() {
if ( isset( $this ) ) {
// gets here on instance (->) reference only
$myValue = $this->_instanceValue;
} else {
// gets here in all other situations
$myValue = self::$_staticValue;
}
return $myValue;
}
public static function fnStaticDeath() {
return $this->_instanceValue;
}
private static $_staticValue = 'no access to $this';
private $_instanceValue = '$this is available';
}
$thing = new DualNature();
echo "==========\n";
printf("DualNature::fnStatic(): \"%s\"\n", DualNature::fnStatic() );
echo "==========\n";
printf("\$thing::fnStatic(): \"%s\"\n", $thing::fnStatic() );
echo "==========\n";
printf("\$thing->fnStatic(): \"%s\"\n", $thing->fnStatic() );
echo "==========\n";
printf("DualNature::fnInstance(): \"%s\"\n", DualNature::fnInstance() );
echo "==========\n";
printf("\$thing::fnInstance(): \"%s\"\n", $thing::fnInstance() );
echo "==========\n";
printf("\$thing->fnInstance(): \"%s\"\n", $thing->fnInstance() );
echo "==========\n";
printf("\$thing->fnStaticDeath(): \"%s\"\n", $thing->fnStaticDeath() );
echo "==========\n";
echo "I'M ALIVE!!!\n";
The output of the above is:
==========
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 45
DualNature::fnStatic(): "no access to $this"
==========
$thing::fnStatic(): "no access to $this"
==========
$thing->fnStatic(): "no access to $this"
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 47
==========
DualNature::fnInstance(): "no access to $this"
==========
$thing::fnInstance(): "no access to $this"
==========
$thing->fnInstance(): "$this is available"
==========
PHP Fatal error: Using $this when not in object context in example.php on line 29
Changing the error reporting level to E_ALL will suppress the default E_STRICT warning messages (the event will still be propagated), but the invalid reference to $this will still cause a fatal error and will exit the program.
Besides the syntax and functional differences there is also a performance difference that matters.
You can refer to this more or less detailed comparison of static and non-static methods in PHP.

Difference between access class methods

Up until the yesterday I though that both of these methods for accessing a class where identical. Google turned up noting (either that or my keywords were bad). What is the difference between accessing a class by defining a new instance of the class rather than just calling the class methods directly.
I hardly understood what I just ask, since I have not a clue what I'm asking but allow me to give a few examples to help out.
For as long as I have been using classes in PHP I have been defining a instance of the class then accessing the methods from that variable. Here is an example:
<?php
class Myclass
{
public function my_method() {
return "This is my method";
}
}
$myclass = new Myclass();
echo $myclass->my_method(); // output: This is my method
?>
What is the difference between that and doing this?
<?php
class Myclass
{
public function my_method() {
return "This is my method";
}
}
echo Myclass::my_method(); // output: This is my method
?>
I hope I was clear enough. If not a brief synopsis would be - What is the difference between creating a new instance of a class then calling a method of the class with "$class->mymethod();," or just directly calling the method like so: "Myclass::mymethod();"?
Thanks in advance.
The :: notation is used to call the function as static. See these pages from the PHP manual for more info:
http://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php
http://php.net/manual/en/language.oop5.static.php.
In essence, static functions are just like regular functions outside classes. The function is not in object context when called as such, so the pseudo-variable $this is not available.
Note that the function should be declared as static if you are planning on calling it as such:
class SomeClass {
static public function StaticFunction() {
...
}
}
The Myclass::my_method() call should be throwing an E_STRICT warning, as you're calling a non-static method in a static context.
Static methods are methods that belong to the class rather than to the instance. These methods cannot access any non-static variables, as they have no reference for them (because non-static variables belong to the instance, not the class).
After using Java and C#, I'm mildly disturbed that this isn't considered an E_WARNING or E_ERROR, particularly since E_STRICT is not logged by default.
First, you should understand the difference between a class and an object, or a class and an instance of a class.
For example, where class is "Circle", an instance might be "this particular circle". Class Circle might have members $center and $radius - every point has these. But the values of these are different for every point.
$class->mymethod() is a call to an instance method, for instance $circle->Length(). You are saying something to a particular instance of an object. This method will have access to class members - variables that belong to the instance. In PHP you gain access to these instance variables using keyword $this.
For instance $circle->Length() might be implemented as return 2*Pi*$this->radius;
What happens when you say Circle::Length()? Nothing. This is syntax for calling static methods. Because you did not say which circle. Circle as a class does not have length.
Static method is declared with keyword static. Whatever it does it has no access to any instances of the class. It's something that a class as a whole does.
For instance, if you want to calculate length of the circle without actually creating one, then there might be static function calculateLength($radius) in the class circle. And you would call it as Circle::calculateLength($myRadius)
In my opinion you should not even think about static methods until you understand the non-static ones.
http://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php
I don't think you can call methods that way. I thought that was how you called static members of the class.
In my understanding when you create an instance of the class you are creating an object and so you call methods/properties from that object.
When you call a method/property via a static call you are calling on the class itself.
So if you have something like this:
class acs {
public $var = 'bla';
}
and then you do
$a = new acs();
$b = new acs();
echo $a->var . '<br>';
echo $b->var . '<br>';
$a->var = 'hey';
$b->var = 'Yooo';
echo $a->var . '<br>';
echo $b->var . '<br>';
You now have 2 instances of class acs which started with the same values but now have different values.
But if you have this:
class acs {
public static $var = 'bla';
}
And then do:
$a = new acs();
$b = new acs();
echo $a->var . '<br>';
echo $b->var . '<br>';
$a->var = 'hey';
$b->var = 'Yooo';
echo $a->var . '<br>';
echo $b->var . '<br>';
echo acs::$var;
What you are doing is:
You create the instances as before.
You echo nothing, because the public property var does not exist.
You create the public property var in both the instances
You echo their values (hey and Yoo)
You echo the static property var (which is 'bla' and has not changed)
Hope this helps!

Categories