0

我在将分页器对象作为 HAL json 集合返回时遇到了一些问题。我正在使用最新版本的 zend-expressive 和 zend-expressive-hal。
这是我的 ConfigProvider 的设置:

public function __invoke() : array
{
    return [
        'dependencies' => $this->getDependencies(),
        MetadataMap::class => $this->getHalConfig(),
    ];
}

public function getHalConfig() : array
{
    return [
        [
            '__class__' => RouteBasedCollectionMetadata::class,
            'collection_class' => RoleCollection::class,
            'collection_relation' => 'user_roles',
            'route' => 'api.user.roles',
        ],
    ];
}

这些是我的处理程序方法:

public function get(ServerRequestInterface $request) : ResponseInterface
{
    // read some records from the database
    $select = new Select();
    $select->from(['r' => 'user_roles']);
    $select->columns(['id', 'name']);

    $paginator = new RoleCollection(new DbSelect($select, $this->dbAdapter));
    $paginator->setItemCountPerPage(25);
    $paginator->setCurrentPageNumber(1);

    return $this->createResponse($request, $paginator);
}

private function createResponse(ServerRequestInterface $request, $instance) : ResponseInterface
{
    return $this->responseFactory->createResponse(
        $request,
        $this->resourceGenerator->fromObject($instance, $request)
    );
}

RoleCollection 类只是 Paginator 的继承:

class RoleCollection extends Paginator
{
}

我得到的错误信息是:

Cannot generate Zend\Expressive\Hal\HalResource for object of type ArrayObject; not in metadata map
4

1 回答 1

0

我认为您缺少 Role 对象本身的元数据。

例如,这与我的帖子对象类似:

MetadataMap::class => [
    [
        '__class__'           => RouteBasedCollectionMetadata::class,
        'collection_class'    => Posts::class,
        'collection_relation' => 'posts',
        'route'               => 'api.posts',
    ],
    [
        '__class__'      => RouteBasedResourceMetadata::class,
        'resource_class' => Post::class,
        'route'          => 'api.posts.view',
        'extractor'      => ArraySerializable::class,
    ],
],

您只描述了集合,并且缺少单个角色的资源类。

我还看到资源生成器尝试解析 ArrayObject。这应该包装在一个 Role 对象中,您可以将其添加到 MetadataMap。

您的代码中出现问题的地方是这一行:

$paginator = new RoleCollection(new DbSelect($select, $this->dbAdapter));

这会将查询的结果添加到分页器中,但分页器不知道如何处理它。如果我没记错的话,DbSelect 返回一个 ResultSet。我猜这就是 ArrayObject 的来源。您可能需要的是覆盖该 ResultSet 并确保它返回一个 Role 对象数组。您可能想查看dbselect 适配器和hydrating结果集

在分页器中拥有 Role 对象后,您可以在元数据中对其进行描述。

[
    '__class__'      => RouteBasedResourceMetadata::class,
    'resource_class' => UserRole::class,
    'route'          => 'api.roles',
    'extractor'      => ...,
],

我自己在 hal 中使用学说,所以 zend-db 超出了我的范围。如果您需要更多帮助,我建议您访问zf 论坛

于 2019-07-09T18:33:48.767 回答