php - 如何使用 PHP-Parser 获取全局变量名称并更改它

标签 php abstract-syntax-tree php-parser

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

代码:

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

到目前为止,我使用的 PHP 解析器如下所示:
<?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 后,得到以下结果:
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 ?例如:
  • // 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]来自 hello world! or any text值(value) ?例如:
    之前
  • $firstname = $_POST['firstname']; 
    


    $firstname = "hello World!"; 
    
    

    谢谢你的帮助

    最佳答案

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

    主要部分是当您看到代码的 AST 时,请尝试确保您可以识别 _POST 的基础。使用权。结果是 Node\Expr\ArrayDimFetch , 然后在这个里面你要检查它使用的变量是否是 _POST .

    一旦你确定了这一点,你可以用一个新的节点替换这个节点,它只是一个字符串 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 - 如何使用 PHP-Parser 获取全局变量名称并更改它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60468224/

    相关文章:

    php - 根据 2016-2017 安全升级处理 Paypal IPN

    scala - 如何用其他树替换子树?

    ruby - 了解 Ruby 中赋值和逻辑运算符的优先级

    parser-generator - PEG 语法和解析器生成器的局限性?

    PHP 简单 HTML DOM 解析器调用非对象上的成员函数 children()

    php - 存储数据的奇怪字符编码,旧脚本显示它们很好,新脚本却没有

    php - 如何使用密码保护网站上可下载的 pdf 文件

    PHP Swagger 和 Yii

    c++ - Boost Spirit 和抽象语法树设计

    php - 如何比较两个不包括 protected 属性的节点? (PHP-解析器)