Чтение данных из базы данных и вывод результатов в дерево JSON - PullRequest
0 голосов
/ 27 января 2020

Мне нужна помощь для создания оператора SELECT для рекурсивного получения записей из таблицы и вывода информации в виде Hal Json. Моя база данных MySQL 5.6, и я использую Zend-Expressive 3.

Я уже сделал следующую реализацию:

$select = new Select();
$select->from('_books');
$select->columns([
    'id',
    'refer_to',
    'create_stamp',
]);

Затем я использую HydratingResultSet с paginator:

$resultSet = new HydratingResultSet();
$resultSet->setHydrator(new EntityClassMethodsHydrator());
$resultSet->setObjectPrototype(new BookEntity());

$paginator = new BookCollection(new DbSelect($select, $this->getAdapter(), $resultSet));
$paginator->setItemCountPerPage($pageSize);
$paginator->setCurrentPageNumber($page);

return $this->createHalResponse($request, $paginator);

Метод createHalResponse выглядит следующим образом:

protected function createHalResponse(ServerRequestInterface $request, $instance) : ResponseInterface
{
    try {
        if (is_array($instance)) {
            $halResource = $this->resourceGenerator->fromArray($instance);
        } else {
            $halResource = $this->resourceGenerator->fromObject($instance, $request);
        }

        return $this->responseFactory->createResponse(
            $request,
            $halResource
        );
    } catch (OutOfBoundsException $e) {
        throw MyApiOutOfBoundsException::create($e->getMessage());
    }
}

А это гидратор, коллекция и сущность:

class EntityClassMethodsHydrator extends ClassMethodsHydrator
{
    public function __construct()
    {
        parent::__construct(false, true);
    }
}

class BookCollection extends Paginator
{
}

class BookEntity
{
    private $id;
    private $referTo;
    private $createStamp;

    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        $this->id = $id;
    }

    public function getReferTo()
    {
        return $this->referTo;
    }

    public function setReferTo($referTo)
    {
        $this->referTo = $referTo;
    }

    public function getCreateStamp()
    {
        return $this->createStamp;
    }

    public function setCreateStamp($createStamp)
    {
        $this->createStamp = $createStamp;
    }
}

Ok, я хочу сделать следующее: у меня есть несколько записей в таблице _books. Некоторые из них имеют значение 0 в поле refer_to, что означает, что это главная книга. Остальные имеют ID своих родителей, например,

id;refer_to;create_stamp
1;0;null
2;0;null
3;2;null

Поэтому я должен рекурсивно выбрать информацию и поместить результаты в своего рода древовидную структуру:

{
    "_total_items": 396,
    "_page": 1,
    "_page_count": 40,
    "_embedded": {
        "books": [
            {
                "id": 1,
                "referTo": 0,
                "createStamp": null,
                "_links": {
                    "self": {
                        "href": "https://my.api/rest/books/1"
                    }
                }
            },
            {
                "id": 2,
                "referTo": 0,
                "createStamp": null,
                "_links": {
                    "self": {
                        "href": "https://my.api/rest/books/2"
                    }
                },
                "_embedded": {
                    "books": [
                        {
                            "id": 3,
                            "referTo": 2,
                            "createStamp": null,
                            "_links": {
                                "self": {
                                    "href": "https://my.api/rest/books/3"
                                }
                            }
                        }
                    ]
                }
            }
        ]
    }
}
...