0

The function extractBody() extracts the body part of a function:

$data = '
    <?php 
    function my_function($param){
        if($param === true){
            // This is true
        }else if($param === false){
            // This is false
        }else{
            // This is not
        }
    }
    ?>
';

function extractBody($functionName, $data) {
    $c = preg_match_all("/function\s+".$functionName."\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/", $data, $matches);
    return $c > 0 ? $matches['body'] : null;
}


$body =extractBody("my_function", $data);

var_dump($body);

result: The variable $body contains

 if($param === true){
            // This is true
        }else if($param === false){
            // This is false
        }else{
            // This is not
        }

Now I need a second function to work with lambda functions (function is assigned to a variable)

$data2 = '
    <?php 
    $my_function = function($param){
        if($param === true){
            // This is true
        }else if($param === false){
            // This is false
        }else{
            // This is not
        }
    }
    ?>
';

function extractBody2($functionName, $data) {
    $c = preg_match_all("/".$functionName."\s+=\s+function\s+\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/", $data, $matches);
    return $c > 0 ? $matches['body'] : null;
}


$body2 =extractBody2("my_function", $data2);

var_dump($body2);

Unfortunately, I'm not a regex specialist and I get NULL back. I think the error must be somewhere here: "/".$functionName."\s+=\s+ regex101 didn't reveal any issues though.

smolo
  • 737
  • 1
  • 15
  • 27
  • Why not simply, in both cases, look for the first `{` and the last `}`? Anything in between, as long as it is a normal or lambda function, will be the function body. You don't always need to use a regular expression to solve these things, especially when your input, and output, is only a single function. – KIKO Software Jun 13 '22 at 08:45
  • @KIKOSoftware I don't know why OP needs to do this but this is more complex than it looks. I am sure it isn't as straightforward as just finding the first and the last brace. Usually string literals make it more cumbersome. – nice_dev Jun 13 '22 at 08:48
  • The reason I'm using a regex is because there might be other functions as well and I really just want to get the body back of a specific function. – smolo Jun 13 '22 at 09:07
  • 1
    @nice_dev: With [strpos()](https://www.php.net/manual/en/function.strpos.php) you can find the first `{`, and with [strrpos()](https://www.php.net/manual/en/function.strrpos.php) you find the last `}`. Then all you need to do is get the body with [substr()](https://www.php.net/manual/en/function.substr.php). – KIKO Software Jun 13 '22 at 09:09
  • @KIKOSoftware Ok but there are several assumptions being made like the code is syntatically correct, doesn't use arrow functions or only one function inside a code snippet etc. – nice_dev Jun 13 '22 at 09:18
  • @nice_dev: That's certainly true, but regular expression often also cannot cope with syntax errors. I simply went with what is being asked in the question. – KIKO Software Jun 13 '22 at 09:25
  • @KIKOSoftware Fair enough. Now, OP's comment changes things. – nice_dev Jun 13 '22 at 09:39
  • Syntax errors can be ignored. Example code updated to make it more clear. – smolo Jun 13 '22 at 12:03

1 Answers1

-1

This works for me:

function extractBody2($functionName, $data) {
    $c = preg_match_all("/\\$".$functionName."\s+=\s+function\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/", $data, $matches);
    return $c > 0 ? $matches['body'] : null;
}
smolo
  • 737
  • 1
  • 15
  • 27