call a static method inside a class? - php

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();

Related

Determine the name of the calling class (parent or child) in parent class method

Looking for a clean way to determine the class (in this case, either parent or child class) of the method that calls a method in the parent class.
I thought late static binding could handle this, but seems like that only really works for calling a static method directly, and not from within an instantiated object's method.
Consider the following:
abstract class ParentClass {
public function parentMethod() {
self::_log("parent.non.static");
}
public static function parentStatic() {
self::_log("parent.static");
}
public static function getClassName() {
return __CLASS__;
}
protected static function _log($key) {
$prefix = 'graphite.key.prefix';
$class = static::getClassName(); // gets the object's class, not calling class
$g_key = "{$prefix}.{$class}.{$key}";
echo "{$g_key} \n";
// Graphite::increment($g_key);
}
}
class ChildClass extends ParentClass {
public function childMethod() {
self::_log("child.non.static");
}
public static function childStatic() {
self::_log("child.static");
}
public static function getClassName() {
return __CLASS__;
}
}
$obj = new ChildClass;
$obj->childMethod(); // graphite.key.prefix.ChildClass.child.non.static
$obj->parentMethod(); // graphite.key.prefix.ChildClass.parent.non.static
ParentClass::parentStatic(); // graphite.key.prefix.ParentClass.parent.static
ChildClass::childStatic(); // graphite.key.prefix.ChildClass.child.static
Looking for a clean way to get the class that calls the _log() method without having to pass it in as a parameter. Doesn't have to be static at all, but I was playing around with the late static binding, because I thought that would work, but it just gets the name of the instantiated object, not the child/parent class of the method that calls the _log() method :-/
Edit:
Just to be clear, I'm after getting the class name of the method that called _log() from within the instantiated object (like parentMethod() and childMethod()) Don't care if _log() is static or not. If that makes it easier, fine. But the static ParentClass::parentStatic() and ChildClass::childStatic() were just to show late static bindings and what I figured might work, but not from calling within an instantiated object
http://php.net/manual/en/function.get-called-class.php
class One {
public static function test() {
echo get_called_class() . PHP_EOL;
}
}
class Two extends One {}
One::test();
Two::test();
Output:
One
Two
Also, according to the top comment in the docs static::class also works as of PHP 5.5.
get_class will get the class name of a class instance. This can also be called on $this within a class. If you have a class that extends/implements another, $this will refer the the instantiated class, meaning the child class.
Another option is to use debug_backtrace to get the stack of functions that lead up to where you currently are. You can parse the returned array to get whatever you need including line numbers, classes, functions, methods, whatever.

different between static:: and $this-> and which syntax i should use?

I have some code:
class a {
public static function getCl() {
echo __CLASS__;
}
public function test() {
static::getCl();
}
}
class b extends a {
public static function getCl() {
echo __CLASS__;
}
}
$testClass = new b();
$testClass->test();
and this result : b. Then i try this:
class a {
public static function getCl() {
echo __CLASS__;
}
public function test() {
$this->getCl();
}
}
class b extends a {
public static function getCl() {
echo __CLASS__;
}
}
$testClass = new b();
$testClass->test();
this result is still b. I already know the different between static:: and self:: but can someone show me what is the different between static:: and $this-> in my code. Which one should i use?
Your context will produce the same result.
Here is simply description about both.
static:- refers late static binding 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.
Static references to the current class like self:: or CLASS are resolved using the class in which the function belongs, as in where it was defined:
While Late static bindings tries to solve that limitation by introducing a keyword that references the class that was initially called at runtime. Basically, a keyword that would allow you to reference child class from parent class method. It was decided not to introduce a new keyword but rather use static that was already reserved.
$this:- refers current object.
Once inside an object's function, you have complete access to its variables, but to set them you need to be more specific than just using the variable name you want to work with. To properly specify you want to work with a local variable, you need to use the special $this variable, which PHP always sets to point to the object you are currently working with.

Having Issues with Magic Static Functions

I have a class that I'm trying to create a function that will call a static method that is run through a magic method. The thing is the functions work as long as they are from different types of classes than the class calling them, but if I call a static function of the same class all the function will return is 1.
class Test {
public function static __callStatic($name, $params) {
return 2;
}
public function __call($name, $params) {
return 1;
}
public function Test1() {
return Test::GetTwo();
}
}
class Test2 {
public function Test() {
return Test::GetTwo();
}
}
$t = new Test();
echo $t->Test1(); //prints 1 should be 2
$t2 = new Test2();
echo $t->Test(); //prints 2 as it should
even if the static method GetTwo() returns an object I still get 1 if I'm calling a function in the same scope as Test1(). Any one else run into this?
echo Test::Test1();
You don't need (nor should use) an instance to call a static method. Use the class and the scope resolution operator (::) to do the call.
If you need late static binding use static::Test1();
For an method call on an instance, PHP will try the following:
Find an instance method named X.
Find a magic method __call.
Find a class (static) method named X.
Find a magic class (static) method __callStatic.
In your case, it finds __call at step 2 and goes with that.

