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

2

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

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 are the obvious to expect. But when I used the function extract the story changed.

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

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

Inside classes, this does not happen.

I would like to know if the above behavior with the extract function, unlike the direct assignment, is a common behavior or this is a bug.

Does the language allow this "assignment to $this " using extract can cause some problem?

    
asked by anonymous 10.06.2016 / 20:29

1 answer

0

Because this permission is really something that intrigued me too, it is not considered bug , as it does not affect the way the language works.

I tried anyway to force a bug or strange behavior, but as quoted in the question, when used in class which is the only place where a $this can be used, extract does not take effect.

I used the get_defined_vars() method to check if a variable named $this is actually being declared, and I noticed that you are declaring this variable when extract is not inside a non-static class when it is inside a class not static, it does not do anything, because inside the extract method there must be some control for this, and when it is in a static class, extract works, but it does not work at all% static_class.

The maximum I got 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: Can not access private property TestClass :: $ 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, or else they saw that there is no possibility of an error occurring because they had already tried so that when called by a non-static class the method did not create certain variables, and then let that happen.

    
19.06.2016 / 01:39