Às vezes, surgem situações em que a solução para o problema de recuperar dados de um banco de dados relacional não se encaixa nos recursos do ORM usado no projeto, por exemplo, devido à velocidade insuficiente do próprio ORM ou às consultas SQL não muito ideais geradas por ele. Nesse caso, você geralmente precisa escrever consultas manualmente.O problema é que os dados do banco de dados (inclusive em resposta a uma solicitação JOIN) são retornados como uma matriz bidimensional "plana" que não reflete a complexa estrutura em "árvore" dos dados do aplicativo. É extremamente inconveniente trabalhar com essa matriz ainda mais, portanto, é necessária uma solução mais ou menos universal para trazer essa matriz para uma forma mais adequada, de acordo com um determinado padrão.A solução foi encontrada, conveniente e rápido o suficiente.Quão rápido
Para avaliar a velocidade da biblioteca, montei uma pequena bancada de testes na qual a velocidade da minha biblioteca é comparada com a velocidade do Eloquent. Para medições, foi utilizado o pacote phpbench.Para implantar um stand em casa:git clone https://github.com/hrustbb2/env-arrayproc-bench.git
cd env-arrayproc-bench
./env
Aqui eu usei a ferramenta descrita no meu artigo anterior .Em seguida, no menu, selecionamos: 1 Desenvolvimento, depois: 1 Compilação, depois 2 Implementar e Ativar;Em seguida, execute os testes 5. Execute os testesExistem 3000 livros no banco de dados. Os resultados são os seguintes:+-----------------+-----+------+------+-------------+--------------+
| subject | set | revs | iter | mem_peak | time_rev |
+-----------------+-----+------+------+-------------+--------------+
| benchEloquent | 0 | 1 | 0 | 76,442,912b | 12,781.612ms |
| benchEloquentId | 0 | 10 | 0 | 5,123,224b | 16.432ms |
| benchProc | 0 | 1 | 0 | 36,364,176b | 1,053.937ms |
| benchProcId | 0 | 10 | 0 | 4,462,696b | 7.684ms |
+-----------------+-----+------+------+-------------+--------------+
benchEloquent - retira todos os livros com os autores usando EloquentbenchEloquentId - retira um certo livro com os autores usando Eloquent (10 vezes)benchProc - retira todos os livros com os autores usando a bibliotecabenchProcId - retira um determinado livro com os autores usando a biblioteca (10)para atuar os testes não são representativos o suficiente, mas a diferença é perceptível, tanto no tempo de execução quanto no consumo de memória.Como funciona
Instalar:composer require hrustbb2/arrayproc:v1.0.0
Além disso, por exemplo (extremamente simples), imagine que temos um banco de dados de livros e autores com a seguinte estrutura.
A tarefa é retirar todos os livros com seus autores.A solicitação será mais ou menos assim:SELECT
books.id,
books.name,
authors.id,
authors.name
FROM
books
LEFT JOIN relations ON relations.books_id = books.id
LEFT JOIN authors ON authors.id = relations.authors_id
Em resposta, obtemos essa matriz de dados.A matriz é bidimensional, alguns campos são duplicados, por conveniência, você precisa convertê-la[
1 => [
'id' => 1,
'name' => 'book1',
'authors' => [
2 => [
'id' => 2,
'name' => 'author2'
],
4 => [
'id' => 4,
'name' => 'author4'
],
6 => [
'id' => 6,
'name' => 'author6'
],
]
],
2 => [
'id' => 2,
'name' => 'book2',
'authors' => [
2 => [
'id' => 2,
'name' => 'author2'
],
3 => [
'id' => 3,
'name' => 'author3'
],
6 => [
'id' => 6,
'name' => 'author6'
],
7 => [
'id' => 7,
'name' => 'author7'
],
]
],
]
Para fazer isso, modifique levemente nossa solicitação:
SELECT
books.id AS book_id,
books.name AS book_name,
authors.id AS author_id,
authors.name AS author_name
FROM
books
LEFT JOIN relations ON relations.books_id = books.id
LEFT JOIN authors ON authors.id = relations.authors_id
Aqui, definimos alias na seção SELECT: para campos com dados sobre livros, alias com o prefixo 'book_' e para campos com informações sobre autores com o prefixo 'author'.Em seguida, convertemos a resposta do banco de dadosuse hrustbb2\arrayproc\ArrayProcessor;
$arrayProcessor = new ArrayProcessor();
$config = [
'prefix' => 'book_',
'authors' => [
'prefix' => 'author_',
]
]
$booksData = $arrayProcessor->process($conf, $rows)->resultArray();
onde:$ lines é a resposta do banco de dados na forma de uma matriz de objetos / stdClass ()$ config é uma matriz associativa que reflete a estrutura de dados da matriz resultanteComo resultado, em $ booksData, temos uma matriz em forma de árvore com a estrutura descrita em $ config, preenchida com os dados correspondentes.Algo assim.