- Allows to convert POPO (POPO = Plain Old PHP Object) to stdClass
- Why? json_encode() does not handle private properties.
- So you need to have all properties public or use
metassione
.
- and stdClass to POPO
- convert your JSON to PHP objects with type checking and casting, etc
This allows to convert complex object to stdClass, and later JSON (with json_encode()
).
Build object hierarchy
$post = new \Blog\Post();
$post->setTitle('il titolo');
$post->setContents('Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Ut posuere risus eu commodo fermentum. Nullam nec dignissim est.
Curabitur adipiscing massa sit amet velit vehicula aliquam.');
{
$comment_1 = new \Blog\Comment();
$comment_1->setAuthorName("l'autore 1");
$comment_1->setContents("Lorem ipsum");
$comment_2 = new \Blog\Comment();
$comment_2->setAuthorName("l'autore 2");
$comment_2->setContents("dolor sit amet");
$comments = [$comment_1, $comment_2];
$post->setComments($comments);
}
Converting to stdClass:
$metassione = new \NorthslopePL\Metassione\Metassione();
$rawData = $metassione->convertToStdClass($post);
print_r($rawData);
gives:
stdClass Object
(
[title] => il titolo
[contents] => Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Ut posuere risus eu commodo fermentum. Nullam nec dignissim est.
Curabitur adipiscing massa sit amet velit vehicula aliquam.
[comments] => Array
(
[0] => stdClass Object
(
[authorName] => l'autore 1
[contents] => Lorem ipsum
)
[1] => stdClass Object
(
[authorName] => l'autore 2
[contents] => dolor sit amet
)
)
)
Then we can convert that to JSON (JSON_PRETTY_PRINT
= php 5.4+):
$json = json_encode($rawData, JSON_PRETTY_PRINT);
print($json);
which gives:
{
"title": "il titolo",
"contents": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nUt posuere risus eu commodo fermentum. Nullam nec dignissim est.\nCurabitur adipiscing massa sit amet velit vehicula aliquam.",
"comments": [
{
"authorName": "l'autore 1",
"contents": "Lorem ipsum"
},
{
"authorName": "l'autore 2",
"contents": "dolor sit amet"
}
]
}
This allows to convert data from JSON into POPO. Instead of reading data from unspecified objects and arrays - you can use your own classes, type hinting, etc.
With your POPOs:
$comments = $post->getComments();
echo $comments[0]->getAuthor();
echo $comments[0]->getContents();
Compare this to arrays and stdClasses (no type/method hinting):
echo $post->comments[0]->author;
echo $post->comments[0]->contents;
We are using $rawData from example above, to build the same \Blog\Post
object:
$otherPost = new \Blog\Post();
$metassione->fillObjectWithRawData($otherPost, $rawData);
print_r($otherPost);
which gives:
Blog\Post Object
(
[title:Blog\Post:private] => il titolo
[contents:Blog\Post:private] => Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Ut posuere risus eu commodo fermentum. Nullam nec dignissim est.
Curabitur adipiscing massa sit amet velit vehicula aliquam.
[comments:Blog\Post:private] => Array
(
[0] => Blog\Comment Object
(
[authorName:Blog\Comment:private] => l'autore 1
[contents:Blog\Comment:private] => Lorem ipsum
)
[1] => Blog\Comment Object
(
[authorName:Blog\Comment:private] => l'autore 2
[contents:Blog\Comment:private] => dolor sit amet
)
)
)
Which is equal to our starting $post
object.
- METASSIONE
- METAdati e di rifleSSIONE
- metadati e di riflessione
- translate to english: metadata and reflection
To make Metassione work, you need to add typehinting and phpdocs to your classes.
Example:
<?php
namespace NorthslopePL\Metassione\Tests\Examples;
class PropertyWithoutFullClassname
{
/**
* Fully qualified class name - same namespace
*
* @var \NorthslopePL\Metassione\Tests\Examples\ChildKlass
*/
private $firstChild;
/**
* Class from the same namespace as current file.
* This is the same as '\NorthslopePL\Metassione\Tests\Examples\ChildKlass'
*
* @var ChildKlass
*/
private $secondChild;
/**
* Fully qualified class name - other namespace
*
* @var \Other\Lib\ChildKlass
*/
private $thirdChild;
/**
* Not fully qualified class name - from global namespace
* @var SomeClassWithoutNamespace
*/
private $fourthChild;
}
?>
- basic types
int
|integer
string
float
|double
bool
|boolean
- arrays of basic types
int[]
|integer[]
string[]
float[]
|double[]
bool[]
|boolean[]
- classes
FirstClass
OtherClass
\Foo\Bar\AnotherClass
- array of classes (
array
is ignored inarray|Foobar[]
)FirstClass[]
OtherClass[]
\Foo\Bar\AnotherClass[]
Metassione::fillObjectWithRawData($targetObject, stdClass $rawData)
returns$targetObject
- This allows you to write:
$myObject = $metassione->fillObjectWithRawData(new MyKlass(), $rawData);
- without storing
new MyKlass()
in temporary variable
- This allows you to write:
- Class metadata retrieval separated from filling the objects (
CachingClassDefinitionBuilder
)- Added caching class metadata (only in memory)
- Performance: ~20% slower than JsonMapper, where metassione 0.4 was 100+% slower
- Improvement in properties handling
- support for nullable properties (
integer|null
,FooBar|null
) - missing or null value for properties
- property value is set to
zero
value - for non-nullable propertiesinteger
-> 0float
-> 0.0string
-> ''boolean
-> falseSomeKlass
->new SomeKlass()
- any array ->
[]
- property value is set to null for nullable properties
integer
->null
float
->null
string
->null
boolean
->null
SomeKlass
->null
- any array ->
[]
(!!! WARNING: array typed property is always set to empty array, not null. by design)
- property value is set to
- support for nullable properties (
- casting values to proper type
- example: property is of type integer, and
12.95
float is passed. Final object will contain12
as its property value
- example: property is of type integer, and
- recognizing undefined properties - they will be filled with nulls. When type for property is specified in invalid way - it is treated as undefined and always will be filled with null values.
- still no support for importing classes from other namespaces (
use ACME\Foo\Bar
and then/* @var Bar */
)
Metassione 0.6.0 is more strict when processing values for properties.
- If you allow nulls for your properties (
integer|null
) - be warned that metassione will set these values tonull
when there is no valid value for property. - All properties of target class are processed. If no value is found for such property then it will be set to
zero value
ornull
- In 0.4.0 you could set object to integer property - now it is impossible. Property will get value of 0.0 (or null).
Example:
<?php
namespace NorthslopePL\Metassione\Tests\Examples;
class PropertyWithoutFullClassname
{
/**
* @var \NorthslopePL\Metassione\Tests\Examples\ChildKlass
*/
private $firstChild;
/**
* @var ChildKlass
*/
private $secondChild;
/**
* @var \Other\Lib\ChildKlass
*/
private $thirdChild;
}
?>
$firstChild
- has full classname specified. That classname will be used$secondChild
- has juz
ChildKlass
specified. Attempt to loadNorthslopePL\Metassione\Tests\Examples\ChildKlass
will be made. - if
\ChildKlass
is found - it will be used - if not, then
NorthslopePL\Metassione\Tests\Examples\ChildKlass
will be used if found - else exception will be thrown
- has juz
$thirdChild
- has full classname specified. That classname will be used.
This feature will not work with:
- with
use
(use \Foo\Bar; ... @var Bar
) - namespace aliases