Skip to content

Commit 700a1e2

Browse files
committed
update 通过手动PDO执行查询方法获取到ColumnMeta来解析字段
这样的做法可能使代码不够美观 但没在Hyperf找到可以使用的地方(除非重写db组件)
1 parent 1a4cd41 commit 700a1e2

File tree

7 files changed

+63
-42
lines changed

7 files changed

+63
-42
lines changed

Diff for: app/ApiJson/Interface/QueryInterface.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public function getPrimaryKey(): string;
1414

1515
public function count($columns = '*'): int;
1616

17-
public function insertGetId(array $values, $sequence = null): int;
17+
public function insert(array $values, $sequence = null): int;
1818

1919
public function update(array $values): bool;
2020

@@ -27,6 +27,4 @@ public function toSql();
2727
public function getBindings();
2828

2929
public function getDb();
30-
31-
public function query();
3230
}

Diff for: app/ApiJson/Model/MysqlQuery.php

+28-19
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44

55
use App\ApiJson\Entity\ConditionEntity;
66
use App\ApiJson\Interface\QueryInterface;
7+
use App\Event\ApiJson\MysqlQueryAfter;
78
use Hyperf\Database\Query\Builder;
89
use Hyperf\DbConnection\Db;
10+
use Hyperf\Utils\ApplicationContext;
11+
use PDO;
12+
use Psr\EventDispatcher\EventDispatcherInterface;
913

1014
class MysqlQuery implements QueryInterface
1115
{
@@ -23,6 +27,11 @@ public function __construct(protected string $tableName, protected ConditionEnti
2327
$this->db = Db::table($tableName);
2428
}
2529

30+
public function getDb(): Builder
31+
{
32+
return $this->db;
33+
}
34+
2635
/**
2736
* @param string $primaryKey
2837
*/
@@ -39,14 +48,20 @@ public function getPrimaryKey(): string
3948
return $this->primaryKey;
4049
}
4150

42-
public function getDb(): Builder
51+
public function all(): array
4352
{
44-
return $this->db;
45-
}
53+
$this->buildQuery();
4654

47-
public function query(): array
48-
{
49-
return $this->db->get()->all();
55+
$pdo = $this->db->getConnection()->getReadPdo(); //为了实现自动解析Json 找不到Hyperf的能提供的能力 则手动拿PDO处理
56+
57+
$statement = $pdo->prepare($this->toSql());
58+
$statement->execute($this->getBindings());
59+
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
60+
61+
$event = new MysqlQueryAfter($result, $statement, $this->toSql(), $this->getBindings()); //这可能并不是很好的写法 待暂无其他思路去实现
62+
ApplicationContext::getContainer()->get(EventDispatcherInterface::class)->dispatch($event);
63+
64+
return $event->result;
5065
}
5166

5267
public function count($columns = '*'): int
@@ -55,7 +70,13 @@ public function count($columns = '*'): int
5570
return $this->db->count();
5671
}
5772

58-
public function insertGetId(array $values, $sequence = null): int
73+
public function toSql(): string
74+
{
75+
$this->buildQuery();
76+
return $this->db->toSql();
77+
}
78+
79+
public function insert(array $values, $sequence = null): int
5980
{
6081
$this->build = true;
6182
return $this->db->insertGetId($values, $sequence);
@@ -75,18 +96,6 @@ public function delete($id = null): bool
7596
return $this->db->delete($id);
7697
}
7798

78-
public function all(): array
79-
{
80-
$this->buildQuery();
81-
return $this->db->get()->all();
82-
}
83-
84-
public function toSql(): string
85-
{
86-
$this->buildQuery();
87-
return $this->db->toSql();
88-
}
89-
9099
public function getBindings(): array
91100
{
92101
return $this->db->getBindings();

Diff for: app/Event/ApiJson/MysqlQueryAfter.php

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace App\Event\ApiJson;
4+
5+
use PDOStatement;
6+
7+
/**
8+
* 查询完毕的处理
9+
*/
10+
class MysqlQueryAfter
11+
{
12+
public function __construct(public array $result, public PDOStatement $statement, protected string $sql, protected array $bindings)
13+
{
14+
}
15+
}

Diff for: app/Listener/QueryResultTryToJsonListener.php

+16-17
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace App\Listener;
55

6-
use App\Event\ApiJson\QueryExecuteAfter;
6+
use App\Event\ApiJson\MysqlQueryAfter;
77
use Hyperf\Event\Annotation\Listener;
88
use Hyperf\Event\Contract\ListenerInterface;
99

@@ -15,29 +15,28 @@ class QueryResultTryToJsonListener implements ListenerInterface
1515
public function listen(): array
1616
{
1717
return [
18-
QueryExecuteAfter::class,
18+
MysqlQueryAfter::class,
1919
];
2020
}
2121

2222
public function process(object $event)
2323
{
24-
if (!$event instanceof QueryExecuteAfter) return;
25-
if ($event->method != 'GET') return;
26-
$event->result = $this->toJson($event->result);
27-
}
28-
29-
private function toJson(array $result): array
30-
{
31-
foreach ($result as $key => $value) {
32-
if (is_array($value)) {
33-
$result[$key] = $this->toJson($value);
24+
if (!$event instanceof MysqlQueryAfter) return;
25+
$columnCount = count(array_keys(current($event->result)));
26+
$columnMeta = [];
27+
for ($i = 0; $i <= $columnCount; $i++) {
28+
$meta = $event->statement->getColumnMeta($i);
29+
if ($meta) {
30+
$columnMeta[$meta['name']] = $meta;
3431
}
35-
if (!is_string($value)) continue;
36-
$jsonData = json_decode($value, true);
37-
if (is_array($jsonData)) {
38-
$result[$key] = $jsonData;
32+
}
33+
34+
foreach(array_filter($columnMeta, function ($item) {
35+
return !isset($item['native_type']) && in_array('blob', $item['flags']);
36+
}, ARRAY_FILTER_USE_BOTH) as $item) {
37+
for ($i = 0; $i < count($event->result); $i++) {
38+
$event->result[$i][$item['name']] = json_decode($event->result[$i][$item['name']], true);
3939
}
4040
}
41-
return $result;
4241
}
4342
}

Diff for: composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"require": {
1515
"php": ">=8.0",
1616
"ext-json": "*",
17+
"ext-pdo": "*",
1718
"hyperf/cache": "~2.2.0",
1819
"hyperf/command": "~2.2.0",
1920
"hyperf/config": "~2.2.0",
@@ -39,7 +40,6 @@
3940
},
4041
"suggest": {
4142
"ext-openssl": "Required to use HTTPS.",
42-
"ext-pdo": "Required to use MySQL Client.",
4343
"ext-pdo_mysql": "Required to use MySQL Client.",
4444
"ext-redis": "Required to use Redis Client."
4545
},

Diff for: config/autoload/databases.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212
return [
1313
'default' => [
14-
'driver' => env('DB_DRIVER', 'mysql'),
14+
'driver' => env('DB_DRIVER', 'pdo'),
1515
'host' => env('DB_HOST', 'localhost'),
1616
'database' => env('DB_DATABASE', 'hyperf'),
1717
'port' => env('DB_PORT', 3306),

Diff for: test/Cases/GetTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ public function testWhereIdSubQuery()
363363
"http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000",
364364
"http://common.cnblogs.com/images/icon_weibo_24.png"
365365
],
366-
"date" =>"2017-02-01 11:21:50"
366+
"date" =>"2017-02-01 19:21:50"
367367
]
368368
], $result);
369369
}

0 commit comments

Comments
 (0)