PHP 8.5.0 Alpha 4 available for testing

Voting

: max(zero, one)?
(Example: nine)

The Note You're Voting On

sebastien at info-conseil dot fr
17 years ago
Here is a small workaround I made for the static inheritance issue. It's not perfect, but it works.

<?php

// BaseClass class will be extended by any class needing static inheritance workaroud
class BaseClass {
// Temporarily stores class name for Entry::getStatic() and Entry::setNextStatic()
protected static $nextStatic = false;

// Returns the real name of the class calling the method, not the one in which it was declared.
protected static function getStatic() {
// If already stored
if (self::$nextStatic) {
// Clean and return
$class = self::$nextStatic;
self::$nextStatic = false;
return
$class;
}

// Init
$backTrace = debug_backtrace();
$class = false;

// Walk through
for ($i=0; $i<count($backTrace); $i++) {
// If a class is defined
if (isset($backTrace[$i]['class'])) {
// Check if it is not a basic class
if (!in_array($backTrace[$i]['class'], array('BaseClass', 'GenericClass'))) {
return
$backTrace[$i]['class'];
} else {
$class = $backTrace[$i]['class'];
}
} else {
// Returns last known class
return $class;
}
}

// Default
return $class;
}

// If a static method is called within global env, the previous method won't work, so we need to tell BaseClass which
public static function setNextStatic($class) {
// Save value
self::$nextStatic = $class;
}
}

// Generic class declaring various static methods
class GenericClass extends BaseClass {
public static
$name = 'Generic';

public function
getName() {
$static = get_class_vars(get_class($this));
return
$static['name'];
}

public static function
basicClassName() {
return
self::$name;
}

public static function
staticClassName() {
// Get real name
$staticName = self::getStatic();

// Return final class name
$static = get_class_vars($staticName);
return
$static['name'];
}
}

// Final class
class SomeClass extends GenericClass {
public static
$name = 'Some';

public static function
returnClassNameWith($string) {
return
$string.' : '.self::staticClassName();
}
}

// Instance call

// Will print 'Some'
$a = new SomeClass();
echo
'Name of $a : '.$a->getName().'<br />';

// Static calls

// Will print 'Generic'
echo 'Basic call to SomeClass::$name : '.SomeClass::basicClassName().'<br />';

// Will print 'Generic'
echo 'Global call to SomeClass::$name : '.SomeClass::staticClassName().'<br />';

// Will print 'Some'
BaseClass::setNextStatic('SomeClass');
echo
'Global call to SomeClass::$name with pre-set : '.SomeClass::staticClassName().'<br />';

// Will print 'Some'
echo 'Internal call to SomeClass::$name : '.SomeClass::returnClassNameWith('This is a ').'<br />';

?>

There are two issues with this workaround :
- if you call a static method from global env, you need to declare the name of the class BEFORE calling the method, otherwise the workaround won't work (see 3rd and 4th examples). But I assume good programming makes few calls to static methods from global scope, so this shouldn't be long to fix if you use it.
- the workaround fails to access to private or protected static vars, as it uses get_class_vars(). If you find any better solution, let us know.

With Php 5.3.0, upgrading will be easy : just delete the methods from the basic class, and search/replace any call to getStatic() and setNextStatic() by static:: - or one could use a selector on PHP_VERSION value to include either the BaseClass file with workaround or a BaseClass file using static::

<< Back to user notes page

To Top