Disclaimer: Yes, I am forced to support PHP 4.3.0. I know it's dead. No I can't upgrade it, because I'm dealing with multiple servers some of which I don't have su access.
Well, since I can't use self::
since it's PHP5 specific, how should I go about implementing statics in a PHP4 class? So far from my research it seems that I can at least use the static
keyword except only in a function context, I've seen another method that uses $_GLOBALS but I don't think I'll be using that.
Just so we're on the same page I need to access these PHP5 statics in 4:
public static $_monthTable = array(
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
public static $_yearTable = array(
1970 => 0, 1960 => -315619200);
So far, I've come up with my own function that basically sets a static variable if one isn't found, and I hardcode all my static properties into it. However, I'm not entirely sure how I can reference those statics within anther method in the same class, assuming it isn't being instantiated and no constructor is fired, meaning I can't use $this
.
class DateClass {
function statics( $name = null ) {
static $statics = array();
if ( count( $statics ) == 0 ) {
$statics['months'] = array(
'Jan', 'Feb'
);
}
if ( $name != null && array_key_exists($name, $statics ) ) {
return $statics[$name];
}
}
};
var_dump( DateClass::statics('months') );
Question #1: Is this feasible? Should I try using a different method?
Question #2: How would I reference the statics from a method in the same class? I tried __CLASS__::statics
but I think __CLASS__
is just a string so I'm not really invoking a method.
Note: I'll be implementing this into a framework which will be used on Apache2+/IIS6+, PHP4.3.0 to PHP 5.2, OSX/Linux/Windows.
Answering your first question, I think your solution is good. I would extend it so variables could also be set and unset. I would also "prime" the static $statics differently, the value of unset variables defaults to null
.
<?php
class DateClass {
function statics( $name, $value=null, $unset=null ) {
static $statics;
// better way to "prime" $statics, it's null by default
if ( !$statics ) {
$statics = array( "months" => array( "Jan", "Feb" ) );
}
if ( $value )
$statics[ $name ] = $value;
if ( $unset )
unset( $statics[ $name ] );
// don't worry about checking for existence
// values of unset variables and array keys always are null
// that's what you should return
return $statics[ $name ];
}
}
Regarding your second question, you can use DateClass::statics()
anywhere, even inside other methods (static or not) of DateClass
. PHP4 also allows you to call DateClass::statics()
as instance method even though you shouldn't do that. (It is also possible to call instance methods statically, as long as there is a $this in the outer scope. That's not pretty and you should definitely not do that ;-)
If you really want the call to DateClass
to be more dynamic, you can use call_user_func, it's just a little more verbose.
<?php
class DateClass {
function statics( ... ) { ... }
function anotherStaticFunc() {
var_dump( DateClass::statics( 'months' ) );
// using __CLASS__ and call_user_func
var_dump(
call_user_func( array( __CLASS__, 'statics' ), 'months' )
);
}
function instanceMethod() {
var_dump( $this->statics( 'months' ) );
}
}
It's generally a bad idea to emulate language features. Since PHP 4 doesn't support static properties, I wouldn't recommend that you try something clever to make it appear as-if. I'd say that the most natural thing is to use global variables. Basically, that's what a static property is anyway - It's just namespaced. So use a namespacing-convention, to minimise the risk of nameclashes and you'll essentially have the same thing. Eg. instead of:
class Foo {
static $ninja = 42;
}
You can use
$GLOBALS['foo_ninja'] = 42;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With