Static and Non-Static Calling in PHP - php

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.

Related

How to access non-static method from within a static method?

I have two methods in a class, one of which is static. I want to access the non-static method from within the static method. Is that possible? I tried this:
class Foo {
public function qux(){
}
public static function waldo(){
self::qux(); // Non-static method Foo::qux() should not be called statically
}
}
Is making qux a static method the only way to achieve this? What if the user doesn't want qux() to be a static method?
This should work as you need:
class Foo {
public function qux(){
}
public static function waldo(){
$foo = new Foo();
$foo->qux();
}
}
There is no other way to call a dynamic method/function without creating the object itself first.
Of course, if you will use the object only one-time and call all methods or functions immediately, you could use something like this:
class Foo {
public function qux(){
}
public static function waldo(){
(new Foo())->qux();
}
}
class Foo {
public function qux(){
}
public static function waldo(){
$obj = new Static();
$obj->qux();
}
}

PHP return object instance from __getStatic()

PHP has a magic method __getStatic() that allows overloading of static method calls. I have a class with a fluent interface which performs integrity checks. I call it like this:-
$check = new CheckSomeCondition();
$check->forActive()->sites(array(1,2,3))->check();
However, I would like to call it like this:-
CheckSomeCondition::forActive()->sites(array(1,2,3))->check();
I thought that having this magic method in my base class would allow me to do this:-
public static function __callStatic($method, $args)
{
$instance = new self();
return call_user_func_array(array($instance, $method), $args);
}
But new self() produces an instance of the class that the calling code is in, and not the class which __callStatic() exists in, why is this? and how can I get around it?
I have also tried new static and this does the same thing.
I know this must be possible because Laravel's QueryBuilder has an interface like DB::table()->... and this uses method chaining, returning object instances, not static classes. I have had a look at the Laravel code, but I think they create the instances somewhere else in the application and they are stored in a class member ready to be returned.
The magic method __callStatic is only called for methods which don't exist, so in this case it will simply not run.
Consider the following simplified example:
class Foo
{
public function bar()
{
echo "Running instance method bar()";
}
public static function __callStatic($method, $args)
{
echo "__callStatic called for non-existent method $method";
}
}
Foo::bar();
If you run this (here's an online demo) you will see that it is the "real" bar() method that is called.
There can only be one method named bar on the class, so PHP's only other option would be to complain that bar() should be static - which it does, but non-fatally.
The reason you see an instance of the calling class is not that $instance is instantiated with the wrong class, but because when your method is called non-statically, $this "leaks" from the enclosing scope.
In the following example, $this ends up being the instance of Bar:
class Foo
{
public function doSomething()
{
echo get_class($this);
}
}
class Bar
{
public function doSomethingElse()
{
Foo::doSomething();
}
}
$bar = new Bar();
$bar->doSomethingElse();
Live Demo
As #IMSoP pointed out, __getStatic() is only called if there is no method with the name called - not just if there isn't a static method with the name.
So the workaround to allow calls such as CheckClass::forActive->sites() is to give all the non static method names a prefix such as '_' and have a magic method __call() which will add the prefix in.
This means if I do CheckClass::forActive() the method forActive() doesn't exist, so __getStatic() will be called and will create an instance of the object and try to call the desired method. But the method doesn't exist because we've prefix it, so PHP will call the __call() magic method which will add the prefix and call the prefixed method.
So the 2 functions are:-
public static function __callStatic($method, $args)
{
$instance = new self;
return call_user_func_array(array($instance, $method), $args);
}
public static function __call($method, $args)
{
$method = 'prefix_' . $method;
return call_user_func_array(array($instance, $method), $args);
}
// Then all our method names need to be prefixed, like so:-
public static function prefix_SomeMethod($method, $args)
{
// Do something
return $this;
}

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.

call a static method inside a class?

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

php static function

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. :(

Categories