{"id":183,"date":"2017-02-10T14:33:10","date_gmt":"2017-02-10T14:33:10","guid":{"rendered":"https:\/\/miklcct.com\/wordpress\/?p=183"},"modified":"2017-04-01T08:47:27","modified_gmt":"2017-04-01T08:47:27","slug":"static-in-php","status":"publish","type":"post","link":"https:\/\/miklcct.com\/wordpress\/2017\/02\/10\/static-in-php\/","title":{"rendered":"static in PHP"},"content":{"rendered":"<p><code>static<\/code> keyword is used to represent class members, i.e. members which are shared among the class, as opposed of instance members which is unique to an object instance, in many programming languages, including PHP. However, the static functionality in PHP is much more powerful than in some other traditional programming languages, for example, C++ and Java, because in PHP polymorphism can also be achieved using static members in addition to instance members.<\/p>\n<p>In C++ and Java, a static member is always resolved at compile time using the declared type. Using the following code as an example:<\/p>\n<p>C++ code:<\/p>\n<pre>#include &lt;iostream&gt;\r\n#include &lt;string&gt;\r\nusing std::cout;\r\nusing std::string;\r\n\r\nclass Base {\r\npublic:\r\n    static string hello() {\r\n        return message;\r\n    }\r\nprotected:\r\n    static string message;\r\n};\r\n\r\nclass Intermediate : public Base {\r\nprotected:\r\n    static string message;\r\n};\r\n\r\nclass Derived : public Intermediate {\r\npublic:\r\n    static string hello() {\r\n        return \"Derived: \" + message;\r\n    }\r\nprotected:\r\n    static string message;\r\n};\r\n\r\nstring Base::message = \"Hello!\";\r\nstring Intermediate::message = \"Howdy!\";\r\nstring Derived::message = \"Hi!\";\r\n\r\nvoid test(Base *object) {\r\n    cout &lt;&lt; Intermediate::hello() &lt;&lt; '\\n';\r\n    cout &lt;&lt; object-&gt;hello() &lt;&lt; '\\n';\r\n}\r\n\r\nint main() {\r\n    test(new Derived());\r\n    return 0;\r\n}\r\n<\/pre>\n<p>Java code:<\/p>\n<pre>class Base {\r\n    protected static String message = \"Hello!\";\r\n    public static String hello() {\r\n        return message;\r\n    }\r\n}\r\n\r\nclass Intermediate extends Base {\r\n    protected static String message = \"Howdy!\";\r\n}\r\n\r\nclass Derived extends Intermediate {\r\n    protected static String message = \"Hi!\";\r\n    public static String hello() {\r\n        return \"Derived: \" + message;\r\n    }\r\n}\r\n\r\npublic class Main {\r\n    private static void test(Base object) {\r\n        System.out.println(Intermediate.hello());\r\n        System.out.println(object.hello());\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        test(new Derived());\r\n    }\r\n}\r\n<\/pre>\n<p>Both programs outputs<\/p>\n<pre>Hello!\r\nHello!\r\n<\/pre>\n<p>when run, indicating <code>Base::hello()<\/code> is called with <code>message<\/code> resolved to <code>Base::message<\/code> inside <code>Base::hello()<\/code>. It is because, in both C++ and Java, all static members are resolved using the static (i.e. declared) type of the expression, which means <code>object-&gt;hello()<\/code> is the same as <code>Base::hello()<\/code> because <code>object<\/code> is declared to be of type <code>Base *<\/code>. Moreover, inside <code>Base::hello()<\/code>, <code>message<\/code> refers to <code>Base::message<\/code> because the scope is in class <code>Base<\/code>. The fact that <code>hello()<\/code> is called using <code>Intermediate::hello()<\/code> does not matter.<\/p>\n<p>Now consider the following piece of similar PHP code:<\/p>\n<pre>&lt;?php\r\nclass Base {\r\n    protected static $message = \"Hello!\";\r\n    public static function hello() {\r\n        return self::$message;\r\n    }\r\n}\r\n\r\nclass Intermediate extends Base {\r\n    protected static $message = \"Howdy!\";\r\n}\r\n\r\nclass Derived extends Intermediate {\r\n    protected static $message = \"Hi!\";\r\n    public static function hello() {\r\n        return \"Derived: \" . self::$message;\r\n    }\r\n}\r\n\r\nfunction test(Base $object) {\r\n    echo Intermediate::hello() . \"\\n\";\r\n    echo $object-&gt;hello() . \"\\n\";\r\n}\r\n\r\ntest(new Derived());\r\n<\/pre>\n<p>Running the PHP code gets:<\/p>\n<pre>Hello!\r\nDerived: Hi!\r\n<\/pre>\n<p>which indicates that <code>Derived::hello()<\/code> get called in <code>$object-&gt;hello()<\/code> despite <code>$object<\/code> being declared as a <code>Base<\/code> in the function header. It is because, despite the type declaration in the function header, PHP is a dynamically-typed language where types are only associated with value but not the expression itself, which means the expression <code>$object<\/code> is not associated with a type without regarding to its value. The type declaration is only checked when an argument is passed into it at the point of calling and unused afterwards. It is not an error to reassign <code>$object<\/code> to something else inside the function. Therefore, when calling <code>$object-&gt;hello()<\/code>, the type of <code>$object<\/code> is retrieved from the <code>$object<\/code> at runtime, therefore, <code>Derived::hello()<\/code> is called because <code>$object<\/code> is a <code>Derived<\/code>.<\/p>\n<p>For the call to <code>Intermediate::hello()<\/code>, the effect is the same as in C++ and Java, where the keyword <code>self<\/code> resolves to the class where the function is in. However, if we replace the keyword <code>self<\/code> by <code>static<\/code>, <i>magic<\/i> happens, which works for PHP version at least 5.3:<\/p>\n<pre>&lt;?php\r\nclass Base {\r\n    protected static $message = \"Hello!\";\r\n    public static function hello() {\r\n        return static::$message;\r\n    }\r\n}\r\n\r\nclass Intermediate extends Base {\r\n    protected static $message = \"Howdy!\";\r\n}\r\n\r\nclass Derived extends Intermediate {\r\n    protected static $message = \"Hi!\";\r\n    public static function hello() {\r\n        return \"Derived: \" . static::$message;\r\n    }\r\n}\r\n\r\nfunction test(Base $object) {\r\n    echo Intermediate::hello() . \"\\n\";\r\n    echo $object-&gt;hello() . \"\\n\";\r\n}\r\n\r\ntest(new Derived());\r\n<\/pre>\n<p>Running the above code shows:<\/p>\n<pre>Howdy!\r\nDerived: Hi!\r\n<\/pre>\n<p>Now, in the call of <code>Intermediate::hello()<\/code>, <code>Intermediate::$message<\/code> is returned from the function! The <code>$message<\/code> member in <code>Intermediate<\/code> has <i>overridden<\/i> the <code>Base<\/code> member and polymorphism is exhibited as the function in <code>Base<\/code> got the value of <code>Intermediate::$message<\/code>.<\/p>\n<p>The magic is that, starting from PHP 5.3, static function calls have an implicit <code>static<\/code> scope, just like non-static function calls having an implicit <code>$this<\/code> variable. The <code>static<\/code> scope is set by the language to be the class where the function is called, i.e., in the call of <code>Intermediate::hello()<\/code> the <code>static<\/code> scope is <code>Intermediate<\/code>, and in the call of <code>$object-&gt;hello()<\/code> the <code>static<\/code> scope is <code>Derived<\/code> because <code>$object<\/code> is of type <code>Derived<\/code> (compared to the fact that, if <code>hello()<\/code> were non-static, <code>$this<\/code> would be set to <code>$object<\/code>). Furthermore, calling methods using <code>self::<\/code>, <code>static::<\/code> or <code>parent::<\/code> also forwards the <code>static<\/code> scope to the called method.<\/p>\n<p>Using this feature, it is possible to do class-based polymorphism in PHP using static methods, properties and class constants, which serves as a complement to normal polymorphism using objects. In modern PHP version static methods are subject to compatibility rules regarding function signature if overriden, can be declared abstract, and can be placed inside interfaces, just like non-static functions. You can even use <code>new static<\/code> in factory methods to create objects of child classes without any knowledge of them as long as the child constructor is compatible with the parent constructor, which is impossible in Java without using reflection.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>static keyword is used to represent class members, i.e. members which are shared among the class, as opposed of instance members which is unique to an object instance, in many programming languages, including PHP. However, the static functionality in PHP is much&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[38],"class_list":["post-183","post","type-post","status-publish","format-standard","hentry","category-programming","tag-static"],"_links":{"self":[{"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/posts\/183","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/comments?post=183"}],"version-history":[{"count":2,"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/posts\/183\/revisions"}],"predecessor-version":[{"id":186,"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/posts\/183\/revisions\/186"}],"wp:attachment":[{"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/media?parent=183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/categories?post=183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/miklcct.com\/wordpress\/wp-json\/wp\/v2\/tags?post=183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}