log
log copied to clipboard
Message::parse() not replacing multiple placeholders from context
Description
A message which contains more than one placeholders is not logged correctly, leaving all placeholders in place and only showing the relevant data in the context.
For example:
$logger = new Logger([new StreamTarget()]);
$logger->info('placeholder1: {p1} - placeholder2: {p2}', ['p1' => 'hello', 'p2' => 'world']);
$logger->flush();
// expected:
// 2026-01-14 10:19:04.022900 [info][application] placeholder1: hello - placeholder2: world
//
// Message context:
//
// trace:
// ...
// p1: 'hello'
// p2: 'world'
// actual:
// 2026-01-14 10:19:04.022900 [info][application] placeholder1: {p1} - placeholder2: {p2}
//
// Message context:
//
// trace:
// ...
// p1: 'hello'
// p2: 'world'
I suspect the issue being in Message::parse(), which uses preg_replace_callback with regex '/{(.*)}/' which is eager instead of '/{(.*?)}/', which is instead lazy, causing the match to always be a single one in the format p1} - placeholder2 {p2.
I quickly looked in the tests and there seems not to be one for this exact scenario, maybe it might also be added.
If this bug is confirmed I will happily fork the repo and submit a patch! Thanks everybody for all your work on Yii!
Package version
2.1.1
PHP version
8.3.6