<?php
namespace Test;
class Expression
{
private $closure;
public function getClosure()
{
return $this->closure;
}
public function setClosure(\Closure $closure)
{
$this->closure = $closure;
}
public function getReflection()
{
return new \ReflectionFunction($this->getClosure());
}
private function getLines()
{
$reflection = $this->getReflection();
$startLine = $reflection->getStartLine();
$endLine = $reflection->getEndLine();
return array_slice(file($reflection->getFileName()), $startLine - 1, ($endLine - $startLine) + 1);
}
private function getAllTokens(array $lines)
{
$code = sprintf('<?php %s ;', implode($lines));
return array_map(function ($token) {
if (is_array($token))
{
list($id, $value) = $token;
return new Token($id, $value);
}
return new Token(T_SYMBOL, $token);
}, array_filter(token_get_all($code), function ($token) {
if (is_array($token))
{
switch ($token[0])
{
case T_INLINE_HTML:
case T_BAD_CHARACTER:
case T_COMMENT:
case T_WHITESPACE:
return false;
}
}
return true;
}));
}
private function getFilteredTokens(array $tokens)
{
while (!empty($tokens))
{
$token = array_shift($tokens);
if ($token->getId() == T_FUNCTION)
{
$depth = 0;
$filteredTokens = [];
foreach ($tokens as $token)
{
$filteredTokens[] = $token;
if ($token->getId() == T_SYMBOL)
{
switch ($token->getValue())
{
case '{':
$depth += 1;
break;
case '}':
$depth -= 1;
if ($depth == 0)
{
return $filteredTokens;
}
break;
}
}
}
}
}
return [];
}
public function test()
{
$lines = $this->getLines();
$tokens = $this->getAllTokens($lines);
$filteredTokens = $this->getFilteredTokens($tokens);
return $filteredTokens;
}
public function __construct(\Closure $closure)
{
$this->setClosure($closure);
}
}
const T_SYMBOL = 1099;
class Token
{
private $id;
private $value;
public function getId()
{
return $this->id;
}
private function setId($id)
{
$this->id = (int) $id;
}
public function getValue()
{
return $this->value;
}
private function setValue($value)
{
$this->value = (string) $value;
}
public function getName()
{
if ($this->id != 1099)
{
return (string) token_name($this->id);
}
return 'T_SYMBOL';
}
public function __construct($id, $value)
{
$this->setId($id);
$this->setValue($value);
}
public function __toString()
{
return vsprintf('%-30s %s', [
$this->getName(),
$this->getValue(),
]);
}
}
$id = 1;
$password = 'foobar';
$expression = new Expression(function (User $u) use ($id, $password) {
return $u->id == $id && $u->password == $password;
});
foreach ($expression->test() as $token)
{
echo $token . PHP_EOL;
}
var_dump($expression->getReflection()->getStaticVariables());
- Output for git.master, git.master_jit, rfc.property-hooks
- T_SYMBOL (
T_STRING User
T_VARIABLE $u
T_SYMBOL )
T_USE use
T_SYMBOL (
T_VARIABLE $id
T_SYMBOL ,
T_VARIABLE $password
T_SYMBOL )
T_SYMBOL {
T_RETURN return
T_VARIABLE $u
T_OBJECT_OPERATOR ->
T_STRING id
T_IS_EQUAL ==
T_VARIABLE $id
T_BOOLEAN_AND &&
T_VARIABLE $u
T_OBJECT_OPERATOR ->
T_STRING password
T_IS_EQUAL ==
T_VARIABLE $password
T_SYMBOL ;
T_SYMBOL }
array(2) {
["id"]=>
int(1)
["password"]=>
string(6) "foobar"
}
This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.
Active branches
Archived branches
Once feature-branches are merged or declined, they are no longer available. Their functionality (when merged) can be viewed from the main output page
preferences:
53.11 ms | 403 KiB | 8 Q