Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
循環参照してるEntityのシリアライズとかの話
Search
Takashi Kanemoto
July 08, 2018
1
770
循環参照してるEntityのシリアライズとかの話
Symfony Meetup #21 LT 資料
https://symfony.connpass.com/event/90319/
Takashi Kanemoto
July 08, 2018
Tweet
Share
More Decks by Takashi Kanemoto
See All by Takashi Kanemoto
いりゃあせ、PHPカンファレンス名古屋2025 / Welcome to PHP Conference Nagoya 2025
ttskch
1
380
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
840
今年書いた技術記事で伸びたやつの自慢と自分の中では力作なのにさっぱり伸びなかったやつの供養 / My Tech Articles 2024
ttskch
2
150
FigmaとPHPで作る1ミリたりとも表示崩れしない最強の帳票印刷ソリューション
ttskch
47
39k
データベース/SQL超入門!完全初心者向けに世界一分かりやすく解説します
ttskch
1
6.4k
Symfony UX Autocompleteとかいう 顧客が本当に必要だったもの
ttskch
0
2.1k
就活生あるいは新人エンジニアさんへのお節介なアドバイス
ttskch
0
1.6k
symfony/pantherでWordleを解いてみた
ttskch
0
360
ついに、Webアプリでの帳票印刷のベストプラクティスを編み出しました💡
ttskch
16
20k
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.5k
RailsConf 2023
tenderlove
30
1.2k
Become a Pro
speakerdeck
PRO
29
5.5k
Designing Experiences People Love
moore
142
24k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Site-Speed That Sticks
csswizardry
10
810
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
1.1k
How GitHub (no longer) Works
holman
315
140k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Done Done
chrislema
185
16k
Transcript
/30 1 ॥ࢀরͯ͠ΔEntityͷ γϦΞϥΠζͱ͔ͷ #symfony_meetup 2018.07.08 @ttskch
ttskchʢ͖ͨͭͪʣ 2 • ໊ݹ͔Βདྷ·ͨ͠ • (ג)ΧϧςοτίϛϡχέʔγϣϯζCTO • PHPྺ6.5ɺSymfonyྺ4ʢROMઐʣ • ͓ख͍ͨ͠ຊʢ2015/12ʣ
/30
͋͞ɺ͋ͳͨࠓ͙͢ϑΥϩʔ͠Α͏!!! શແྉ ͨ ͭ ͖ ͪ twitter.com/ttskch ·͞ʹ໊ݴػ ਓੜͰେͳ͜ͱɺͯ͢ ͖͔ͨͭͪΒڭΘͬͨ
͖ͨͭͪΛϑΥϩʔͨ͠Β ࠊ௧͕࣏Γ·ͨ͠ ͍ͯ͠Δ ͍ͯ͠ͳ͍ ͖ͨͭͪΛϑΥϩʔ͍ͯ͠Δʁ ϑΥϩϫʔ͞Μ100ਓʹฉ͖·ͨ͠ 100% φϯτʂ ϑΥϩϫʔ͔Βͷࢧ࣋ 3/30
• PHPer/JSer ઈࢍେืूதʂʢϑϧϦϞʔτϫʔΫՄʂʣ • ϦεςΟϯάࠂӡ༻πʔϧʮLisketʯΛఏڙ • ࣌ΛઌऔΔϗϫΠτاۀͰ͢ (ג)Χϧςοτίϛϡχέʔγϣϯζ 4 ಛผड
/30
5 (ג)Χϧςοτίϛϡχέʔγϣϯζ ΤϯδχΞͷಇ͖͢͞େࣄʹͯ͠·͢ /30
6 (ג)Χϧςοτίϛϡχέʔγϣϯζ SNSͳͲ͔Β͓ؾܰʹ͝࿈བྷ͍ͩ͘͞✨ /30
/30 7 ॥ࢀরͯ͠ΔEntityͷ γϦΞϥΠζͱ͔ͷ #symfony_meetup 2018.07.08 @ttskch /30
class User { public $name; /** * @var Post[] */
public $posts; } 8 Α͋͘Δ User(1) - Post(N) class Post { public $title; /** * @var User */ public $user; } /30
$serializer = SerializerBuilder::create()->build(); $json = $serializer->serialize($user, 'json'); echo $json; 9
jms/serializerͰUserΛγϦΞϥΠζ /30
{ "name": "user1", "posts": [ { "title": "post1" }, {
"title": "post2" } ] } 10 ݁Ռ posts.user͕ফ͑ڈͬͯΔ /30
class User { public $name; /** * @var Post[] */
public $posts; } 11 user.posts.user = userʢ॥ࢀরʣ class Post { public $title; /** * @var User */ public $user; } /30
ͳΔ΄Ͳ͔֬ʹ 12 • ͩͬͨΒɺMaxDepth(1) ͱ͔͓͚ͬͯ ҆શʹγϦΞϥΠζͰ͖ΔͷͰʁ /30
use JMS\Serializer\Annotation\MaxDepth; class User { public $name; /** * @var
Post[] * * @MaxDepth(1) */ public $posts; } 13 ͬͯΈͨ /30
- $serializer = SerializerBuilder::create()->build(); + $serializer = SerializerBuilder::create() + ->setSerializationContextFactory(function
() { + return SerializationContext::create() + ->enableMaxDepthChecks() + ; + }) + ->build() + ; 14 ͬͯΈͨ MaxDepthͷνΣοΫΛ༗ޮԽ /30
{ "name": "user1", "posts": [ { "title": "post1" }, {
"title": "post2" } ] } 15 ݁Ռ มΘΒͣɻ /30
ΑΖ͍͠, ͳΒ print σόοάͩ 16/30
if ((null === $v && $context->shouldSerializeNull() !== true) || (true
=== $metadata->skipWhenEmpty && ($v instanceof \ArrayObject || \is_array($v)) && 0 === count($v)) ) { return; } 17 JsonSerializationVisitor.php ͜͜Ͱreturnͯͨ͠ʢ͕null͔ͭɺnullγϦΞϥΠζ͠ͳ͍ઃఆʣ /30
$serializer = SerializerBuilder::create() ->setSerializationContextFactory(function () { return SerializationContext::create() ->enableMaxDepthChecks() +
->setSerializeNull(true) ; }) ->build() ; 18 nullγϦΞϥΠζ͢ΔΑ͏ʹઃఆ /30
{ "name": "user1", "posts": [ { "title": "post1", "user": null
}, { "title": "post2", "user": null } ] } 19 ֬ೝ post.user͔֬ʹnullʹͳͬͯΔ /30
͞Βʹ print σόοά 20/30
if ($context->isVisiting($data)) { return null; } 21 GraphNavigator.php ͜͜Ͱnullʹͳͬͯͨ /30
if ($context->isVisiting($data)) { return null; } 22 ࣮ݧɿಉҰΦϒδΣΫτ͡Όͳ͚Ε͍͚Δͷ͔ ϓϩύςΟΛτοϓμϯͰḷΓͭͭɺ๚த ͷΦϒδΣΫτΛελοΫ͓͍ͯͯ͠ɺ৽ͨʹ๚
ͨ͠ΦϒδΣΫτ͕๚தελοΫʹੵ·Ε ͯͨΒ࠶ؼͳͷͰnullʹ͢Δɺͱ͍͏࣮Έ͍ͨ /30
foreach ($user->posts as $post) { $post->user = clone $user; }
$json = $serializer->serialize($user, 'json'); 23 clone $user ͯ͠ஔ͖͑ͯΈΔ /30
{ "name": "user1", "posts": [ { "title": "post1", "user": {
"name": "user1", "posts": [ null, null ] } }, : ] } 24 ݁Ռ ͳΔ΄Ͳߦ͚ͨɻ /30
݁ 25 • jms/serializerͰɺಉҰΦϒδΣΫτ͕࠶ؼ తʹࢀর͞ΕΔΤϯςΟςΟγϦΞϥΠζ Ͱ͖ͳ͍ • MaxDepthͷνΣοΫҎલʹ͔ΕͯΔʢଟʣ /30
͡Ό͋ Ͳ͏͢Εʁ 26/30
APIΛ͚Δ 27 • userͱpostsผʑͷAPI͔Βऔಘ͢Δ • ϑϩϯτͷΠϝʔδ http.get(`/users/${user.id}`) .then(user => http.get(`/users/${user.id}/posts`)
.then(posts => ({user, posts}))) .then(({user, posts}) => { user.posts = posts; this.user = user; }) ; /30
// user-repository.ts get(id: string): Observable<User> { return this.http.get(`/users/${id}`).pipe( map(response =>
getUserFromResponse(response)), switchMap((user: User) => this.postRepository.cgetByUser(user).pipe( map((posts: Post[]) => { user.posts = posts; return user; }) )) ); } 28 Angular (rxjs@6) ͩͱ͜Μͳײ͡ /30
·ͱΊ 29 • jms/serializerͰ॥ࢀর͍ͯ͠ΔΤϯςΟ ςΟγϦΞϥΠζͰ͖ͳ͍ • ͜͏͍͏߹APIΛ͚Δͷ͕Ұൠతʢଟʣ • Qiitaʹࡉ͔͘ॻ͍ͯ·͢ https://bit.ly/2uaINck
/30
Thanks :) 30/30