<?php
$name = 'anon';
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 '
';
}
$phpCode = explode(";\necho ", $phpCode);
$phpCode = implode(',', $phpCode);
<?php
$name = 'anon';
echo '
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>','
';
}
<?php
$name = 'anon';
echo '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>
';
}
<?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>
';
}
echo '<h2>';
echo 'Number is: ';
echo count(["1","2","3"]);
echo '</h2>';
$isEchoOpen = false;
if(token === echo) {
if($isEchoOpen) {
$res.= ',';
} else {
$isEchoOpen = true;
$res .= 'echo ';
}
} else {
if($isEchoOpen) {
$isEchoOpen = false;
$res.= ';';
}
}
$phpCode = explode(";\necho ", $phpCode);
$phpCode = implode(',', $phpCode);
<?php
echo '
CHECK
',1 + 3 . '-'. 4 . '=' . 0,'
',count(["1","2","3"]),'
',rand(0,1),'
','<h2>','Olololo','</h2>','
','<h3>','QWErt\'y','</h3>','
','<h2>','Hello, ',$name,'</h2>','
';
foreach ([1,2,3] as $item) {
echo '
','<h2>','Number is: ',$item,'</h2>','
';
}
public function compile($node)
{
if ($node instanceof ForeachBlock) {
$res = "";
if ($node->fallback) {
$res .= "\nif($node->expression) {\n";
}
$res .= "\nforeach ($node->expression as $node->context) {";
$res .= $this->compile($node->body);
$res .= "\n}";
if ($node->fallback) {
$res .= "\n} else {";
$res .= $this->compile($node->fallback);
$res .= "\n}";
}
return $res;
}
if ($node instanceof Text) {
return $this->echo(str_replace('\'', '\\\'', $node->data));
}
if ($node instanceof ExpressionTag) {
return $this->echo($node->expression, inQuotes: false);
}
}
array (
0 =>
(object) array(
'string' => '
CHECK
',
'inQuotes' => true,
),
1 =>
(object) array(
'string' => '1 + 3 . \'-\'. 4 . \'=\' . 0',
'inQuotes' => false,
),
2 =>
(object) array(
'string' => '
',
'inQuotes' => true,
),
3 =>
(object) array(
'string' => '<h2>',
'inQuotes' => true,
),
4 =>
(object) array(
'string' => 'Olololo',
'inQuotes' => true,
),
5 =>
(object) array(
'string' => '</h2>',
'inQuotes' => true,
),
6 =>
(object) array(
'string' => '
',
'inQuotes' => true,
),
7 =>
(object) array(
'string' => '<h2>',
'inQuotes' => true,
),
8 =>
(object) array(
'string' => 'Number is, ',
'inQuotes' => true,
),
9 =>
(object) array(
'string' => 'count()',
'inQuotes' => false,
),
10 =>
(object) array(
'string' => '</h2>',
'inQuotes' => true,
),
11 =>
(object) array(
'string' => '
',
'inQuotes' => true,
),
12 => '
if (rand(0,1)){',
13 =>
(object) array(
'string' => '
lol
',
'inQuotes' => true,
),
14 => '
}',
)
<?php
$data = [
(object)array(
'string' => '
CHECK
',
'inQuotes' => true,
),
(object)array(
'string' => '1 + 3 . \'-\'. 4 . \'=\' . 0',
'inQuotes' => false,
),
(object)array(
'string' => '
',
'inQuotes' => true,
),
(object)array(
'string' => '<h2>',
'inQuotes' => true,
),
(object)array(
'string' => 'Olololo',
'inQuotes' => true,
),
(object)array(
'string' => '</h2>',
'inQuotes' => true,
),
(object)array(
'string' => '
',
'inQuotes' => true,
),
(object)array(
'string' => '<h2>',
'inQuotes' => true,
),
(object)array(
'string' => 'Number is, ',
'inQuotes' => true,
),
(object)array(
'string' => 'count()',
'inQuotes' => false,
),
(object)array(
'string' => '</h2>',
'inQuotes' => true,
),
(object)array(
'string' => '
',
'inQuotes' => true,
),
'
if (rand(0,1)){',
(object)array(
'string' => '
lol
',
'inQuotes' => true,
),
'
}',
];
$printecho = function($d=null){
static $parameters=[];
if(!is_null($d)){
if($d->inQuotes){
$val="'".addcslashes($d->string,'\\\'')."'";
} else {
$val = $d->string;
}
// пытаемся склеить крайние строковые значения
$count=0;
if(count($parameters)>0) {
$x = $parameters[count($parameters) - 1];
$x = preg_replace('~^(.{' . (strlen($x) - 1) . '})\'\'~s', '\1', $x . $val, -1, $count);
}
if($count>0){
$parameters[count($parameters)-1]=$x;
} else {
$parameters[] = $val;
}
} else if(!empty($parameters)){
echo 'echo '.implode(', ',$parameters).';';
$parameters=[];
}
};
foreach($data as $d){
if(is_object($d)){
$printecho($d);
} else {
$printecho();
echo $d;
}
}
$printecho();
echo '
CHECK
', 1 + 3 . '-'. 4 . '=' . 0, '
<h2>Olololo</h2>
<h2>Number is, ', count(), '</h2>
';
if (rand(0,1)){echo '
lol
';
}
$data = [
(object) array(
'string' => '
CHECK
',
'inQuotes' => true,
),
(object) array(
'string' => '1 + 3 . \'-\'. 4 . \'=\' . 0',
'inQuotes' => false,
),
(object) array(
'string' => '
',
'inQuotes' => true,
),
(object) array(
'string' => '<h2>',
'inQuotes' => true,
),
(object) array(
'string' => 'Olololo',
'inQuotes' => true,
),
(object) array(
'string' => '</h2>',
'inQuotes' => true,
),
(object) array(
'string' => '
',
'inQuotes' => true,
),
(object) array(
'string' => '<h2>',
'inQuotes' => true,
),
(object) array(
'string' => 'Number is, ',
'inQuotes' => true,
),
(object) array(
'string' => 'count(["1","2","3"])',
'inQuotes' => false,
),
(object) array(
'string' => '</h2>',
'inQuotes' => true,
),
(object) array(
'string' => '
',
'inQuotes' => true,
),
'
if (rand(0,1)){',
(object) array(
'string' => '
lol
',
'inQuotes' => true,
),
'
}',
];
$res = '';
$openEcho = false;
$inQuotes = false;
foreach ($data as $str) {
if (is_string($str)) {
if ($openEcho) {
if ($inQuotes) {
$res .= "'";
}
$res .= ";";
$openEcho = false;
}
$res .= $str;
continue;
}
if (!$openEcho) {
$openEcho = true;
$inQuotes = $str->inQuotes;
$res .= "\necho ";
if ($str->inQuotes) {
$res .= "'";
}
$res .= $str->string;
} elseif ($str->inQuotes) {
if (!$inQuotes) {
$res .= ",'";
$inQuotes = true;
}
$res .= $str->string;
} elseif (!$str->inQuotes) {
if ($inQuotes) {
$res .= "'";
$inQuotes = false;
}
$res .= ",$str->string";
}
}
echo $res;
echo '
CHECK
',1 + 3 . '-'. 4 . '=' . 0,'
<h2>Olololo</h2>
<h2>Number is, ',count(["1","2","3"]),'</h2>
';
if (rand(0,1)){
echo '
lol
';
}
if ($node instanceof Text) {
$this->php[] = $this->echo(str_replace('\'', '\\\'', $node->data));
}