1

In the first.php file, I assigned some variables and defined some constant values,

define("CONSTANT1", "cons1value");

$variable1 = "var1value";

$variable2 = array(
    "key1" => "value1",
    "key2" => "value2"
);

I need to change values through the second.php file. That changes may like:

define("CONSTANT1", "cons1value_updated");

$variable1 = "var1value_updated";

$variable2 = array(
    "key1" => "value1_updated",
    "key2" => "value2",
    "key_3_added" => "value3_added"
);

I want to do this job using Nikic PhpParser. I tried this code -

$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
$traverser = new PhpParser\NodeTraverser;

$source = file_get_contents("first.php");

try {
    $stmts = $parser->parse($source);
    $stmts = $traverser->traverse($stmts);
} catch (Error $error) {
    echo "Parse error: {$error->getMessage()}\n";
    return;
}

foreach ($stmts as $item) {
    if (property_exists($item, "expr")) {
        $Ex = $item->expr;

        if (property_exists($Ex, "var")) {
            if ($Ex->var->name == 'variable2') {
                foreach ($Ex->expr->items as $fetItem) {
                    switch ($fetItem->key->value) {
                        case 'key1':
                            $fetItem->value->name->parts[0] = "value1_updated";
                            break;

                        case 'key2':
                            $fetItem->value->name->parts[0] = "value2_updated";
                            break;
                    }
                }

                $Ex->expr->items[] = [
                    "key3_added" => "value3_added"
                ];
            }
        }
    }
}

Everything is works fine. But in the section,

$Ex->expr->items[] = [
    "key3_added" => "value3_added"
];

I'm getting an error. Any solution ?

  • _"I'm getting an error"_... what's the error?! We don't have a clue what the object you're working on looks like or contains. Even if you're using a third party library, you need to post all code that's relevant to the issue. Also, what does _"I need to change values through the second.php file"_ mean? Are you loading both files in the same request? If that's the case, it won't work since you can't change the value of an already defined constant. The question is generally unclear. – M. Eriksson Nov 20 '21 at 10:05

1 Answers1

1

Not 100% sure if you are using the same version of the parser, but the problem is that you are adding a simple array element into what is an abstract syntax tree. This should contain a description of the element you want to create rather than the data itself.

With nikic/php-parser 4.10.4, you can use something like...

$Ex->expr->items[] = new ArrayItem(new String_("value 3 added"), new String_("key3_added"));

with the following use statements...

use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Scalar\String_;

As you can see, it's creating an ArrayItem() element with two expressions - both being a simple string containing the value first and then the key.

Nigel Ren
  • 56,122
  • 11
  • 43
  • 55