This thing has been bugging me for long and I can't find it anywhere!
What is the difference when using classes in php between :: and ->
Let me give an example.
Imagine a class named MyClass and in this class there is a function myFunction
What is the difference between using:
MyClass myclass = new MyClass
myclass::myFunction();
or
MyClass myclass = new MyClass
myclass->myFunction();
Thank you
MyClass::myFunction(); // static method call
$myclass->myFunction(); // instance method call
"::" is for calling static methods on the class. So, you can use:
MyClass::myStaticFunction()
but not:
MyClass->myStaticFunction()
as stated, "::" is for static method calls whereas "->" is for instance method calls
except for when using parent:: to access functions in a base class, where "parent::" can be used for both static and non-static parent methods
abstract class myParentClass
{
public function foo()
{
echo "parent class";
}
}
class myChildClass extends myParentClass
{
public function bar()
{
echo "child class";
parent::foo();
}
}
$obj = new myChildClass();
$obj->bar();
class MyClass {
static function myStaticFunction(...){
...
}
}
//$myObject=new MyClass(); it isn't necessary. It's true??
MyClass::myStaticFunction();
Related
I am just checking the OOPs static/non-static concept and found something strange.
I have heard that static method's output can be get by using static keyword with resolution operator(::) . But In my program I am getting non static method's value using static keyword. Can any one explain the program? I am getting confused.
<?php
error_reporting(E_ALL);
class parentclass
{
protected function sum()
{
return 145;
}
}
class childclass extends parentclass
{
protected function sum()
{
return 125;
}
}
class grandchild extends childclass
{
function sum()
{
return 100;
}
function __construct()
{
echo static::sum(); // 100 as output but how
}
}
$obj = new grandchild();
?>
Besides this If I am making function sum() of childclass as static like
class childclass extends parentclass
{
protected static function sum()
{
return 125;
}
}
then also it is giving fatal error as following:
Fatal error: Cannot make non static method parentclass::sum() static in class childclass
But why I am not calling that function.
You can call a function statically, even if it is not declared as static, as long as you don't reference $this inside it.
That is why the original code works.
You cannot, however, change the signature of an inherited method.
Fatal error: Cannot make non static method parentclass::sum() static
in class childclass
When you declare protected static function sum() in childclass, you are changing the signature of the inherited method from parentclass which is not specifically declared static.
Bottomline, you are trying to use some PHP quirks that I would recommend against. Yes, they work, but that doesn't mean you should use them.
Stick to a strict style of coding. Write separate methods for static and instance use and call them as intended.
You are using static as a Late Static Binding. But what you heard about was rather
class Foo
{
static function bar() {}
}
$baz = Foo::bar();
I think to understand late static bindings a bit better you could write a variation of your code:
<?php
error_reporting(E_ALL);
class parentclass
{
protected function sum()
{
return 145;
}
public function do_the_math()
{
printf('Static sum: %d, Self sum: %d',
static::sum(),
self::sum());
}
}
class childclass extends parentclass
{
protected function sum()
{
return 125;
}
}
class grandchild extends childclass
{
function sum()
{
return 100;
}
}
$obj = new grandchild();
$obj->do_the_math();
Output:
Static sum: 100, Self sum: 145
When I defined a function in a supertype and called without parent:: it gave me and error teling me it's undefined function. I am wondering if I should use parent:: each time or if I am doing something wrong somewhere else.
I have a class, named core, which has an escape() function for escaping strings
I am trying to call this function from subtypes.
all methods are static.
Right now I don'T think static methods are inherited. I call all the static superclass methods with
parent::mystaticmethod()
now. Because static methods are not inherited.
use parent:: only when you are going to override function in your child class
Best way to explain this is this example:
class Parent {
function test1() {}
function test2() {}
function __construct() {}
}
class Child extends Parent {
function test1() {} // function is overrided
function test3() {
parent::test1(); // will use Parent::test1()
$this->test1(); // will use Child::test1()
$this->test2(); // will use Parent:test2()
}
function __construct() {
parent::__construct() // common use of parent::
... your code.
}
}
Practical example (static methods):
class LoaderBase {
static function Load($file) {
echo "loaded $file!<br>";
}
}
class RequireLoader extends LoaderBase {
static function Load($file) {
parent::Load($file);
require($file);
}
}
class IncludeLoader extends LoaderBase {
static function Load($file) {
parent::Load($file);
include($file);
}
}
LoaderBase::Load('common.php'); // this will only echo text
RequireLoader::Load('common.php'); // this will require()
IncludeLoader::Load('common.php'); // this will include()
Output:
loaded common.php!
loaded common.php!
loaded common.php!
Anyways using parent:: is more useful in non-static methods.
As of PHP 5.3.0, PHP implements a feature called late static bindings which can be used to reference the called class in a context of static inheritance.
More information here http://php.net/manual/en/language.oop5.late-static-bindings.php
<?php
class MyParent {
public static function tellSomething() {
return __CLASS__;
}
}
class MyChild extends MyParent {
}
echo MyChild::tellSomething();
The code above echos "MyParent". How can i get to name of child class - in this case "MyChild"? If it's possible...
I just simply need to know which child is calling the inherited method.
__CLASS__ is a pseudo-constant, that always refers to the class, where it is defined. With late-static-binding the function get_called_class() were introduced, that resolve the classname during runtime.
class MyParent {
public static function tellSomething() {
return get_called_class();
}
}
class MyChild extends MyParent {
}
echo MyChild::tellSomething();
(as a sidenote: usually methods don't need to know the class on were they are called)
What you are describing is called Late Static Bindings, and it was made available in PHP 5.3.
How do I call child function from parent static function ?
In php5.3 there is a built in method called get_called_class() to call child method from parent class. But my server is running with php 5.1.
Is there any way can do this ?
I want to call it from a static function . So that I can not use "$this"
So i should use "self" keyword.
Below example my parent class is "Test123" , from the parent class static function "myfunc" am trying to call child class function like this "self::test();"
abstract class Test123
{
function __construct()
{
// some code here
}
public static function myfunc()
{
self::test();
}
abstract function test();
}
class Test123456 extends Test123
{
function __construct()
{
parent::__construct();
}
function test()
{
echo "So you managed to call me !!";
}
}
$fish = new Test123456();
$fish->test();
$fish->myfunc();
Edit: What you try to achieve is not possible with PHP 5.1. There is no late static bindings PHP Manual in PHP 5.1, you need to explicitly name the child class to call the child function: Test123456::test(), self will be Test123 in a static function of the class Test123 (always) and the static keyword is not available to call a static function in PHP 5.1.
Related: new self vs new static; PHP 5.2 Equivalent to Late Static Binding (new static)?
If you are referring to a static parent function, then you need to explicitly name the parent (or child) for the function call in php 5.1:
parentClass::func();
Test123456::test();
In PHP 5.3 you can do this instead with the static keyword PHP Manual to resolve the called class' name:
static::func();
static::test();
If those are non-static, just use $this PHP Manual:
$this->parentFunc();
$this->childFunc();
Or if it has the same name, use parent PHP Manual:
parent::parentFunc();
(which is not exactly what you asked for, just putting it here for completeness).
Get_called_class() has been introduced for very specific cases like to late static bindings PHP Manual.
See Object Inheritance PHP Manual
I suspect you are a bit confused abuot parent / child, class / object and function / method.
IonuČ› G. Stan has provided the explanation of how to invoke a method which is not declared in a parent class (which as he says should be abstract or implement the __call() method).
However if you mean how do invoke a method which has been overridden in a child class from the parent, then it is not possible - nor should it be. Consider:
Class shape {
...
}
Class circle extends shape {
function area() {
}
}
Class square extends shape {
function area() {
}
}
If it is your intent to call the area method on an instance of 'shape' (which does not have an area method) then which child should it use? Both the child methods would depend on properties which are not common / not implemented by the shape class.
try this:
<?php
class A {
public static function newInstance() {
$rv = new static();
return $rv;
}
public function __construct() { echo " A::__construct\n"; }
}
class B extends A {
public function __construct() { echo " B::__construct\n"; }
}
class C extends B {
public function __construct() { echo " C::__construct\n"; }
}
?>
I am trying to create a simple MVC my personal use and I could really use an answer to this simple question
class theParent extends grandParent{
protected $hello = "Hello World";
public function __construct() {
parent::__construct();
}
public function route_to($where) {
call_user_func(array("Child", $where), $this);
}
}
class Child extends theParent {
public function __construct() {
parent::__construct();
}
public function index($var) {
echo $this->hello;
}
}
$x = new theParent();
$x->route_to('index');
Now Child::index() this throws a fatal error: Using $this when not in object context but if I were to use echo $var->hello, it works just fine.
I know I can use $var to access all properties in the parent, but I would rather use $this.
By writing call_user_func(array("Child", $where), $this) you are calling the method statically. But as your method isn't static you need some kind of object instance:
call_user_func(array(new Child, $where), $this);
Documentation on callback functions.
You don't have an instance of Child to call a non-static method upon when you're doing $x->route_to('index'); The way you're calling the method, without having made an instance first, is implied static.
There are two ways to correct it. Either make the Child class's methods static:
class Child extends theParent {
public function __construct() {
parent::__construct();
}
static public function index($var) {
echo self::$hello;
}
}
...or make an instance of the child class for the parent to use:
class theParent extends grandParent{
protected $hello = "Hello World";
private $child = false
public function __construct() {
parent::__construct();
}
public function route_to($where) {
if ($this->child == false)
$this->child = new Child();
call_user_func(array($this->child, $where), $this);
}
}
Of course, both of these samples are rather generic and useless, but you see the concept at hand.
$this gives you access to everything visible/accessible in the current object. That can either be in the class itself (this) or any of it's parents public or protected members/functions.
In case the current class overrides something of a parent class, you can access the parent method explicitly using the parent keyword/label, whereas you add :: to it regardless if it is not a static method.
Protected variables exist only once, so you can not use parent to access them.
Is this info of use?