Why does PHP allow you to "declare" $this with Extract?

Asked

Viewed 84 times

2

I was doing some tests (playing) with the function extract and compact PHP. I was seeing how these two functions behaved with the variable $this.

Then I performed the following tests:

I tried to get the value:

var_dump($this); // Notice: Undefined variable 'this'

I tried to assign a value:

$this = 1; // Fatal Error:  Cannot re-assign $this

The above results is the obvious to expect. However when I used the function extract history has changed.

extract(['this' => 1]);

var_dump($this); // int(1)

Already within classes this does not happen.

I wonder if the above behavior with the function extract, unlike direct attribution, it is a common behavior or this is a bug.

The fact that language allows for this "attribution to $this" using extract may cause some problem?

1 answer

0

Why this permission is really something that also intrigued me, is not considered bug, because it does not affect the functioning of language.

I tried to force one anyway bug or strange behavior, but as mentioned in the question, when used in class it is the only place in which a $this can be used, the code of the extract has no effect.

I used the method get_defined_vars() to check if a variable with a name is actually being declared $this and I noticed that you are declaring this variable when the extract is not within a non-static class, when it is within a non-static class it does nothing, because within the method extract there must be some control to it, and when it is in a static class the extract works, but it does not help a $this static class.

The most I could get was to take a copy of the class, when returning it to an external environment (outside the class) it is only possible to change and take public attributes, nor public methods can be called:

index php.:

require_once "TesteClass.php";
$teste = new TesteClass();
$teste->dump();
$retorno = $teste->ext();

echo "Retorno: ";
var_dump($retorno);
echo "<hr/>";
echo $retorno['this']->atributo."<br/>";
$retorno['this']->atributo = "Teste de troca de atributo fora da classe";

echo "Atributo da classe: " . $teste->getAtributo();
echo "<hr/>";

echo "Tentando acessar metodo public fora da classe (pela copia do this): ";
$retorno['this']->mPublico();
echo "<hr/>";

echo "Tentando acessar metodo privado fora da classe (pela copia do this): ";
$retorno['this']->mPrivado();
echo "<hr/>";

Testeclass.php:

<?php
class TesteClass
{
    public $atributo = "valor do meu atributo";

    public function getAtributo()
    {
        return $this->atributo;
    }

    public function dump()
    {
        echo "Minha classe: ";
        var_dump($this);
        echo "<hr/>";
    }

    public function ext()
    {
        extract(["classe" => get_defined_vars($this)]);     
        echo "Get Defined vars na classe: ";
        var_dump(get_defined_vars());
        echo "<hr/>";
        echo "Atributo do Extract : " . $classe['this']->atributo . "<br/>";
        $classe['this']->atributo = "Novo valor do atributo";
        echo "Novo Atributo do Extract : " . $classe['this']->atributo . "<br/>";
        echo "Novo Atributo do THIS : " . $this->atributo . "<br/>";
        echo "<hr/>";
        echo "Metodo privado chamadao da classe pela variavel do Extract : <br/>";
        $classe['this']->mPrivado();
        echo "<hr/>";
        return $classe;
    }

    private function mPrivado()
    {
        echo "Acessou o metodo privado!";
    }

    public function mPublic()
    {
        echo "Acessou o metodo publico!";
    }
}

The test will give a fatal error:

Fatal error: Cannot access private Property Testeclass::$attribute in C: wamp www test.php on line 11

As a conclusion it seems to me that it is more a forgetfulness of the developers than a bug itself, or else they saw that there is no possibility of an error arising from it, because they had already arranged so that when called by a non-static class the method did not create certain variables, and then let it occur.

Browser other questions tagged

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