skip to Main Content

I need to extract php variables from Blade templates. The issue is that I can’t figure out how to exclude variables created within foreach loops.

{{ $ok }}
{{$alsoOK}}
@foreach($yes as $no)
{{ $no }}
{{ $no->foo }}
@endforeach

So for the above code, I’d like to extract:

$ok
$alsoOK
$yes

but don’t extract $no.

My regex is failing me and I can’t quite tell why.

~[({][s]?($[A-Za-z0-9_]*)[s]?[)}]?~img almost does it, but it also captures the first $no after the foreach loop.

I appreciate the help in advance.

2

Answers


  1. As I already said – regexp is the right tool for the job here. I prefer this approach – it’s simpler and easier to maintain.

    <?php
    $template = <<<EOT
    {{     $ok }}
    {{$alsoOK}}
    @foreach($yes as $no)
    {{ $no }}
    {{ $no->foo }}
    @endforeach
    EOT;
    
    $lines = explode("n", $template);
    
    $variables = [];
    $inForeach = false;
    
    foreach ($lines as $line) {
      if (!$inForeach && preg_match_all('/{{2}s*$([a-zd_]+)s*}{2}/i', $line, $matches)) {
        $variables = array_merge($variables, $matches[1]);
      } elseif (preg_match('/@foreach($([a-zd_]+)s+ass+$([a-zd_]+))/i', $line, $matches)) {
        $inForeach = true;
        $variables[] = $matches[1];
      } elseif (preg_match('/@endforeach/i', $line)) {
        $inForeach = false;
      }
    }
    
    $variables = array_unique($variables);
    
    print_r($variables);
    

    harvests all the variables, but ignores those within @foreach block:

    Array
    (
       [0] => ok
       [1] => alsoOK
       [2] => yes
    )
    
    
    Login or Signup to reply.
  2. I would suggest iterating over each line of the template and only extract the variables of each line.
    This way you could easily skip those lines, that appear within a foreach loop.

    Another advantage of this approach would be writing better readable and maintainable code.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search