Symfony 5 - 如何在 JSON 中操作序列化对象
Posted
技术标签:
【中文标题】Symfony 5 - 如何在 JSON 中操作序列化对象【英文标题】:Symfony 5 - How manipulate a serialized object in JSON 【发布时间】:2021-04-17 06:35:33 【问题描述】:我想序列化一个对象以获取 JSON。当我序列化这个对象时,我得到了这个:
"id": 1,
"title": "Title",
"authors": [
"/api/authors/1",
"/api/authors/2"
]
我想更改 JSON 中的“作者”数据,并将其传递给一个数组。像这个例子:
"id": 1,
"title": "Title",
"authors": [
"id":1,
"name": "Robert Smith",
"booksCount":1
etc etc....
]
这是我的实际代码
$book = $bookRepository->find($id);
$authors = array("authors" => $bookRepository->find($id)->getAuthors());
return $this->json($book, 200, []);
我会用 $authors 中的数组替换“作者”JSON 值。 我怎样才能像我想要的那样操作 JSON 格式?
【问题讨论】:
您目前有任何代码吗? 抱歉,帖子已编辑 【参考方案1】:一种可能性是使用 json_decode 函数。
php 文档:json_decode, json_encode
$json_array = json_decode($json, true); // return array
$json_array['authors'] = $bookRepository->find($id)->getAuthors();
$json = json_encode($json_array); //return json
或@VirtualProperty()来自JMS serializer的注解@
/**
* @Serializer\VirtualProperty()
*/
public function getAuthorsCustom()
return ...;
【讨论】:
【参考方案2】:首先,您在某些路线的路径中保留对作者的引用很奇怪
@Route("/api/authors/authorId")
.
建议:
我会考虑像这样使用 ORM 关系映射:
Book.php
/**
* @ORM\OneToMany(targetEntity="Author", mappedBy="book")
*/
private $authors;
作者.php
/**
* @ORM\ManyToOne(targetEntity="Book", inversedBy="authors")
* @JoinColumn(name="book_id", referencedColumnName="id")
*/
private $book;
然后为您服务:
$book = $entityManager->getRepository(App\Entity\Book::class)->find($id);
return $book;
然后在你的控制器中:
$book = $yourService->getBook($book_id);
return new JSONResponse($book);
然后在 javascript 中:
let bookJSON = JSON.parse(responseData);
let authors = bookJSON.authors;
解决办法:
AuthorRepository.php
/**
* @var $ids int[] array of author identifiers
*/
public function getAuthorsByIds(array $ids)
// it should return array of author entities
return $this->createQueryBuilder('author')
->select('author')
->where("author.id IN (?)")
->setParameter($ids)
->getQuery()
->getResult();
您的控制器
$book = $bookRepository->find($id);
$authorIdentificators = $book->getAuthors();
// convert routes to array of ids
array_walk($authorIdentificators, function(&$route)
$route = explode('/', $route)[3];
);
$authors = $authorRepository->getAuthorsByIds($authorIdentificators);
// notice that your $authors private property is now array of objects (not array of strings(routes))
$book->setAuthors($authors);
return new JSONResponse($book); // now book JSON should have array of authors
你可以使用这个慢循环来代替存储库方法
$authors = $book->getAuthors();
// convert routes to array of entity objects:
array_walk($authors, function(&$route)
$route = $authorRepository->find(explode('/', $route)[3]);
);
【讨论】:
嗨!非常感谢您的帮助。我决定采用第二种解决方案,但我收到此错误“警告:explode() 期望参数 2 是字符串,给定数组”。还有一个问题:为什么在函数中我们给出了两个参数($route 和 $key)但我们只使用了 $route?谢谢! 你$book->getAuthors();
的结果是什么?我希望它是数组或字符串:["/api/authors/1", "/api/authors/2"]。 $route
应该是 $authorIdentificators
数组的每个元素,因此您有一个数组数组,但没有字符串数组。也许 getAuthors() 返回类似这样的内容:['authors' => ["/api/authors/1", "/api/authors/2"]]。我不知道,你告诉我 :) array_walk
的回调可能有 3 个参数,每个参数都是可选的,所以第二个($key)在这里没用(谢谢,我会编辑它)。
我检查了它,然后 $book->getAuthors() 给我发送了一个对象。你建议我怎么做?我转换数组中的对象?
我是这样进行的:我得到了作者,并且通过一个循环,我得到了一个 $authorIdentidicators 的数组,但是,即使在我确认这个变量是一个数组的取消调试之后,我也得到了相同的错误消息“警告:explode() 期望参数 2 是字符串,给定对象”
好吧,但你必须告诉我你的 $authorIdentificators
变量是什么。它必须是一个字符串数组。以上是关于Symfony 5 - 如何在 JSON 中操作序列化对象的主要内容,如果未能解决你的问题,请参考以下文章
最佳实践以及如何在 Symfony2 中找到从 iOS AFNetworking 获取 POST 数据并在 GET 中返回 JSON?