require_once() in a class

I noticed that if I declare a function inside a class method that has the same name as a outside function I get a error:
function a(){
...
}
class foo{
public function init(){
function a(){ // <- error
...
}
...
}
}
this however would work:
function a(){
...
}
class foo{
public static function a(){
...
}
}
Can I include a set of functions that act as static methods for this class using require_once or something like that?
require_once('file.php'); after class foo{ doesn't work...
PHP allows to nest function declarations in others, but it doesn't actually have nested functions. They always end up in the global scope. So the a() that you define in your init method clashes with the already defined function a().
The static function a() is associated with the class namespace, even if it behaves like a function, not a method.
Invoking a require_once statement in a class definition is not possible. The PHP syntax does not allow for it. Class definitions are special scopes / language constructs, that only allow function or variable declarations within the immediate parsing level. - So PHP does not allow for that (classes and their methods must be declared at once, not assembled), and there are no really nice or advisable workarounds for what you want.
If your class structure allows, you can split the class into several different classes which are part of an inheritance chain:
class foo1 {
public static function a() {}
}
class foo extends foo1 {
public static function b() {}
}
Alternatively, you can use __callStatic() if you are willing to take the performance hit. (Requires PHP 5.3; though if you only need non-static methods, __call is available from 5.0.) Smarty 3 does this IIRC.
class foo {
private static $parts = array('A', 'B');
public static __callStatic($name, $arguments) {
foreach (self::$parts as $part) {
if (method_exists($part, $name)) {
return call_user_func_array(array($part, $name), $arguments);
}
}
throw new Exception();
}
}
class A {
public static function a() {}
}
class B {
public static function b() {}
}
PHP 5.4 will supposedly include traits, which are a more straightforward way of including external code in a class:
class foo {
use A, B;
}
trait A {
public static function a() {}
}
trait B {
public static function b() {}
}
To answer the question: you should first check whether or not the function a has already been implemented by using function_exists:
class foo{
public function init(){
if(!function_exists('a')):
function a(){ // <- will only be declared when it doesn't already exist
...
}
endif;
...
}
}
However, consider this as a very bad coding practice. It will get a mess pretty soon as you have no idea of what's going on exactly and what function will be used. I'd say you'd be better off using a subclass and require_once the appropriate subclass.
Assuming not defining the second "a" method is not acceptable, you'll need to move it outside the init method.
It sounds like your require_once call is the problem (definitely should not be called inside the class). Could you post a full sample including your require_once call that isn't working ?

Why can't bee() call bar() unless I prepend self::?

Why can't bee() call bar() unless I prepend self:: ?
class X {
function bar ()
{
echo "OK";
}
public static function bee ()
{
bar ();
}
};
$x = new X ();
$x->bee ();
static functions do not have access to the $this pointer, but what you have written there is actually trying to call the global function bar(). A regular call to a method on $x would be something like:
class X
{
...
static function Bee()
{
$this->Bar();
}
}
but this is not good practice because then your static function depends on being called from an object and there is no point in having it be static.
http://en.wikipedia.org/wiki/Method_(computer_programming)#Static_methods
As mentioned above, a method may be
declared as static, meaning that it
acts at the class level rather than at
the instance level. Therefore, a
static method cannot refer to a
specific instance of the class (i.e.
it cannot refer to this, self, Me,
etc.), unless such references are made
through a parameter referencing an
instance of the class, although in
such cases they must be accessed
through the parameter's identifier
instead of this. Most importantly
there is no need to make an object for
accessing data .i.e. without creating
an object we can access the data
members of a static class.
you are insight of a static method.
Inside of a static method you are not in the object context so you cannot call the method with $this, ...
self::bar() or X::bar (); does the job...
But be carefull. Stuff like that is not possible if you call it from a static method:
function bar ()
{
echo $this->test;
}
I would not make the method static unless you need it!
BR,
TJ
Static methods get called via the scope resolution operator ::
X::bee();
Then inside bee() you call bar(), what is a regular function, not a method. Here you must call it the same way as mentioned above, but you can simplify the scope identifier to self
public static bee () {
self::bar();
}
Just to remember: Every "function" inside a class is in real a method. If you omit the visibility identifier public is implicitly assumed, but it will remain a method and must be called like this.
I see bar() is not static. To call a regular method you need an instance of the object within the context you are going to call it. Here you can either make bee() non-static (then $this as reference to the current object is avaible), or you instanciate a new object within bee().
class X {
public function bar () { /* .. */ }
public function bee () { $this->bar(); }
}
$x = new X;
$x->bee();
or
class X {
public function bar () { /* .. */ }
public static function bee () {
$x = new self();
$x->bar();
}
}
X:bee();
Whats better depends on what the methods should do (meaning: Whats the design of the class in whole):

Categories