user3004118
user3004118

Reputation: 125

Trying to figure out static variables in PHP

I have the following class:

class cls_Tip extends cls_getTips {
    public static $result = null;
    public static $event = null;
    public static $market = null;
    public static $participant = null;

    public function __construct() {

    }

    public static function grab( $id ) {
        global $wpdb;

        $query  = " SELECT * FROM " . $wpdb->prefix . "asp_tips                     WHERE id = '" . $id . "';";
        $result = $wpdb->get_row( $query );
        self::$result = $result;
    }

    public static function add_element_to_parent_array(){
        parent::add_array_ellement( self::$result );
    }

    public static function return_static_variable( $variable_name ) {
        return self::${ $variable_name };
    }

    public static function get_event() {
        new cls_Event;
        cls_Event::grab( self::$result->markets_id );       
        cls_Event::add_static_variable_to_parent();
    }

    public static function get_market() {
        new cls_Market;
        cls_Market::grab( self::$result->markets_id );
        cls_Market::add_static_variable_to_parent();
    }

    public static function get_participant() {
        new cls_Participant;
        cls_Participant::grab( self::$result->participants_id );
        cls_Participant::add_static_variable_to_parent();
    }

    public static function add_static_variable( $variable_name, $class ) {
        self::${ $variable_name } = $class;
    }
}

When I initiate this class as follows:

new cls_Tip;
cls_Tip::get( $record->id );
cls_Tip::get_participant();

$p = cls_Tip::return_static_variable( 'participant' );

... it works, but $p continues to have the same value, after creating another 'new cls_Tip' as outlined above (in a loop.)

Is this because a static variable can only be set once? And what would you recommend doing in this case?

Thanks very much for your advice.

Best regards,

Giorgio

PS: Here is the cls_Participant class:

class cls_Participant extends cls_Tip {
    public static $result = null;

    public function __construct() {

    }

    public static function grab( $id ) {
        global $wpdb;

        $query = " ... ";

        $result = $wpdb->get_row( $query );
        self::$result = $result;
    }

    public static function add_static_variable_to_parent() {
        parent::add_static_variable( 'participant', self::$result );
    }   
}

Upvotes: 1

Views: 145

Answers (1)

rm-vanda
rm-vanda

Reputation: 3158

Well, you see, when you call static properties/methods of a class, unless you explicitly handle the instantiation inside of the function that you call, the "static" instance is a completely separate instance from the instantiated one -

Thus, you should do this:

$class = new cls_Tip;
$class::get( $record->id );
$class::get_participant();

$p = $class::return_static_variable( 'participant' );

And that should give you the behavior you expect...

However, in this case, you don't need to use static methods/properties... you could do:

$class = new cls_Tip;
$class->get( $record->id );
$class->get_participant();

$p = $class->return_static_variable( 'participant' );

Furthermore, this is equivalent, in your last line:

$p = cls_Tip::$participant

You don't need the getter function, since the property is public...

BUT, to further illustrate my answer, do this:

cls_Tip::$result = "Static Result"; 
$alt = new cls_Tip(); 
$alt::$result = "Instantiated Property"; 

echo cls_Tip::$result; 
echo $alt::$result; 

So, ultimately, the lesson here is that if you are going to have several separate instances of a class, you don't really need to label everything as static - There seems to be a lot of discourse on this topic - some people say you should almost never use static methods/properties in PHP, albeit they seem to have a proper place in some cases.

However, it is my personal opinion that you would be better off taking all the static stuff out of your class, which is going to have several instances.

Thus, you would end up using the -> operator instead of the static :: operator.

A case where the :: operator would be more appropriate would be if you wanted to have a static class that managed all your instances might look like this...

class clp_Tip{
    static private $instances; 
//[...]

   public static function new_instance($name){
        return self::$instance[$name] = new $this;
    }
   public static function get_instances(){
        return self::$instances;

    }

  //[...]
}


//[...]
// example: 

    $classOne = cls_Tip::new_instance('name'); 
    $classTwo = cls_Tip::new_instance('two'); 
    echo count(cls_Tip::get_instances()); // 2

    $classOne->doSomeFunction(); 
    $classOne->someProperty = "foo"; 


}

There are plenty of debates over why not use :: - the simplest answer is simply for design purposes, but - it makes good sense to use the operators in the way they were made to be used - and the static operators were made to be used without having to invoke a new instance - So, that is good enough reason, in my opinion, to remove the static stuff from your class and use the -> operator.

Upvotes: 1

Related Questions