I want to use PHP-Parser library to get the global method (_POST, _GET, _REQUEST
) to get values in PHP. I'm using PHP-Parser where I want to check the node name if it equal to (_POST, _GET, _REQUEST
). I'm still beginner in PHP-Parser and not figure out how to get these global variables. For example, if I have the following source code:
code:
<?php
$firstname = $_POST['firstname];
The PHP-parser I used until now looks like this:
<?php
require_once('vendor/autoload.php');
use PhpParser\Error;
use PhpParser\NodeDumper;
use PhpParser\ParserFactory;
$code = <<<'CODE'
<?php
$firstname= $_POST['firstname'];
CODE;
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
try {
$ast = $parser->parse($code);
} catch (Error $error) {
echo "Parse error: {$error->getMessage()}\n";
return;
}
use PhpParser\{Node, NodeTraverser, NodeVisitorAbstract};
$traverser = new NodeTraverser;
// This code exist in the PHP-Parser documentation
$traverser->addVisitor(new class extends NodeVisitorAbstract {
public function leaveNode(Node $node) {
if ($node instanceof Node\Stmt\Expression
&& $node->expr instanceof Node\Expr\FuncCall
&& $node->expr->name instanceof Node\Name
&& $node->expr->name->toString() === '_POST'
) {
// Change the $_POST['firstname'] and replace it with XXX value
}
}
});
print_r($modifiedStmts = $traverser->traverse($ast) );
after implement the above PHP-Parser AST, I got the following result:
Array ( [0] => PhpParser\Node\Stmt\Expression Object ( [expr] => PhpParser\Node\Expr\Assign Object ( [var] => PhpParser\Node\Expr\Variable Object ( [name] => firstname [attributes:protected] => Array ( [startLine] => 2 [endLine] => 2 ) ) [expr] => PhpParser\Node\Expr\ArrayDimFetch Object ( [var] => PhpParser\Node\Expr\Variable Object ( [name] => _POST [attributes:protected] => Array ( [startLine] => 2 [endLine] => 2 ) ) [dim] => PhpParser\Node\Scalar\String_ Object ( [value] => firstname [attributes:protected] => Array ( [startLine] => 2 [endLine] => 2 [kind] => 1 ) ) [attributes:protected] => Array ( [startLine] => 2 [endLine] => 2 ) ) [attributes:protected] => Array ( [startLine] => 2 [endLine] => 2 ) ) [attributes:protected] => Array ( [startLine] => 2 [endLine] => 2 ) ) )
_POST, _GET, REQUEST
? for example: // Something like this
if($node->value === '_POST' OR $node->value === '_GET' or $node->value === '_REQUEST')
{
// Do next step to change the global variable to specific text value
}
$_POST[firstname]
by hello world! or any text
value ? for example:
Before $firstname = $_POST['firstname'];
After
$firstname = "hello World!";
Thanks for your help
This should work for the particular instance you have highlighted, it only does the POST instance, but that should be easy to expand.
The main part is when you see the AST for the code, try and make sure you can identify the base of the _POST
access. This turns out to be a Node\Expr\ArrayDimFetch
, then inside this you want to check if the variable it is using is _POST
.
Once you have identified this, you can replace that node with a new one which is just a string Node\Scalar\String_("Hello World!");
.
$traverser->addVisitor(new class extends NodeVisitorAbstract {
public function leaveNode(Node $node) {
if ($node instanceof Node\Expr\ArrayDimFetch
&& $node->var instanceof Node\Expr\Variable
&& $node->var->name === '_POST'
) {
// Change the $_POST['firstname'] and replace it with XXX value
return new Node\Scalar\String_("Hello World!");
}
}
});
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
echo $prettyPrinter->prettyPrintFile($traverser->traverse($ast));
From your original code of
<?php
$firstname= $_POST['firstname'];
this code outputs....
<?php
$firstname = 'Hello World!';