• Как трансформировать код из 1 вида в другой?

    @ksnk
    Отредактировал немного, сейчас работает лучше, но в принципе - наверное лучше в класс перетащить, а то 3 анонимные функции как-то криво начинают выглядеть.
    <?php
    
    $source = <<<'code'
    <?php
    
    $name = 'anon';
    echo '<h2>';
    echo 'Number is: ';
    echo count(["1","2","3"]);
    echo '</h2>';
    echo 'CHECK
    
    ';
    echo 1 + 3 . '-'. 4 . '=' . 0;
    echo '
    
    ';
    echo '<h2>';
    echo 'Olololo';
    echo '</h2>';
    echo '
    
    ';
    echo '<h3>';
    echo 'QWErty';
    echo '</h3>';
    echo '
    
    
    ';
    echo '<h2>';
    echo 'Hello, ';
    echo $name;
    echo '</h2>';
    echo '
    
    ';
    foreach ([1,2,3] as $item) {
    echo '
        ';
    echo '<h2>';
    echo 'Number is: ';
    echo $item;
    echo '</h2>';
    echo '
    ';
    }
    code;
    
    $tokens = token_get_all($source);
    $last_token=false;
    
    $getnext=function() use (&$tokens, &$last_token){
      $token=array_shift($tokens);
      if(is_null($token)) return false;
      if(is_array($token)){
        $last_token= token_name($token[0]);
        return  $token[1];
      } else {
        $last_token='';
          return  $token;
      }
    };
    
    $getbracket=function($bracket) use (&$tokens,$getnext,&$last_token){
    	$stack=[]; $buf=$bracket;
    	
    	if($bracket=='[') array_unshift($stack,']');
    	if($bracket=='(') array_unshift($stack,')');
    	while(false!==($x=$getnext())){
    		$buf.=$x;
    		if($x==$stack[0]){
    			array_shift($stack);
    			if(count($stack)==0) break;
    		}
    		if($x=='(') array_unshift($stack,')');
    		if($x=='{') array_unshift($stack,'}');
    		if($x=='[') array_unshift($stack,']');
    	}
    	return $buf;
    };
    
    $getecho=function() use (&$tokens,$getnext,$getbracket,&$last_token){
      $buf='';
      $buf2='';
      $waitecho=false;
      while(false!==($x=$getnext())){
      	//echo '{'.$last_token.' '.$x.'}';
        if($last_token==='' && $x==';'){
          $waitecho=true;
          $buf2.=$x;
        } elseif($last_token==='T_ECHO' && $waitecho){ // склеиваем
          $waitecho=false;
          $buf.=',';$buf2='';
        } elseif($last_token==='T_WHITESPACE' && $waitecho){ 
          $buf2.=$x;
        } else if($waitecho){
          return $buf.$buf2.$x;
        } else if($last_token==='T_CONSTANT_ENCAPSED_STRING') {// склеиваем константные строки с одинаковыми кавычками
          $s=$x[0];
          $y = preg_replace('~'.preg_quote($s,"~'").'\s*[\.\,]\s*$~', '', $buf, 1, $count);
          if($count>0)
             $buf=$y.substr($x,1);
          else
            $buf.=$x;
        } else if($last_token==='' && in_array($x,['[','('])) {
        	$buf.=$getbracket($x);
        } else {
          $buf.=$x;
        }
      };
      return '';
    };
    
    while(false!==($x=$getnext())) {
      echo $x;
      if($last_token=='T_ECHO'){
        echo $getecho();
      }
    }
    ?>


    <?php
    
    $name = 'anon';
    echo '<h2>Number is: ', count(["1","2","3"]), '</h2>CHECK
    
    ', 1 + 3 . '-'. 4 . '=' . 0, '
    
    <h2>Olololo</h2>
    
    <h3>QWErty</h3>
    
    
    <h2>Hello, ', $name, '</h2>
    
    ';
    foreach ([1,2,3] as $item) {
    echo '
        <h2>Number is: ', $item, '</h2>
    ';
    }
    Ответ написан