note 92148 added to language.oop5.static
| From: | sep16 at psu dot edu | Date: | Fri, 10 Jul 2009 19:32:57 +0000 |
| Subject: | note 92148 added to language.oop5.static | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-158174@lists.php.net to get a copy of this message | ||
I find having class variables useful for inherited classes, especially when inheriting abstract
classes, yet self:: doesn't refer to the class calling the method, rather the actual class in
which it was defined. Although it is less memory efficient, this can be circumvented with instance
properties, but sometimes even this won't work, i.e., when using resources like class-wide
database or prepared statement handles.
The pre-5.3.0 way that I used to get around this limitation was to write a class that stores a
central value and sets instance properties as references to this value. In this way objects can
have access to the same value while still being able to use inherited methods that reference this
property.
Usage example:
<?php // (SharedPropertyClass is defined below)
class Foo extends SharedPropertyClass {
public $foo = "bar";
public function showFoo() {
echo $this->foo, "\n";
}
}
class FooToo extends Foo {
public function __construct() {
$this->makeShared('foo');
}
}
$ojjo = new FooToo;
$ojjo->showFoo(); // "bar"
$xjjx = new FooToo;
$xjjx->showFoo(); // "bar"
$ojjo->foo = "new";
$ojjo->showFoo(); // "new"
$xjjx->showFoo(); // "new"
?>
Notice how the showFoo() method, while defined in the parent class, correctly uses the child
class's "foo" property (unlike self:: would), and how the "foo" property is
shared by all instances of FooToo objects (like a static property). This is essentially how the new
static:: keyword will work, and how most people probably expected the self:: keyword to work.
<?php
// ---------------------------------------------------------------
abstract class SharedPropertyClass {
// ---------------------------------------------------------------
/*
Shared properties should be declared as such in the
constructor function of the inheriting class.
The first instance will have the shared property set to
the value in the class definition, if any, otherwise null.
All subsequent instances will also have their shared
property set as a reference to that variable.
*/
private static $shared = array();
public function makeShared($property) {
$class = get_class($this);
if (!property_exists($this,$property))
trigger_error("Access to undeclared property "
. "'$property' in class $class.",E_USER_ERROR);
if (!array_key_exists($class,self::$shared))
self::$shared[$class] = array();
if (!array_key_exists($property,self::$shared[$class]))
self::$shared[$class][$property]
= isset($this->$property)
? $this->$property
: null;
$this->$property =& self::$shared[$class][$property];
}
public function isShared($property) {
$class = get_class($this);
if (!property_exists($this,$property))
trigger_error("Access to undeclared property "
. "'$property' in class $class.",E_USER_ERROR);
return array_key_exists($class,self::$shared)
&& array_key_exists($property, self::$shared[$class]);
}
}
----
Server IP: 208.69.120.35
Probable Submitter: 150.231.246.1
----
Manual Page -- http://www.php.net/manual/en/language.oop5.static.php
Edit -- https://master.php.net/note/edit/92148
Del: integrated -- https://master.php.net/note/delete/92148/integrated
Del: useless -- https://master.php.net/note/delete/92148/useless
Del: bad code -- https://master.php.net/note/delete/92148/bad+code
Del: spam -- https://master.php.net/note/delete/92148/spam
Del: non-english -- https://master.php.net/note/delete/92148/non-english
Del: in docs -- https://master.php.net/note/delete/92148/in+docs
Del: other reasons-- https://master.php.net/note/delete/92148
Reject -- https://master.php.net/note/reject/92148
Search -- https://master.php.net/manage/user-notes.php