FRIHOST FORUMS SEARCH FAQ TOS BLOGS COMPETITIONS
You are invited to Log in or Register a free Frihost Account!


static keyword in PHP





inuyasha
I've been working on a project and come across a weird problem this morning. The code is simplified below.
Code:

<?php

class A{
   public function GetTableName(){
      return static::NAME;
   }
}

class B extends A{
   const NAME = 'B';
}

class C{
   const NAME = 'C';

   public function getBTableName(){
      return B::GetTableName();
   }
}

$c = new C();
echo $c->getBTableName();

?>


What output do you expect? B or C?

I thought it were B but unfortunately it is C. Sad
manfer
public static function GetTableName

Code:

class A{
   public static function GetTableName(){
      return static::NAME;
   }
}

class B extends A{
   const NAME = 'B';
}

class C{
   const NAME = 'C';

   public function getBTableName(){
      return B::GetTableName();
   }
}

$c = new C();
echo $c->getBTableName();
inuyasha
@manfer
Thanks ~ It works~ But I don't understand. Why must the method be static?
I thought non-static methods could be called with class::method() and worked as it is static, for a historical reason, that there's no static keyword in php 4.
manfer
Code:
error_reporting(E_ALL | E_STRICT);

class A{
   public function GetTableName(){
      return static::NAME;
   }
}

class B extends A{
   const NAME = 'B';
}

class C{
   const NAME = 'C';

   public function getBTableName(){
      return B::GetTableName();
   }
}

$c = new C();
echo $c->getBTableName();


You shouldn't call non static methods with ::

Any class method must be static.

Calling a static method, a class method from an instance of the class is correct. Calling a non static method with the class and not with an instance of the class is wrong.

CLASS::static_method CORRECT
Intance_of_type_CLASS::static_method CORRECT
Instance_of_type_CLASS->non_static_method CORRECT

CLASS->non_static_method INCORRECT
CLASS::non_static_method INCORRECT (from outside the class)

I would suggest you to use:
Code:
error_reporting(E_ALL | E_STRICT);

during development
inuyasha
@manfer
Yeah, it's really not supposed to call a non-static method with ::, though PHP allows it for backwards compatibility purpose, and my method doesn't access non-static properties. It works differently without "static" now.
Just want to know how come it accesses the constant NAME in class C. Question static::method() seems to be added in PHP 5.3. Is that a new bug?
manfer
inuyasha wrote:
@manfer
Yeah, it's really not supposed to call a non-static method with ::, though PHP allows it for backwards compatibility purpose, and my method doesn't access non-static properties. It works differently without "static" now.
Just want to know how come it accesses the constant NAME in class C. Question static::method() seems to be added in PHP 5.3. Is that a new bug?


In my opinion is not a bug, is what you are coding.

As already said PHP gives you a E_STRICT warning, so if you as developer decide to don't take that into account, it is your own decision.

There is nothing wrong on accesing the constant on the C class as it is public. You could just have accesed its value with C::NAME. If you were trying to access something private on C from outside C you wouldn't have been allowed to.

Look the PHP documentation about the late static binding carefully and study the examples.
http://php.net/manual/en/language.oop5.late-static-bindings.php
There is already an example of what you should expect when using static:: in a non static context. If you read it you'll understand it is not so strange that static:: is being derreferenced as class C while you were specting the result on a static context, class B.
inuyasha
@manfer
So the fact is, backwards compatibility for PHP 4 no longer exists?
I expect a non-static method without access to non-static properties acts like a static method if called with class::method(). That's how it works in PHP 4. And PHP 5 introduced static keyword, and promised that's an acceptable syntax, though with an "error" you can ignore or not, as it still works.
Besides, error_reporting(E_ALL ^ E_NOTICE); works fine for me.

And that example doesn't explain my confusion. I didn't call it with $obj->method()
manfer
inuyasha wrote:
@manfer
So the fact is, backwards compatibility for PHP 4 no longer exists?
I expect a non-static method without access to non-static properties acts like a static method if called with class::method(). That's how it works in PHP 4. And PHP 5 introduced static keyword, and promised that's an acceptable syntax, though with an "error" you can ignore or not, as it still works.
Besides, error_reporting(E_ALL ^ E_NOTICE); works fine for me.

And that example doesn't explain my confusion. I didn't call it with $obj->method()


You start in a non static context $c->getBTableName()

If you change the code to C::getBTableName or you make the function getBTableName static or you make getTableName static you get the expected result from static::NAME

I would avoid any E_STRICT warnings when coding. That makes code more robust. Something you are not doing with E_ALL ^ E_NOTICE, you ignore E_STRICT warnings. Though warnings are just warnings and not errors, of course. In PHP 5.4 E_ALL includes E_STRICT (I bet to make people take more care about E_STRICT warnings). So with E_ALL ^ E_NOTICE you are going to start seeing those warnings in PHP 5.4. I wouldn't care about PHP4 compatibility nowadays, I don't mind my code not working in PHP4 (it shouldn't be used anymore as it has not support now), but that is a personal choice.
Related topics
Great php editor
How to get your dynamic PHP website crawled better by se ?
Editing static HTML pages and CSS in PHP
Php sms
Some php probs..need some help plzz!
[PHP] Faking Shell Access Through PHP
PHP VS ASP
How to get your Site higher on Google.
Layout Gap PRoblems with PHP/Javascript Combo
emailing Via PHP
php and xml
Solved: Need convert php-template to css-html static
Serve static content from a cookieless domain
having difficulties understanding OOP
Reply to topic    Frihost Forum Index -> Scripting -> Php and MySQL

FRIHOST HOME | FAQ | TOS | ABOUT US | CONTACT US | SITE MAP
© 2005-2011 Frihost, forums powered by phpBB.