I have a question regarding static function in php.
let's assume that I have a class
class test {
public function sayHi() {
echo 'hi';
}
}
if I do test::sayHi(); it works without a problem.
class test {
public static function sayHi() {
echo 'hi';
}
}
test::sayHi(); works as well.
What are the differences between first class and second class?
What is special about a static function?
In the first class, sayHi() is actually an instance method which you are calling as a static method and you get away with it because sayHi() never refers to $this.
Static functions are associated with the class, not an instance of the class. As such, $this is not available from a static context ($this isn't pointing to any object).
Simply, static functions function independently of the class where they belong.
$this means, this is an object of this class. It does not apply to static functions.
class test {
public function sayHi($hi = "Hi") {
$this->hi = $hi;
return $this->hi;
}
}
class test1 {
public static function sayHi($hi) {
$hi = "Hi";
return $hi;
}
}
// Test
$mytest = new test();
print $mytest->sayHi('hello'); // returns 'hello'
print test1::sayHi('hello'); // returns 'Hi'
Entire difference is, you don't get $this supplied inside the static function. If you try to use $this, you'll get a Fatal error: Using $this when not in object context.
Well, okay, one other difference: an E_STRICT warning is generated by your first example.
Calling non-static methods statically generates an E_STRICT level warning.
In a nutshell, you don't have the object as $this in the second case, as
the static method is a function/method of the class not the object instance.
After trying examples (PHP 5.3.5), I found that in both cases of defining functions you can't use $this operator to work on class functions. So I couldn't find a difference in them yet. :(
Related
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() ?
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.
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
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).
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
I am calling a function inside a class, function is outside the class. I want to pass $this of the class to that function,
currently I am doing this:
class foo {
func_outside_class($this);
}
function func_outside_class($context){
return $context;
}
Is there a way so that I don't need to pass context as function parameter.
Or my above code is OK?
I cannot create an object inside function, cause this class need some parameters.
#Barmar wrote:
There's nothing wrong with passing $this to an outside function. But I don't understand why you're immediately overwriting the $context variable -- why does the function take an argument if it's not using it? Perhaps you mean $this = $context.
If that's that case, I don't think you can do it. You're not allowed to assign $this, it's a special variable that always contains the current object in a class method.
In the outside function, you can simply do $context->method(...) to use it instead.
If you're trying to just reference methods inside of you class you can do something like this
class Foo {
public function bar() {
return 'Hello World';
}
}
function func_outside_class() {
// instantiate class
$foo = new Foo;
// call method bar() from Foo class
echo $foo->bar();
}
I've seen this use of syntax a few times on the Yii framework. I tried searching for an explanation but got no examples. A link will be nice if possible. It goes something like class::model()->function();
My understanding is that model is an object of class therefore it can access the function. So I tried to code it but I get " Call to a member function sound() on a non-object in". Here's my code
class animal
{
private static $obj;
public static function obj($className = __CLASS__)
{
return self::$obj;
}
public static function walk()
{
return "walking";
}
}
include('animal.php');
class cat extends animal
{
public static function obj($className = __CLASS__)
{
return parent::obj($className);
}
public static function sound()
{
return "meow";
}
}
echo cat::obj()->sound();
Also what benefits does it have?
That is called an object operator and this, ->, calls a class method from your created object which is defined in that class.
Here is an explanation and some examples.
$obj = new Class; // Object of the class
$obj->classMethod(); // Calling a method from that class with the object
echo cat::obj()->sound();
This will display the output of the sound() method, called on the object that is returned from cat::obj().
The reason it's failing for you is because cat::obj() is not returning a valid object.
And the reason for that is because the obj() method returns the static obj property, but you're not actually setting that obj property anywhere.
The pattern you're trying to use here is known as a "Singleton" object. In this pattern, you call an obj() method to get the single instance of the class; every call to the method will give you the same object.
However the first call to the method needs to instantiate the object; this is what you're missing.
public static function obj($className = __CLASS__){
if(!static::$obj) {static::$obj = new static;}
return static::$obj;
}
See the new line where the object is created if it doesn't exist.
Also note that I've changed self to static. The way you're using this with class inheritance means that you probably expect to have a different static object for each class type, self will always return the root animal::$obj property, whereas static will return the $obj property for whichever class you're calling it from.
There are a few other bugs you need to watch out for too. For example, you've defined the sound() method as static, but you're calling it with ->, so it shouldn't be static.
Hope that helps.
The cat::obj() returns you a object of the type cat. With ->sound(); you're executing the function sound() from the class cat. All that should return "meow".
cat::obj() returns an object; ->sound(); execute a method of this object. Equivalent is
$o = cat::obj();
$o->sound();
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.
how do i call a static method from another method inside the same class?
$this->staticMethod();
or
$this::staticMethod();
self::staticMethod();
More information about the Static keyword.
Let's assume this is your class:
class Test
{
private $baz = 1;
public function foo() { ... }
public function bar()
{
printf("baz = %d\n", $this->baz);
}
public static function staticMethod() { echo "static method\n"; }
}
From within the foo() method, let's look at the different options:
$this->staticMethod();
So that calls staticMethod() as an instance method, right? It does not. This is because the method is declared as public static the interpreter will call it as a static method, so it will work as expected. It could be argued that doing so makes it less obvious from the code that a static method call is taking place.
$this::staticMethod();
Since PHP 5.3 you can use $var::method() to mean <class-of-$var>::; this is quite convenient, though the above use-case is still quite unconventional. So that brings us to the most common way of calling a static method:
self::staticMethod();
Now, before you start thinking that the :: is the static call operator, let me give you another example:
self::bar();
This will print baz = 1, which means that $this->bar() and self::bar() do exactly the same thing; that's because :: is just a scope resolution operator. It's there to make parent::, self:: and static:: work and give you access to static variables; how a method is called depends on its signature and how the caller was called.
To see all of this in action, see this 3v4l.org output.
This is a very late response, but adds some detail on the previous answers
When it comes to calling static methods in PHP from another static method on the same class, it is important to differentiate between self and the class name.
Take for instance this code:
class static_test_class {
public static function test() {
echo "Original class\n";
}
public static function run($use_self) {
if($use_self) {
self::test();
} else {
$class = get_called_class();
$class::test();
}
}
}
class extended_static_test_class extends static_test_class {
public static function test() {
echo "Extended class\n";
}
}
extended_static_test_class::run(true);
extended_static_test_class::run(false);
The output of this code is:
Original class
Extended class
This is because self refers to the class the code is in, rather than the class of the code it is being called from.
If you want to use a method defined on a class which inherits the original class, you need to use something like:
$class = get_called_class();
$class::function_name();
In the later PHP version self::staticMethod(); also will not work. It will throw the strict standard error.
In this case, we can create object of same class and call by object
here is the example
class Foo {
public function fun1() {
echo 'non-static';
}
public static function fun2() {
echo (new self)->fun1();
}
}
call a static method inside a class
className::staticFunctionName
example
ClassName::staticMethod();