1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-08-05 04:37:38 +02:00

Handle __toString to serialize objects which are not json-serializable in JsonFormatter, fixes #1733

This commit is contained in:
Jordi Boggiano
2022-07-22 15:27:46 +02:00
parent 284482a726
commit cf0f4b3814
2 changed files with 74 additions and 5 deletions

View File

@@ -178,12 +178,25 @@ class JsonFormatter extends NormalizerFormatter
return $normalized; return $normalized;
} }
if ($data instanceof \DateTimeInterface) { if (is_object($data)) {
return $this->formatDate($data); if ($data instanceof \DateTimeInterface) {
} return $this->formatDate($data);
}
if ($data instanceof Throwable) { if ($data instanceof Throwable) {
return $this->normalizeException($data, $depth); return $this->normalizeException($data, $depth);
}
// if the object has specific json serializability we want to make sure we skip the __toString treatment below
if ($data instanceof \JsonSerializable) {
return $data;
}
if (method_exists($data, '__toString')) {
return $data->__toString();
}
return $data;
} }
if (is_resource($data)) { if (is_resource($data)) {

View File

@@ -11,6 +11,7 @@
namespace Monolog\Formatter; namespace Monolog\Formatter;
use JsonSerializable;
use Monolog\Logger; use Monolog\Logger;
use Monolog\Test\TestCase; use Monolog\Test\TestCase;
@@ -314,4 +315,59 @@ class JsonFormatterTest extends TestCase
$record $record
); );
} }
public function testFormatObjects()
{
$formatter = new JsonFormatter();
$record = $formatter->format(array(
'level' => 100,
'level_name' => 'DEBUG',
'channel' => 'test',
'message' => 'Testing',
'context' => array(
'public' => new TestJsonNormPublic,
'private' => new TestJsonNormPrivate,
'withToStringAndJson' => new TestJsonNormWithToStringAndJson,
'withToString' => new TestJsonNormWithToString,
),
'extra' => array(),
));
$this->assertSame(
'{"level":100,"level_name":"DEBUG","channel":"test","message":"Testing","context":{"public":{"foo":"fooValue"},"private":{},"withToStringAndJson":["json serialized"],"withToString":"stringified"},"extra":{}}'."\n",
$record
);
}
}
class TestJsonNormPublic
{
public $foo = 'fooValue';
}
class TestJsonNormPrivate
{
private $foo = 'fooValue';
}
class TestJsonNormWithToStringAndJson implements JsonSerializable
{
public function jsonSerialize()
{
return ['json serialized'];
}
public function __toString()
{
return 'SHOULD NOT SHOW UP';
}
}
class TestJsonNormWithToString
{
public function __toString()
{
return 'stringified';
}
} }