Asmir Mustafic
Symfony User Group - Berlin - October 2018
Berlin
My first
jms/serializer?
class User
{
private $name;
private $email;
public function __construct($name, $email)
{
$this->name = $name;
$this->email = $email;
}
}
$user = new User(
'Elvis Presley',
'elvis@rocknroll.com'
);
// or get it from DB
echo $serializer->serialize($user);
{
"name": "Elvis Presley",
"email": "elvis@rocknroll.com"
}
JsonSerializable
class User implements JsonSerializable
{
// ...
public function jsonSerialize()
{
return [
"name" => $this->name,
"email" => $this->email,
];
}
}
echo json_encode($user);
{
"name": "Elvis Presley",
"email": "elvis@rocknroll.com"
}
class User implements JsonSerializable
{
// ...
public function jsonSerialize()
{
if (Auth::getInstance()->isLoggedIn()) {
return [
"name" => $this->name,
"email" => $this->email,
];
} else {
return [
"name" => $this->name,
];
}
}
}
PHP
Serialize:
Deserialize:
opensource
First release 2011
Metadata:
Serialize into:
Deserialize from:
Exclusion strategies:
Customization:
Access strategies:
More:
And More:
Naming:
https://slides.com/goetas/jms-serializer-2017
PHP ^5.5 || ^7.0
Apache-2 License
Serialize:
Deserialize:
opensource
PHP ^5.5 || ^7.0 ^5.5 ^7.2
Apache-2 License MIT
Serialize:
Deserialize:
opensource
Accumulated in 7 years of history
YAML/XML/Annotations
Not just serialization performance!
egeloen/ivory-serializer-benchmark
With small datasets
license
$context = SerializationContext::create();
// v1.x
$context->attributes->set("foo", "bar");
$holder = $context->attributes->get("foo");
if ($holder instanceof Some) {
// get a value
$value = $holder->get();
}
$context = SerializationContext::create();
// v2.0
$context->setAttribute("foo", "bar");
if ($context->hasAttribute("foo")) {
// get a value
$value = $context->getAttribute("foo");
}
class User
{
private $name;
/**
* @MaxDepth(1)
* @var Collection|Song[]
*/
private $songs;
}
{
"name": "Elvis Presley",
"songs": {
{},
{}
}
}
class User
{
private $name;
/**
* @MaxDepth(2)
* @var Collection|Song[]
*/
private $songs;
}
{
"name": "Elvis Presley",
"songs": {
{
"id: 9
"title: "Jailhouse Rock"
},
{
"id: 10
"title: "Love me tender"
}
}
}
class User
{
private $name;
/**
* @MaxDepth(1)
* @var Collection|Song[]
*/
private $songs;
}
{
"name": "Elvis Presley",
"songs": {
{
"id: 9
"title: "Jailhouse Rock"
},
{
"id: 10
"title: "Love me tender"
}
}
}
function ($visitor, $data)
{
// do something
return $result;
}
It's just a callback!
function ($visitor, $data, $type, $context)
{
// do something
return $result;
}
function (
JsonSerializationVisitor $visitor,
User $user
)
{
$data = [
'username' => $user->getUsername()
];
// extra root check
if ($visitor->getRoot() === null) {
$visitor->setRoot($data);
}
return $data;
}
function (
JsonSerializationVisitor $visitor,
User $user
)
{
return [
'username' => $user->getUsername()
];
}
class CustomUserHandler
{
function __construct(Serializer $serializer)
{
$this->serializer = $serializer;
}
function serializeUserToJson(
JsonSerializationVisitor $visitor,
User $user
)
{
return [
'raw' => $this->serializer->serialize($user, 'json')
];
}
}
Most of the classes now are declared
final
https://ocramius.github.io/blog/when-to-declare-classes-final/
JMS\Serializer\Exception\InvalidMetadataException
All metadata errors throw a single exception type
jms_serializer:
visitors:
json_serialization:
options: 0 # json_encode options bitmask
depth: 512
json_deserialization:
options: 0 # json_dencode options bitmask
jms_serializer:
visitors:
xml_serialization:
format_output: false
version: "1.0"
encoding: "UTF-8"
default_root_name: "result"
default_root_ns: null
xml_deserialization:
external_entities: false
doctype_whitelist:
- '<!DOCTYPE authorized ...'
{
"require" : {
"jms/serializer" : "^2.0"
},
"minimum-stability": "RC"
}
{
"require" : {
"jms/serializer-bundle" : "^3.0"
},
"minimum-stability": "RC"
}