Why can’t we destroy [using unset in] a static variable?

Asked

Viewed 1,212 times

1

I was doing some tests with static variables of a class and I came across a Fatal Error.

Behold:

class Stack
{
    public static $overflow = 'english';

    public $user;
}

Stack::$overflow = 'portuguese';

unset(Stack::$overflow);   

The unset generates the following error:

Fatal error: Attempt to unset Static Property Stack::$overflow

Why PHP does not allow you to destroy [using unset in] a static class variable?

3 answers

5


The function unset() is for array elements, variables and object attributes.

It is not possible to exclude a property from a class declared in the scope of the class, regardless of the declaration type or data type.

For static properties is emitted as fatal error because static variables are allocated in spaces stacking values such as reference links.

Ok, we know what arrays and variables are, however, what would be "object attributes"?

Example:

    $a = new stdClass();
    $a->foo = 'test';
    $var_dump($a);
    /*
    object(stdClass)#1 (1) {
      ["foo"]=>
      string(4) "test"
    }
    */

    unset($a->foo);
    var_dump($a);
    /*
    object(stdClass)#1 (0) {
    }
    */

Note that an entire object can also be deleted when assigned as an instance. But this does not mean that the class will be excluded.

$a = new stdClass();
unset($a);

class Bar{}
$a = new Bar();
unset($a);

For properties not declared as static, a fatal error is not issued, as the property, when public, becomes a member of the new instance of the object and not of the original class itself:

class Foo {
public $bar = 'bar';
}

$obj = new Foo;
print_r($obj);
unset($obj->bar); // Aqui excluímos a propriedade
print_r($obj); // Vejamos se realmente foi exluída

$obj = new Foo;
print_r($obj); // Veja o que acontece se, logo em seguida criamos uma nova instância. A propriedade original permanece inalterada -pois trata-se de uma nova instância.

2

Variables declared in class body are estates, Imagine you program a class:

class Cachorro
{
    public $Altura;
    public $Idade;
}

Height and age are properties of all dog-like objects, so any function that receives such an object will assume that these properties exist within the object.

Now imagine with me, another programmer made a function to print the properties of the dog:

function ImprimeCachorro ($CachorroTop)
{
    echo 'Idade:' . $CachorroTop->Idade . ' Altura:' . $CachorroTop->Altura;
}

Now let’s assume that for some reason it receives an object where PHP allowed the Height property to be removed, the dog now lives in another dimension.

Obviously, I would go for the code when it comes to running, but then this other programmer will look at his Dog class and say, "WTF?! You told me the dog had these two properties but when I get paid he only has one of them.".

So removing property from objects would be the same as violating a contract. Whether it is static or not only influences whether the property is unique to each (common) object or whether it is shared between all of them (static).

Languages like Javascript allow you to add and remove various "objects" according to your criteria, but this is only possible because Javascript is NOT object oriented, each "object" in it is actually an associative array where you associate a name to a value.

1

Take a look at the documentation, la fala:

If unset() is used with a static variable within a function, unset() destroys the variable only in the context of the rest of the function. Following calls will restore the variable’s previous value. all references.

<?php
function foo()
{
    static $bar;
    $bar++;
    echo "Before unset: $bar, ";
    unset($bar);
    $bar = 23;
    echo "after unset: $bar\n";
}

foo();
foo();
foo();
?>

The above example will print:

Before unset: 1, after unset: 23
Before unset: 2, after unset: 23
Before unset: 3, after unset: 23

http://php.net/manual/en/function.unset.php

  • But what about the class issue? I’d like to understand why when we use in a class property it generates Fatal Erro!

  • an important note, such execution may enter as deprecated or completely abolished in the future. Currently issues "notice Strict" because it has no explicit statement of the class visibility type and its members (properties and methods)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.