Skip to content

Instantly share code, notes, and snippets.

@abcarroll
Created June 9, 2019 02:07
Show Gist options
  • Save abcarroll/e5a77a2c663eff62bc8e838a6af4d36c to your computer and use it in GitHub Desktop.
Save abcarroll/e5a77a2c663eff62bc8e838a6af4d36c to your computer and use it in GitHub Desktop.
fun with token parser
<?php
error_reporting(-1);
ini_set('display_errors', true);
$savedValues = [];
$searchForVariableNames = ['$MetaKeys', '$MetaDesc'];
foreach(['test2.php', 'test3.php'] as $filename) {
$srcText = file_get_contents($filename);
$tokens = token_get_all($srcText);
// use this to visualize tokens...
/* foreach($tokens as $token) {
if(is_array($token)) {
echo token_name($token[0]) . "\t" . $token[1] . "\t" . $token[2] . "\n";
} else {
echo ' > ' . $token . "\n";
}
} */
for($x = 0; $x < count($tokens); $x++) {
$token = $tokens[$x];
if(is_array($token)) {
if($token[0] === T_VARIABLE && in_array($token[1], $searchForVariableNames, true)) {
// look ahead
$y = $x;
// if you really want to make it pretty, add all the possible token types here with a separate "no-save" path,
// instead of assuming it will always be followed by T_CONSTANT_ENCAPSED_STRING ... else, this code will error out on eg.
// $MetaDesc = $anotherVar;
while(isset($tokens[$y]) && $tokens[$y][0] !== T_CONSTANT_ENCAPSED_STRING) {
$y++;
// reasonable limit
if($y - $x >= 5) {
throw new \Exception("Can't find value for token: {$token[1]} within a reasonable amount of tokens (started on line {$token[2]})");
}
};
if(!isset($tokens[$y])) {
throw new \Exception("Reached the end of file with no string for token: " . $token[1] . " (started on line " . $token[2] . "). Probably set to a not-a-string.");
}
// now we have the variable-name token in $x and the value in $y
// (probably)
$savedValues[$filename] = $savedValues[$filename] ?? [];
$savedValues[$filename][] = [
$tokens[$x][1] => $tokens[$y][1]
];
}
}
}
}
var_dump($savedValues);
<?php
class foo
{
public $cache_platformprefix = '0';
public $MetaDesc = 'lorem
ipsum $dolor sit
amed';
public $MetaKeys = 'xxx';
public function gobbledyGook()
{
}
}
<?php
declare(strict_types=1);
//
// Taken from league/container composer package as a test
// added the metakeys bit randomly somewhere in the center
//
namespace League\Container;
use League\Container\Definition\{DefinitionAggregate, DefinitionInterface, DefinitionAggregateInterface};
use League\Container\Exception\NotFoundException;
use League\Container\Inflector\{InflectorAggregate, InflectorInterface, InflectorAggregateInterface};
use League\Container\ServiceProvider\{ServiceProviderAggregate, ServiceProviderAggregateInterface};
use Psr\Container\ContainerInterface;
class Container implements ContainerInterface
{
/**
* @var boolean
*/
protected $defaultToShared = false;
/**
* @var \League\Container\Definition\DefinitionAggregateInterface
*/
protected $definitions;
/**
* @var \League\Container\ServiceProvider\ServiceProviderAggregateInterface
*/
protected $providers;
/**
* @var \League\Container\Inflector\InflectorAggregateInterface
*/
protected $inflectors;
/**
* @var \Psr\Container\ContainerInterface[]
*/
protected $delegates = [];
/**
* Construct.
*
* @param \League\Container\Definition\DefinitionAggregateInterface|null $definitions
* @param \League\Container\ServiceProvider\ServiceProviderAggregateInterface|null $providers
* @param \League\Container\Inflector\InflectorAggregateInterface|null $inflectors
*/
public function __construct(
DefinitionAggregateInterface $definitions = null,
ServiceProviderAggregateInterface $providers = null,
InflectorAggregateInterface $inflectors = null
) {
$this->definitions = $definitions ?? (new DefinitionAggregate);
$this->providers = $providers ?? (new ServiceProviderAggregate);
$this->inflectors = $inflectors ?? (new InflectorAggregate);
if ($this->definitions instanceof ContainerAwareInterface) {
$this->definitions->setContainer($this);
}
if ($this->providers instanceof ContainerAwareInterface) {
$this->providers->setContainer($this);
}
if ($this->inflectors instanceof ContainerAwareInterface) {
$this->inflectors->setContainer($this);
}
}
/**
* Add an item to the container.
*
* @param string $id
* @param mixed $concrete
* @param boolean $shared
*
* @return \League\Container\Definition\DefinitionInterface
*/
public function add(string $id, $concrete = null, bool $shared = null) : DefinitionInterface
{
$concrete = $concrete ?? $id;
$shared = $shared ?? $this->defaultToShared;
return $this->definitions->add($id, $concrete, $shared);
}
/**
* Proxy to add with shared as true.
*
* @param string $id
* @param mixed $concrete
*
* @return \League\Container\Definition\DefinitionInterface
*/
public function share(string $id, $concrete = null) : DefinitionInterface
{
return $this->add($id, $concrete, true);
}
/**
* Whether the container should default to defining shared definitions.
*
* @param boolean $shared
*
* @return self
*/
public function defaultToShared(bool $shared = true) : ContainerInterface
{
$this->defaultToShared = $shared;
return $this;
}
/**
* Get a definition to extend.
*
* @param string $id [description]
*
* @return \League\Container\Definition\DefinitionInterface
*/
public function extend(string $id) : DefinitionInterface
{
if ($this->providers->provides($id)) {
$this->providers->register($id);
}
if ($this->definitions->has($id)) {
return $this->definitions->getDefinition($id);
}
throw new NotFoundException(
sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $id)
);
}
/**
* Add a service provider.
*
* @param \League\Container\ServiceProvider\ServiceProviderInterface|string $provider
*
* @return self
*/
public function addServiceProvider($provider) : self
{
$this->providers->add($provider);
return $this;
}
/**
* {@inheritdoc}
*/
public function get($id, bool $new = false)
{
if ($this->definitions->has($id)) {
$resolved = $this->definitions->resolve($id, $new);
return $this->inflectors->inflect($resolved);
}
if ($this->definitions->hasTag($id)) {
$arrayOf = $this->definitions->resolveTagged($id);
array_walk($arrayOf, function (&$resolved) {
$resolved = $this->inflectors->inflect($resolved);
});
return $arrayOf;
}
if ($this->providers->provides($id)) {
$this->providers->register($id);
return $this->get($id, $new);
}
foreach ($this->delegates as $delegate) {
if ($delegate->has($id)) {
$resolved = $delegate->get($id);
return $this->inflectors->inflect($resolved);
}
}
throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id));
}
public $MetaDesc = 'lorem
ipsum \$dolor sit
amed';
/**
* {@inheritdoc}
*/
public function has($id) : bool
{
if ($this->definitions->has($id)) {
return true;
}
if ($this->definitions->hasTag($id)) {
return true;
}
if ($this->providers->provides($id)) {
return true;
}
foreach ($this->delegates as $delegate) {
if ($delegate->has($id)) {
return true;
}
}
return false;
}
/**
* Allows for manipulation of specific types on resolution.
*
* @param string $type
* @param callable|null $callback
*
* @return \League\Container\Inflector\InflectorInterface
*/
public function inflector(string $type, callable $callback = null) : InflectorInterface
{
return $this->inflectors->add($type, $callback);
}
/**
* Delegate a backup container to be checked for services if it
* cannot be resolved via this container.
*
* @param \Psr\Container\ContainerInterface $container
*
* @return self
*/
public function delegate(ContainerInterface $container) : self
{
$this->delegates[] = $container;
if ($container instanceof ContainerAwareInterface) {
$container->setContainer($this);
}
return $this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment