pilotguy
pilotguy

Reputation: 687

Extended classes and static values

I'm trying to understand how PHP manages memory and variables with static methods in extended classes. I've got three classes one entitled Model, User1, User2. Hence:

class Model {
    static public $structure;
    static public $name;
    static function get_structure() {
        return self::$structure = file_get_contents(self::$name.'.json');
    }
}
class User1 extends Model {

}
class User2 extends Model {

}
User1::$name = 'User1';
User2::$name = 'User2';
echo User1::get_structure();
echo User2::get_structure();

If I run User1::get_structure(); for some reason it doesn't populate the result accordingly, it seems to be grabbing the value of User2 (the last $name value declared).

I'm operating on the assumption that declaring User2 and extending Model creates a completely separate scope for my $name property. So User1 and User2 are declared as separate classes with the same structure as Model. Then I can statically define values for them in separate scopes.

I'm now however questioning that. If I extend and call the same $name variable do they both point back to the Model class? Or does it only create a separate scope when I declare each class with new User1(); and new User2();?

Thanks.

Upvotes: 1

Views: 139

Answers (3)

jorjdaniel
jorjdaniel

Reputation: 870

Yes, all classes that extends Model will point back to the same $name variable. Sees static variable as a "global" variable.

Maybe this example will clarify you:

class Model 
{
    static public $name;
}

class User1 extends Model 
{
    public function setName( $name )
    {
        parent::$name = $name;
    }

    public function getName()
    {
        return parent::$name;
    }
}

class User2 extends Model 
{
    public function setName( $name )
    {
        parent::$name = $name;
    }

    public function getName()
    {
        return parent::$name;
    }
}

$user1 = new User1();
$user1->setName("User1");

$user2 = new User2();
$user1->setName("User2");

echo $user1->getName();
echo $user2->getName();

// Output : User2User2

Upvotes: 1

Wrikken
Wrikken

Reputation: 70540

You can work around it with:

<?php
class Model {
    static public $structure;
    static public $name;
    static function get_structure() {
        $class = get_called_class();
        return $class::$structure = file_get_contents($class::$name.'.json');
    }
}
class User1 extends Model {
    static public $structure;
    static public $name;
}
class User2 extends Model {
    static public $structure;
    static public $name;
}
User1::$name = 'User1';
User2::$name = 'User2';
echo User1::get_structure();
echo User2::get_structure();

... but, you might ask yourself the question whether this design is the proper one. atm it for instance looks like they should be instances with separate values & instance methods, but that might be because of the condensed example.

Upvotes: 0

tereško
tereško

Reputation: 58454

You get this behavior, because you are accessing same variable

class X
{
    public static $data = null;
}

class Foo extends X{};
class Bar extends X{};

Foo::$data = 'lorem ipsum';
echo Bar::$data;
// :: output :: lorem ipsum;

Your $name variable stays tied to the Model class, even in inherited classes.

Upvotes: 1

Related Questions