Skip to content

Commit

Permalink
Default $bStrictObjectTypeChecking to true
Browse files Browse the repository at this point in the history
BC break!

Passing simple types to the class constructor may lead
to a bunch of unexpected behavior, which can result in crashes
or violate expectations - see the list in the README.

By enabling strict object type checks automatically,
JsonMapper behaves more calculatable.

This is a backwards compatibility break.
The old behavior can be restored by setting the
$bStrictObjectTypeChecking option to `false`.

Resolves: #226
Resolves: #238
  • Loading branch information
cweiske committed Jul 20, 2024
1 parent 30589df commit 155cf24
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 6 deletions.
26 changes: 21 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -477,17 +477,33 @@ setter methods by setting ``$bIgnoreVisibility`` to true:
Simple types instead of objects
===============================
When a variable's type is a class and JSON data is a simple type
like ``string``, JsonMapper passes this value to the class' constructor.

If you do not want this, set ``$bStrictObjectTypeChecking`` to ``true``:
like ``string``, JsonMapper can pass this value to the class' constructor
when configured to do so:

.. code:: php
$jm = new JsonMapper();
$jm->bStrictObjectTypeChecking = true;
$jm->bStrictObjectTypeChecking = false;
$jm->map(...);
An exception is then thrown in such cases.
This can be used to automatically initialize DateTime objects
from date strings.

Disabling this strict object type checks may lead to problems, though:

- When a class does not have a constructor or no constructor parameter,
the value will get lost
- When the constructor has more than 1 required parameter, it will crash.
- When the constructor's parameter type does not match the one of the
data in JSON, it will crash
- ``@required`` properties will not be filled

.. note::
The default value changed from ``false`` to ``true`` in version 5 to
increase security.

Now you have to opt in if you want to pass simple types to
the class constructor.


Passing arrays to ``map()``
Expand Down
2 changes: 1 addition & 1 deletion src/JsonMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class JsonMapper
*
* @var boolean
*/
public $bStrictObjectTypeChecking = false;
public $bStrictObjectTypeChecking = true;

/**
* Throw an exception, if null value is found
Expand Down
3 changes: 3 additions & 0 deletions tests/ArrayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public function testMapTypedArray()
public function testMapTypedSimpleArray()
{
$jm = new JsonMapper();
$jm->bStrictObjectTypeChecking = false;
$jm->bStrictNullTypesInArrays = false;
$sn = $jm->map(
json_decode('{"typedSimpleArray":["2014-01-02",null,"2014-05-07"]}'),
Expand Down Expand Up @@ -510,6 +511,7 @@ public function testMapArrayStrangeKeys()
public function testMapTypedSimpleArrayFromObject()
{
$jm = new JsonMapper();
$jm->bStrictObjectTypeChecking = false;
$sn = $jm->map(
json_decode('{"typedSimpleArray":{"en-US":"2014-01-02"}}'),
new JsonMapperTest_Array()
Expand Down Expand Up @@ -587,6 +589,7 @@ public function testMapArrayFromVariadicFunctionWithSimpleType()
public function testMapArrayFromVariadicFunctionWithObjectType()
{
$jm = new JsonMapper();
$jm->bStrictObjectTypeChecking = false;
/** @var JsonMapperTest_VariadicArray $sn */
$sn = $jm->map(
json_decode('{"variadicDateTime":["2014-01-02","2014-05-07"]}'),
Expand Down
3 changes: 3 additions & 0 deletions tests/ClassMapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public static function classMapTestData()
public function testClassMap($classMapValue)
{
$jm = new JsonMapper();
$jm->bStrictObjectTypeChecking = false;
$jm->classMap[self::CLASS_MAP_CLASS] = $classMapValue;
$sn = $jm->map(
json_decode('{"pPlainObject":"'.self::CLASS_MAP_DATA.'"}'),
Expand All @@ -75,6 +76,7 @@ public function testClassMap($classMapValue)
public function testNamespaceKeyWithLeadingBackslash()
{
$jm = new JsonMapper();
$jm->bStrictObjectTypeChecking = false;
$jm->classMap['\\namespacetest\\model\\User']
= \namespacetest\Unit::class;
$data = $jm->map(
Expand All @@ -88,6 +90,7 @@ public function testNamespaceKeyWithLeadingBackslash()
public function testNamespaceKeyNoLeadingBackslash()
{
$jm = new JsonMapper();
$jm->bStrictObjectTypeChecking = false;
$jm->classMap[\namespacetest\model\User::class]
= \namespacetest\Unit::class;
$data = $jm->map(
Expand Down
1 change: 1 addition & 0 deletions tests/Enums_PHP81_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Enums_PHP81_Test extends \PHPUnit\Framework\TestCase
public function testEnumMapping()
{
$jm = new JsonMapper();
$jm->bStrictObjectTypeChecking = false;
/** @var \Enums\ObjectWithEnum $sn */
$sn = $jm->map(
json_decode(self::TEST_DATA),
Expand Down
2 changes: 2 additions & 0 deletions tests/NamespaceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public function testMapChildClassNamespace()
public function testMapChildClassConstructorNamespace()
{
$mapper = new \JsonMapper();
$mapper->bStrictObjectTypeChecking = false;
$json = '{"user":"John Smith"}';
$res = $mapper->map(json_decode($json), new UnitData());
$this->assertInstanceOf(\namespacetest\UnitData::class, $res);
Expand Down Expand Up @@ -106,6 +107,7 @@ public function testMapCustomArrayObject()
public function testSetterNamespacedTypeHint()
{
$mapper = new \JsonMapper();
$mapper->bStrictObjectTypeChecking = false;
$json = '{"namespacedTypeHint":"Foo"}';
$res = $mapper->map(json_decode($json), new UnitData());
$this->assertInstanceOf(\namespacetest\UnitData::class, $res);
Expand Down
1 change: 1 addition & 0 deletions tests/ObjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public function testMapObjectByClassName()
public function testMapDateTime()
{
$jm = new JsonMapper();
$jm->bStrictObjectTypeChecking = false;
$sn = $jm->map(
json_decode('{"datetime":"2014-04-01T00:00:00+02:00"}'),
new JsonMapperTest_Object()
Expand Down

0 comments on commit 155cf24

Please sign in to comment.