3

There's some PHP code assigned to one variable ($phpCode) that may contain a function called runjustthis() or/and any other php code.

I'm looking for a possibility to run just that function runjustthis() with eval().

In other words, how do I extract (with a regex?) the function runjustthis() from the string $phpCode and then call eval() on the extracted string?

Pseudo code:

$phpCode = "
 function runjustthis() {
   // some code here...
 }
 
 // maybe some more code here...
  // Don't execute that: 
  $something = '123'; 
  somethingElse();
";

$runjustthis = extractFunction("runjustthis", $phpCode); 
eval($runjustthis);

2 Answers 2

2

You do not need anything else. as the doc says:

The code will be executed in the scope of the code calling eval(). Thus any variables defined or changed in the eval() call will remain visible after it terminates.

So you just need:

<?php
$phpCode = "
 function runjustthis() {
    return 'Hi';
 }
 
 function runjustthis2(){
     return 'working?';
 }
";

eval($phpCode);
echo runjustthis(). PHP_EOL;
echo runjustthis2();

Output

Hi
working?

But if you insists on getting only the function you want(part of $phpCode), so you can do this:

<?php
$phpCode = "
 function runjustthis() {
    return 'Hi';
 }
 
 function runjustthis2(){
     return 'working?';
 }
";
function extractFunction($functionName, $code){
    $pattern = "/function (?<functionName>$functionName+)\(\)(\s+)?\{[^\}]+\}/m";
    preg_match_all($pattern, $code, $matches);
    return($matches[0][0]);
}

$runjustthis = extractFunction("runjustthis", $phpCode); 
eval($runjustthis);
echo runjustthis();

This would only execute the runjustthis() function not other codes which wrote in $phpCode, so if we try runjustthis2() it will get this error:

PHP Fatal error:  Uncaught Error: Call to undefined function runjustthis2() in your/file/directory/file_name.php
Sign up to request clarification or add additional context in comments.

8 Comments

There might be some code that doesn't reside within a function. And I don't want to execute it, just the function runjustthis()
@smolo I just edit the code, hope to be helpful
There's an issue with your function extractFunction(): Error: There is 1 more closing curly braces '}' found Checked with phpcodechecker.com
@smolo I ran the code in multi IDE and it's working, I think the problem is with the phpcodechecker.com , try this code in IDE and other websites such as w3schools.com/php/phptryit.asp?filename=tryphp_compiler
This will fail immediately as soon as the function contains another closing curly brace which will not be unusual. Generally speaking, the php language grammar is too complex to be able to correctly parse it only using regular expressions.
|
0

The cleanest approach would be to use a PHP parser written in PHP to parse the text, then extract the function from the syntax tree created by the parser and execute it.

One example of a php parser writtein in php is https://github.com/nikic/PHP-Parser


Sample code:

<?php

$phpCode = <<<'CODE'
 <?php
 // Bla Bla
 $else = 'something';
 function donRunThis() {
   echo "Zonk";
 }

 function runjustthis() {
   // some code here...
   echo 42;
 }

 class X {

 }

  // maybe some more code here...
  // Don't execute that: 
  $something = '123'; 
  echo "Zonk";
  somethingElse();

  ?>
CODE;

// Function to extract the code from a function with the given name from the given php code.
function extractFunction($name, $phpCode)
{
    // Create parser and parse php code
    $parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7);
    $ast = $parser->parse($phpCode);

    // Find first function with the given name
    $nodeFinder = new PhpParser\NodeFinder;
    $func = $nodeFinder->findFirst($ast, function(PhpParser\Node $node) use ($name) 
    {
        // Node must be a function
        if($node instanceof PhpParser\Node\Stmt\Function_)
        {
            // and have the correct name
            if($node->name->toString() === $name)
            {
                return true;
            }
        }
        return false;
    });

    // If function was found
    if($func)
    {
        // Use pretty printer to get text representation of the statements in the function
        $prettyPrinter = new PhpParser\PrettyPrinter\Standard;
        $funcCode = $prettyPrinter->prettyPrint($func->stmts);

        return $funcCode;
    }
}


$runjustthis = extractFunction("runjustthis", $phpCode); 
eval($runjustthis);

?>

Try it out at PHP Sandbox:

https://phpsandbox.io/n/super-base-mgkn-nbiyn

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.