php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #54543 Late Static Binding on Properties and/or Inheritance
Submitted: 2011-04-15 22:46 UTC Modified: 2011-04-16 03:44 UTC
From: bmajdak@php.net Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.3.6 OS: Any
Private report: No CVE-ID: None
 [2011-04-15 22:46 UTC] bmajdak@php.net
Description:
------------
Should late static binding also apply to properties? My test here I would have 
expected each result to be different, not the value of the last created object. It 
is counter-intuitive to work on methods and not properties. I would expect this 
behaviour with self:: but not static::

inb4 "we rejected this multiple times" i do not actually care about the object 
class name like in my example, that was just an easy demo case.

Test script:
---------------
<?php

// [bob@cairne:test]$ php static.php 
// value: two two two

class old {
	static $prop = 'old';
	public function __construct() { static::$prop = get_class($this); }
}

class one extends old { }
class two extends old { }

$one = new one;
$two = new two;

printf("value: %s %s %s\n",old::$prop,one::$prop,two::$prop);

?>

Expected result:
----------------
value: old one two

Actual result:
--------------
value: two two two

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-04-16 01:37 UTC] cataphract@php.net
-Status: Open +Status: Bogus
 [2011-04-16 01:37 UTC] cataphract@php.net
Expected behavior. LSB applies to properties, but in PHP it was decided to have static properties shared between classes and their subclasses (via a reference set), possibly so that they can reliably be used in a non-static contexts. This behavior can be changed by redeclaring the property or manually breaking the reference set (possibly this ought to be documented).
 [2011-04-16 03:24 UTC] bmajdak@php.net
you are correct in your statement about breaking the reference, the following 
example works as i believe should be default.

<?php

class old {
	static $prop = 'old';
	public function __construct() {
	
		static::$prop = &$this;
		// ^^^ daft assignment of any random reference to cause it
		// to break itself. normal assignment will not do it has to 
		// be a reference. comment out that line and instead of
		// "old one two" you will get "two two two"
		
		static::$prop = get_class($this);
		// ^^^ an actual assignment that i care about keeping.
		
		return;
	}
}

class one extends old { }
class two extends old { }

$one = new one;
$two = new two;

printf("value: %s %s %s\n",old::$prop,one::$prop,two::$prop);

?>

nice and jenky.
 [2011-04-16 03:44 UTC] cataphract@php.net
Changing this behavior would be a BC break; consider:

<?php
class A {
	public static $f = 7;
}
class B extends A {
	function m() {
		A::$f = 6;
		return self::$f;
	}
}
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 26 04:01:30 2024 UTC