如何使用PHP解析器获取全局变量名称并进行更改 [英] How to use PHP-Parser to get the global variables name and change it

查看:182
本文介绍了如何使用PHP解析器获取全局变量名称并进行更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 PHP分析器库以获取全局方法( _POST,_GET,_REQUEST )以获取PHP中的值。我正在使用 PHP分析器其中我想检查节点名称是否等于( _POST,_GET,_REQUEST )。我仍然是PHP-Parser的初学者,不知道如何获取这些全局变量。例如,如果我有以下源代码:

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:

代码:

<?php 
$firstname = $_POST['firstname];

我到目前为止使用的PHP解析器如下所示:

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) );

实施上述PHP-Parser 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 ) ) )




  1. 如何检测测试代码是否具有 _POST,_GET,请求?例如:

  1. How to detect if the test code have _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
}




  1. 如何通过 hello world更改 $ _ POST [firstname] !或任何文本的值?例如:

  1. How to change the $_POST[firstname] by hello world! or any text value ? for example: Before



$firstname = $_POST['firstname']; 

之后

$firstname = "hello World!"; 

感谢您的帮助

推荐答案

这应该适用于您突出显示的特定实例,它仅适用于POST实例,但是应该易于扩展。

This should work for the particular instance you have highlighted, it only does the POST instance, but that should be easy to expand.

主要部分是当您看到代码的AST时,请尝试确保您可以确定 _POST 访问权限的基础。原来这是一个 Node\Expr\ArrayDimFetch ,然后在其中要检查其使用的变量是否为 _POST

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.

一旦确定了这一点,就可以用一个只是字符串 Node\的新节点替换该节点Scalar\String _( Hello World!);

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));

根据您的原始代码

<?php
$firstname=  $_POST['firstname'];

此代码输出...。

<?php

$firstname = 'Hello World!';

这篇关于如何使用PHP解析器获取全局变量名称并进行更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