Why do we have to use it? ? php when we use eval in the contents of a php script?

7

I took a look at the source code of laravel 3 and saw the following code:

eval('?>'.$__contents);

On other occasions, I've seen something like:

$content = file_get_contents('file.php');
eval('?>' . $content . '<?php');

Why do we have to use ?> and <?php when we use the eval function in a content of a PHP script?

Is there any special reason for this?

    
asked by anonymous 12.08.2015 / 16:21

2 answers

7

How eval works:

The eval executes a string as a normal PHP run, for example:

$x = 2;
$y = 3;
$z = eval('return $x + $y;');
eval('echo $z;');

The above example will print 5 on the screen, because on line 3 eval returned the result of the sum of the variables $x and $y and on line 4 the eval printed on the screen with echo . Now we have an idea of how eval works.

Why use '?>' :

$content = file_get_contents('file.php');
eval('?>' . $content . '<?php');

Imagine that the structure of the file.php file starts like this:

<?php
  // faça algum procedimento...

Then when the eval run it will open the PHP tag, which in case is already open by the current code that is running eval, then eval should close it:

$content = file_get_contents('file.php');
eval('?>' . $content);

This execution would be:

$content = file_get_contents('file.php'); // apartir da próxima linha é a execução do 'eval'
?><?php
  // faça algum procedimento...

Even if the file started with text (or HTML), there would be no problem:

$content = file_get_contents('file.php'); // apartir da próxima linha é a execução do 'eval'
?><html>
     <head>
     <!-- restante do código -->

Close or not the tag ?> no eval ?

In the case of closing it is the same thing, but a little more complicated in some cases.

Now imagine that the file file.php ends with

// Termino dos procedimentos
?>

Then in this case you should reopen the tag of PHP so that PHP continues execution, otherwise the lines of code after eval will be printed as text, eg

$content = file_get_contents('file.php');
eval('?>' . $content.'<?php');
$sql = "INSERT INTO users (user, pass) VALUES ('admin', '123456')";

In the above example, if the $content closes the php ?> tag and if it is not reopened, the next lines, like the $sql variable, would be printed on the screen for anyone who wants to see it. This would be a big problem, since PHP allows and even it is advisable not to close the TAG when there is no output in the buffer.

The safest way to avoid this problem is to check all lines of code, and see if there is a last occurrence of the closing tag ?> .

Routine example to check whether the PHP tag is open or closed.

function checkTagPHP($linhas){
   $php = NULL; 
   foreach ($linhas as $linha) {
      $aber = strrpos($linha, '<?php');
      $fech = strrpos($linha, '?>');

      if ($aber > -1 && $fech > -1)
        $php = ($fech < $aber);
      else if ($aber > -1)
        $php = TRUE;
      else if ($fech > -1)
        $php = FALSE;
   }
   return $php;
}
$php = checkTagPHP($arrayDeLinhasDoCodigo);
// Após o loop
// $php == NULL  -> Não existe tag PHP no código
// $php == TRUE  -> Tag PHP aberta
// $php == FALSE -> Tag PHP Fechada

So you can decide whether or not to close the PHP tag:

$content = file_get_contents('file.php');
$execute = '?>' . $content;

if (!checkTagPHP($content)) // Se Tag php estiver fechada
  $execute .= '<?php';

eval($execute);

    
12.08.2015 / 17:56
3

The eval of PHP expects to receive a valid code snippet, but allows switching to "HTML mode". For example, this excerpt, adapted from an example of the manual

eval('echo "In PHP mode!"; ?>In HTML mode!<?php echo "Back in PHP mode!";');

gives the following output:

In PHP mode!In HTML mode!Back in PHP mode!

That is, eval "spits" back content that is in HTML mode, if it is properly informed that it is in that mode.

The snippets that you quoted in the question take this into account, and try to ensure that the content passed to eval as any variable ( $__contents or $content ) is interpreted in HTML mode. That is, this code was made to deal with content of this type:

<h1>HTML Normal</h1>
<h2><?php echo $valorVindoDoBanco ?></h2>
...

Without the precaution of forcing HTML input with ?> , this code would generate a syntax error when executed by eval .

    
12.08.2015 / 16:42