Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: Overwriting of static methods does not work as expected

I have two php classes: TestUK and TestFR, which extends TestUK.

Both classes are used to generate requests to two different domains. But something is going wrong with the inheritence, and I fail to understand why.

I have one method named "get_domain", which is overwritten to get the domain that should actually be used. If I call it directly via TestFR::get_domain(), i receive the expected result. But if I call a method that is not overwritten by TestFR, but which uses self::get_domain(), I receive the wrong domain.

If I simply copy-and-paste the method do_stuff from TestUK to TestFR, then I get the expected result. But copy-pasting identical (!) code is just what I was trying to avoid.

What is the reason for this? I do not have that much experience with class inheritence in PHP, but I would have expected this to work without problems. Or is my approch completely flawed?

<?php
class TestUK {

    const DOMAIN_UK = 'http://www.domain.co.uk';
    const DOMAIN_FR = 'http://www.domain.fr';

    static function get_domain(){
        return self::DOMAIN_UK;
    }

    static function do_stuff(){
        echo self::get_domain();
    }

}

class TestFR extends TestUK {

    static function get_domain(){
        return self::DOMAIN_FR;
    }

}

// Works as intended:
// Expected and actual output: http://www.domain.fr
echo TestFR::get_domain();

// Does NOT work as intendes:
// Expected Output: http://www.domain.fr
// Actual Output:   http://www.domain.co.uk
TestFR::do_stuff();
?>
like image 760
Majiy Avatar asked Sep 17 '13 11:09

Majiy


People also ask

Can I override static method in PHP?

Here comes the call of static method with static keyword. In case there is no overridden function then it will call the function within the class as self keyword does. If the function is overridden then the static keyword will call the overridden function in the derived class.

Can a static method be overwritten?

Can we override a static method? No, we cannot override static methods because method overriding is based on dynamic binding at runtime and the static methods are bonded using static binding at compile time. So, we cannot override static methods.

Why should static methods not be overwritten?

Static methods are bonded at compile time using static binding. Therefore, we cannot override static methods in Java.

Why not use static methods PHP?

It's generally a bad idea to depend on static methods because they make substitution (and therefore specialising or testing) difficult. It looks like what you have is 10 independent classes that all inherit from the same interface. But without explaining what those functions do, its impossible to say how to improve.

What is static saysomething method in PHP?

A saySomething method is invoked statically without creating an instance of a class. In PHP 7, calling the saySomething method statically produces a warning and prints Hello message. Since PHP 8.0, no longer allows to call non-static class methods statically.

How to call a static method from another class in PHP?

Then, we call the static method by using the class name, double colon (::), and the method name (without creating an instance of the class first). PHP - More on Static Methods A class can have both static and non-static methods. A static method can be accessed from a method in the same class using the self keyword and double colon (::):

How to get an overloaded variable from a function in PHP5?

Php 5 has a simple recursion system that stops you from using overloading within an overloading function, this means you cannot get an overloaded variable within the __get method, or within any functions/methods called by the _get method, you can however call __get manualy within itself to do the same thing.

What is a non-static method in PHP?

A non-static method is a method that belongs to an instance of a class. In all PHP 7 versions, calling non-static methods statically is deprecated and emits a warning ( E_DEPRECATED ). Let’s say we have a User class with one non-static method: A saySomething method is invoked statically without creating an instance of a class.


2 Answers

This is because the keyword self refers to the class where it appears in, not to the class on which the method was called. For the latter functionality you will have to use late static binding with the static keyword:

static function do_stuff(){
    echo static::get_domain();
}

That said, this code smells really bad. Why is everything static and not simply an instance method? Why is TestFR extending TestUK instead of both extending an abstract base class Test?

It would be much better to convert everything to non-static methods, and as a bonus your problem would immediately disappear.

like image 53
Jon Avatar answered Nov 06 '22 14:11

Jon


call it like (if you are using php >= 5.3

static::get_domain();
like image 27
shankhan Avatar answered Nov 06 '22 16:11

shankhan