code-abyss 1.6.16 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/bin/install.js +59 -163
- package/bin/lib/ccline.js +82 -0
- package/bin/lib/utils.js +61 -0
- package/package.json +5 -2
- package/skills/SKILL.md +24 -16
- package/skills/domains/ai/SKILL.md +2 -2
- package/skills/domains/ai/prompt-and-eval.md +279 -0
- package/skills/domains/architecture/SKILL.md +2 -3
- package/skills/domains/architecture/security-arch.md +87 -0
- package/skills/domains/data-engineering/SKILL.md +188 -26
- package/skills/domains/development/SKILL.md +1 -4
- package/skills/domains/devops/SKILL.md +3 -5
- package/skills/domains/devops/performance.md +63 -0
- package/skills/domains/devops/testing.md +97 -0
- package/skills/domains/frontend-design/SKILL.md +12 -3
- package/skills/domains/frontend-design/claymorphism/SKILL.md +117 -0
- package/skills/domains/frontend-design/claymorphism/references/tokens.css +52 -0
- package/skills/domains/frontend-design/engineering.md +287 -0
- package/skills/domains/frontend-design/glassmorphism/SKILL.md +138 -0
- package/skills/domains/frontend-design/glassmorphism/references/tokens.css +32 -0
- package/skills/domains/frontend-design/liquid-glass/SKILL.md +135 -0
- package/skills/domains/frontend-design/liquid-glass/references/tokens.css +81 -0
- package/skills/domains/frontend-design/neubrutalism/SKILL.md +141 -0
- package/skills/domains/frontend-design/neubrutalism/references/tokens.css +44 -0
- package/skills/domains/infrastructure/SKILL.md +174 -34
- package/skills/domains/mobile/SKILL.md +211 -21
- package/skills/domains/orchestration/SKILL.md +1 -0
- package/skills/domains/security/SKILL.md +4 -6
- package/skills/domains/security/blue-team.md +57 -0
- package/skills/domains/security/red-team.md +54 -0
- package/skills/domains/security/threat-intel.md +50 -0
- package/skills/orchestration/multi-agent/SKILL.md +195 -46
- package/skills/run_skill.js +139 -0
- package/skills/tools/gen-docs/SKILL.md +6 -4
- package/skills/tools/gen-docs/scripts/doc_generator.js +363 -0
- package/skills/tools/lib/shared.js +98 -0
- package/skills/tools/verify-change/SKILL.md +8 -6
- package/skills/tools/verify-change/scripts/change_analyzer.js +289 -0
- package/skills/tools/verify-module/SKILL.md +6 -4
- package/skills/tools/verify-module/scripts/module_scanner.js +171 -0
- package/skills/tools/verify-quality/SKILL.md +5 -3
- package/skills/tools/verify-quality/scripts/quality_checker.js +337 -0
- package/skills/tools/verify-security/SKILL.md +7 -5
- package/skills/tools/verify-security/scripts/security_scanner.js +283 -0
- package/skills/__pycache__/run_skill.cpython-312.pyc +0 -0
- package/skills/domains/COVERAGE_PLAN.md +0 -232
- package/skills/domains/ai/model-evaluation.md +0 -790
- package/skills/domains/ai/prompt-engineering.md +0 -703
- package/skills/domains/architecture/compliance.md +0 -299
- package/skills/domains/architecture/data-security.md +0 -184
- package/skills/domains/data-engineering/data-pipeline.md +0 -762
- package/skills/domains/data-engineering/data-quality.md +0 -894
- package/skills/domains/data-engineering/stream-processing.md +0 -791
- package/skills/domains/development/dart.md +0 -963
- package/skills/domains/development/kotlin.md +0 -834
- package/skills/domains/development/php.md +0 -659
- package/skills/domains/development/swift.md +0 -755
- package/skills/domains/devops/e2e-testing.md +0 -914
- package/skills/domains/devops/performance-testing.md +0 -734
- package/skills/domains/devops/testing-strategy.md +0 -667
- package/skills/domains/frontend-design/build-tools.md +0 -743
- package/skills/domains/frontend-design/performance.md +0 -734
- package/skills/domains/frontend-design/testing.md +0 -699
- package/skills/domains/infrastructure/gitops.md +0 -735
- package/skills/domains/infrastructure/iac.md +0 -855
- package/skills/domains/infrastructure/kubernetes.md +0 -1018
- package/skills/domains/mobile/android-dev.md +0 -979
- package/skills/domains/mobile/cross-platform.md +0 -795
- package/skills/domains/mobile/ios-dev.md +0 -931
- package/skills/domains/security/secrets-management.md +0 -834
- package/skills/domains/security/supply-chain.md +0 -931
- package/skills/domains/security/threat-modeling.md +0 -828
- package/skills/run_skill.py +0 -153
- package/skills/tests/README.md +0 -225
- package/skills/tests/SUMMARY.md +0 -362
- package/skills/tests/__init__.py +0 -3
- package/skills/tests/__pycache__/test_change_analyzer.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_doc_generator.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_module_scanner.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_quality_checker.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_security_scanner.cpython-312.pyc +0 -0
- package/skills/tests/test_change_analyzer.py +0 -558
- package/skills/tests/test_doc_generator.py +0 -538
- package/skills/tests/test_module_scanner.py +0 -376
- package/skills/tests/test_quality_checker.py +0 -516
- package/skills/tests/test_security_scanner.py +0 -426
- package/skills/tools/gen-docs/scripts/__pycache__/doc_generator.cpython-312.pyc +0 -0
- package/skills/tools/gen-docs/scripts/doc_generator.py +0 -520
- package/skills/tools/verify-change/scripts/__pycache__/change_analyzer.cpython-312.pyc +0 -0
- package/skills/tools/verify-change/scripts/change_analyzer.py +0 -529
- package/skills/tools/verify-module/scripts/__pycache__/module_scanner.cpython-312.pyc +0 -0
- package/skills/tools/verify-module/scripts/module_scanner.py +0 -321
- package/skills/tools/verify-quality/scripts/__pycache__/quality_checker.cpython-312.pyc +0 -0
- package/skills/tools/verify-quality/scripts/quality_checker.py +0 -481
- package/skills/tools/verify-security/scripts/__pycache__/security_scanner.cpython-312.pyc +0 -0
- package/skills/tools/verify-security/scripts/security_scanner.py +0 -374
|
@@ -1,659 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: php
|
|
3
|
-
description: PHP 开发技术。Laravel、Symfony、Composer、PSR 标准、Eloquent ORM、Blade 模板。当用户提到 PHP、Laravel、Symfony、Composer、PSR、Eloquent、Blade、Artisan 时使用。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# 🐘 PHP 开发 · PHP Development
|
|
7
|
-
|
|
8
|
-
## 生态架构
|
|
9
|
-
|
|
10
|
-
```
|
|
11
|
-
Laravel/Symfony
|
|
12
|
-
│
|
|
13
|
-
┌─────────┼─────────┐
|
|
14
|
-
│ │ │
|
|
15
|
-
Eloquent Blade Artisan
|
|
16
|
-
│ │ │
|
|
17
|
-
└─────────┼─────────┘
|
|
18
|
-
│
|
|
19
|
-
Composer (PSR)
|
|
20
|
-
│
|
|
21
|
-
┌─────────┼─────────┐
|
|
22
|
-
Cache Queue Session
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Laravel 核心
|
|
26
|
-
|
|
27
|
-
### 路由与控制器
|
|
28
|
-
```php
|
|
29
|
-
// routes/web.php
|
|
30
|
-
use App\Http\Controllers\UserController;
|
|
31
|
-
|
|
32
|
-
Route::get('/users', [UserController::class, 'index']);
|
|
33
|
-
Route::post('/users', [UserController::class, 'store']);
|
|
34
|
-
Route::get('/users/{id}', [UserController::class, 'show']);
|
|
35
|
-
|
|
36
|
-
// 路由组
|
|
37
|
-
Route::middleware(['auth'])->group(function () {
|
|
38
|
-
Route::prefix('admin')->group(function () {
|
|
39
|
-
Route::get('/dashboard', [AdminController::class, 'index']);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// API 路由
|
|
44
|
-
Route::apiResource('posts', PostController::class);
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Eloquent ORM
|
|
48
|
-
```php
|
|
49
|
-
// 模型定义
|
|
50
|
-
namespace App\Models;
|
|
51
|
-
|
|
52
|
-
use Illuminate\Database\Eloquent\Model;
|
|
53
|
-
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
54
|
-
|
|
55
|
-
class User extends Model
|
|
56
|
-
{
|
|
57
|
-
protected $fillable = ['name', 'email', 'password'];
|
|
58
|
-
protected $hidden = ['password', 'remember_token'];
|
|
59
|
-
protected $casts = [
|
|
60
|
-
'email_verified_at' => 'datetime',
|
|
61
|
-
'is_admin' => 'boolean',
|
|
62
|
-
];
|
|
63
|
-
|
|
64
|
-
public function posts(): HasMany
|
|
65
|
-
{
|
|
66
|
-
return $this->hasMany(Post::class);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// 查询构建器
|
|
71
|
-
$users = User::where('active', true)
|
|
72
|
-
->whereHas('posts', function ($query) {
|
|
73
|
-
$query->where('published', true);
|
|
74
|
-
})
|
|
75
|
-
->with('posts')
|
|
76
|
-
->orderBy('created_at', 'desc')
|
|
77
|
-
->paginate(15);
|
|
78
|
-
|
|
79
|
-
// 批量操作
|
|
80
|
-
User::where('last_login', '<', now()->subYear())
|
|
81
|
-
->chunk(100, function ($users) {
|
|
82
|
-
foreach ($users as $user) {
|
|
83
|
-
$user->delete();
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### 依赖注入与服务容器
|
|
89
|
-
```php
|
|
90
|
-
// 服务提供者
|
|
91
|
-
namespace App\Providers;
|
|
92
|
-
|
|
93
|
-
use Illuminate\Support\ServiceProvider;
|
|
94
|
-
|
|
95
|
-
class PaymentServiceProvider extends ServiceProvider
|
|
96
|
-
{
|
|
97
|
-
public function register()
|
|
98
|
-
{
|
|
99
|
-
$this->app->singleton(PaymentGateway::class, function ($app) {
|
|
100
|
-
return new StripeGateway(config('services.stripe.key'));
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// 控制器注入
|
|
106
|
-
class OrderController extends Controller
|
|
107
|
-
{
|
|
108
|
-
public function __construct(
|
|
109
|
-
private PaymentGateway $payment,
|
|
110
|
-
private OrderRepository $orders
|
|
111
|
-
) {}
|
|
112
|
-
|
|
113
|
-
public function store(Request $request)
|
|
114
|
-
{
|
|
115
|
-
$order = $this->orders->create($request->validated());
|
|
116
|
-
$this->payment->charge($order->total);
|
|
117
|
-
return response()->json($order, 201);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Blade 模板
|
|
123
|
-
```php
|
|
124
|
-
{{-- layouts/app.blade.php --}}
|
|
125
|
-
<!DOCTYPE html>
|
|
126
|
-
<html>
|
|
127
|
-
<head>
|
|
128
|
-
<title>@yield('title')</title>
|
|
129
|
-
</head>
|
|
130
|
-
<body>
|
|
131
|
-
@include('partials.header')
|
|
132
|
-
|
|
133
|
-
<main>
|
|
134
|
-
@yield('content')
|
|
135
|
-
</main>
|
|
136
|
-
|
|
137
|
-
@stack('scripts')
|
|
138
|
-
</body>
|
|
139
|
-
</html>
|
|
140
|
-
|
|
141
|
-
{{-- users/index.blade.php --}}
|
|
142
|
-
@extends('layouts.app')
|
|
143
|
-
|
|
144
|
-
@section('title', 'Users')
|
|
145
|
-
|
|
146
|
-
@section('content')
|
|
147
|
-
@forelse($users as $user)
|
|
148
|
-
<div class="user">
|
|
149
|
-
<h3>{{ $user->name }}</h3>
|
|
150
|
-
@if($user->is_admin)
|
|
151
|
-
<span class="badge">Admin</span>
|
|
152
|
-
@endif
|
|
153
|
-
</div>
|
|
154
|
-
@empty
|
|
155
|
-
<p>No users found.</p>
|
|
156
|
-
@endforelse
|
|
157
|
-
|
|
158
|
-
{{ $users->links() }}
|
|
159
|
-
@endsection
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### 中间件
|
|
163
|
-
```php
|
|
164
|
-
namespace App\Http\Middleware;
|
|
165
|
-
|
|
166
|
-
use Closure;
|
|
167
|
-
use Illuminate\Http\Request;
|
|
168
|
-
|
|
169
|
-
class CheckApiToken
|
|
170
|
-
{
|
|
171
|
-
public function handle(Request $request, Closure $next)
|
|
172
|
-
{
|
|
173
|
-
$token = $request->header('X-API-Token');
|
|
174
|
-
|
|
175
|
-
if (!$this->isValidToken($token)) {
|
|
176
|
-
return response()->json(['error' => 'Unauthorized'], 401);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return $next($request);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// 注册中间件
|
|
184
|
-
protected $routeMiddleware = [
|
|
185
|
-
'api.token' => \App\Http\Middleware\CheckApiToken::class,
|
|
186
|
-
];
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### 队列与任务
|
|
190
|
-
```php
|
|
191
|
-
// 任务定义
|
|
192
|
-
namespace App\Jobs;
|
|
193
|
-
|
|
194
|
-
use Illuminate\Bus\Queueable;
|
|
195
|
-
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
196
|
-
|
|
197
|
-
class ProcessVideoUpload implements ShouldQueue
|
|
198
|
-
{
|
|
199
|
-
use Queueable;
|
|
200
|
-
|
|
201
|
-
public $tries = 3;
|
|
202
|
-
public $timeout = 120;
|
|
203
|
-
|
|
204
|
-
public function __construct(
|
|
205
|
-
private Video $video
|
|
206
|
-
) {}
|
|
207
|
-
|
|
208
|
-
public function handle()
|
|
209
|
-
{
|
|
210
|
-
// 转码逻辑
|
|
211
|
-
$this->video->transcode();
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
public function failed(\Throwable $exception)
|
|
215
|
-
{
|
|
216
|
-
// 失败处理
|
|
217
|
-
$this->video->markAsFailed();
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// 分发任务
|
|
222
|
-
ProcessVideoUpload::dispatch($video)
|
|
223
|
-
->onQueue('videos')
|
|
224
|
-
->delay(now()->addMinutes(5));
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Artisan 命令
|
|
228
|
-
```php
|
|
229
|
-
namespace App\Console\Commands;
|
|
230
|
-
|
|
231
|
-
use Illuminate\Console\Command;
|
|
232
|
-
|
|
233
|
-
class CleanupOldLogs extends Command
|
|
234
|
-
{
|
|
235
|
-
protected $signature = 'logs:cleanup {--days=30}';
|
|
236
|
-
protected $description = 'Clean up old log files';
|
|
237
|
-
|
|
238
|
-
public function handle()
|
|
239
|
-
{
|
|
240
|
-
$days = $this->option('days');
|
|
241
|
-
$this->info("Cleaning logs older than {$days} days...");
|
|
242
|
-
|
|
243
|
-
$deleted = Log::where('created_at', '<', now()->subDays($days))
|
|
244
|
-
->delete();
|
|
245
|
-
|
|
246
|
-
$this->info("Deleted {$deleted} log entries.");
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
## Symfony 组件
|
|
252
|
-
|
|
253
|
-
### HTTP 基础
|
|
254
|
-
```php
|
|
255
|
-
use Symfony\Component\HttpFoundation\Request;
|
|
256
|
-
use Symfony\Component\HttpFoundation\Response;
|
|
257
|
-
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
258
|
-
|
|
259
|
-
// 请求处理
|
|
260
|
-
$request = Request::createFromGlobals();
|
|
261
|
-
$name = $request->query->get('name');
|
|
262
|
-
$data = $request->request->all();
|
|
263
|
-
$file = $request->files->get('upload');
|
|
264
|
-
|
|
265
|
-
// 响应
|
|
266
|
-
$response = new Response('Hello World', 200, [
|
|
267
|
-
'Content-Type' => 'text/plain'
|
|
268
|
-
]);
|
|
269
|
-
|
|
270
|
-
$json = new JsonResponse(['status' => 'success']);
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
### 依赖注入容器
|
|
274
|
-
```php
|
|
275
|
-
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
276
|
-
use Symfony\Component\DependencyInjection\Reference;
|
|
277
|
-
|
|
278
|
-
$container = new ContainerBuilder();
|
|
279
|
-
|
|
280
|
-
$container->register('mailer', Mailer::class)
|
|
281
|
-
->addArgument(new Reference('transport'));
|
|
282
|
-
|
|
283
|
-
$container->register('transport', SmtpTransport::class)
|
|
284
|
-
->addArgument('%smtp.host%')
|
|
285
|
-
->addArgument('%smtp.port%');
|
|
286
|
-
|
|
287
|
-
$mailer = $container->get('mailer');
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### 事件调度器
|
|
291
|
-
```php
|
|
292
|
-
use Symfony\Component\EventDispatcher\EventDispatcher;
|
|
293
|
-
|
|
294
|
-
class OrderPlacedEvent
|
|
295
|
-
{
|
|
296
|
-
public function __construct(
|
|
297
|
-
public Order $order
|
|
298
|
-
) {}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
$dispatcher = new EventDispatcher();
|
|
302
|
-
|
|
303
|
-
$dispatcher->addListener('order.placed', function (OrderPlacedEvent $event) {
|
|
304
|
-
// 发送邮件
|
|
305
|
-
$mailer->send($event->order->user->email);
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
$dispatcher->dispatch(new OrderPlacedEvent($order), 'order.placed');
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
## Composer 依赖管理
|
|
312
|
-
|
|
313
|
-
### composer.json 配置
|
|
314
|
-
```json
|
|
315
|
-
{
|
|
316
|
-
"name": "vendor/project",
|
|
317
|
-
"type": "project",
|
|
318
|
-
"require": {
|
|
319
|
-
"php": "^8.2",
|
|
320
|
-
"laravel/framework": "^10.0",
|
|
321
|
-
"guzzlehttp/guzzle": "^7.5"
|
|
322
|
-
},
|
|
323
|
-
"require-dev": {
|
|
324
|
-
"phpunit/phpunit": "^10.0",
|
|
325
|
-
"laravel/pint": "^1.0"
|
|
326
|
-
},
|
|
327
|
-
"autoload": {
|
|
328
|
-
"psr-4": {
|
|
329
|
-
"App\\": "app/",
|
|
330
|
-
"Database\\": "database/"
|
|
331
|
-
},
|
|
332
|
-
"files": [
|
|
333
|
-
"app/helpers.php"
|
|
334
|
-
]
|
|
335
|
-
},
|
|
336
|
-
"scripts": {
|
|
337
|
-
"test": "phpunit",
|
|
338
|
-
"format": "pint"
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### 常用命令
|
|
344
|
-
```bash
|
|
345
|
-
# 安装依赖
|
|
346
|
-
composer install
|
|
347
|
-
composer install --no-dev
|
|
348
|
-
|
|
349
|
-
# 更新依赖
|
|
350
|
-
composer update
|
|
351
|
-
composer update vendor/package
|
|
352
|
-
|
|
353
|
-
# 添加包
|
|
354
|
-
composer require guzzlehttp/guzzle
|
|
355
|
-
composer require --dev phpunit/phpunit
|
|
356
|
-
|
|
357
|
-
# 自动加载优化
|
|
358
|
-
composer dump-autoload -o
|
|
359
|
-
|
|
360
|
-
# 查看过期包
|
|
361
|
-
composer outdated
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
## PSR 标准
|
|
365
|
-
|
|
366
|
-
### PSR-4 自动加载
|
|
367
|
-
```php
|
|
368
|
-
// composer.json
|
|
369
|
-
{
|
|
370
|
-
"autoload": {
|
|
371
|
-
"psr-4": {
|
|
372
|
-
"App\\": "src/",
|
|
373
|
-
"App\\Tests\\": "tests/"
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// 目录结构
|
|
379
|
-
src/
|
|
380
|
-
├── Controllers/
|
|
381
|
-
│ └── UserController.php // App\Controllers\UserController
|
|
382
|
-
├── Models/
|
|
383
|
-
│ └── User.php // App\Models\User
|
|
384
|
-
└── Services/
|
|
385
|
-
└── PaymentService.php // App\Services\PaymentService
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### PSR-12 代码风格
|
|
389
|
-
```php
|
|
390
|
-
<?php
|
|
391
|
-
|
|
392
|
-
declare(strict_types=1);
|
|
393
|
-
|
|
394
|
-
namespace App\Services;
|
|
395
|
-
|
|
396
|
-
use App\Models\User;
|
|
397
|
-
use Illuminate\Support\Facades\Hash;
|
|
398
|
-
|
|
399
|
-
class UserService
|
|
400
|
-
{
|
|
401
|
-
public function __construct(
|
|
402
|
-
private UserRepository $repository,
|
|
403
|
-
private Mailer $mailer
|
|
404
|
-
) {
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
public function createUser(array $data): User
|
|
408
|
-
{
|
|
409
|
-
$user = $this->repository->create([
|
|
410
|
-
'name' => $data['name'],
|
|
411
|
-
'email' => $data['email'],
|
|
412
|
-
'password' => Hash::make($data['password']),
|
|
413
|
-
]);
|
|
414
|
-
|
|
415
|
-
$this->mailer->sendWelcomeEmail($user);
|
|
416
|
-
|
|
417
|
-
return $user;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
### PSR-3 日志接口
|
|
423
|
-
```php
|
|
424
|
-
use Psr\Log\LoggerInterface;
|
|
425
|
-
|
|
426
|
-
class OrderProcessor
|
|
427
|
-
{
|
|
428
|
-
public function __construct(
|
|
429
|
-
private LoggerInterface $logger
|
|
430
|
-
) {}
|
|
431
|
-
|
|
432
|
-
public function process(Order $order)
|
|
433
|
-
{
|
|
434
|
-
$this->logger->info('Processing order', ['order_id' => $order->id]);
|
|
435
|
-
|
|
436
|
-
try {
|
|
437
|
-
$order->process();
|
|
438
|
-
$this->logger->info('Order processed successfully');
|
|
439
|
-
} catch (\Exception $e) {
|
|
440
|
-
$this->logger->error('Order processing failed', [
|
|
441
|
-
'order_id' => $order->id,
|
|
442
|
-
'error' => $e->getMessage()
|
|
443
|
-
]);
|
|
444
|
-
throw $e;
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
## 数据库迁移
|
|
451
|
-
|
|
452
|
-
### 迁移文件
|
|
453
|
-
```php
|
|
454
|
-
use Illuminate\Database\Migrations\Migration;
|
|
455
|
-
use Illuminate\Database\Schema\Blueprint;
|
|
456
|
-
use Illuminate\Support\Facades\Schema;
|
|
457
|
-
|
|
458
|
-
return new class extends Migration
|
|
459
|
-
{
|
|
460
|
-
public function up()
|
|
461
|
-
{
|
|
462
|
-
Schema::create('posts', function (Blueprint $table) {
|
|
463
|
-
$table->id();
|
|
464
|
-
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
|
465
|
-
$table->string('title');
|
|
466
|
-
$table->text('content');
|
|
467
|
-
$table->boolean('published')->default(false);
|
|
468
|
-
$table->timestamp('published_at')->nullable();
|
|
469
|
-
$table->timestamps();
|
|
470
|
-
$table->softDeletes();
|
|
471
|
-
|
|
472
|
-
$table->index(['user_id', 'published']);
|
|
473
|
-
$table->fullText(['title', 'content']);
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
public function down()
|
|
478
|
-
{
|
|
479
|
-
Schema::dropIfExists('posts');
|
|
480
|
-
}
|
|
481
|
-
};
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
## 测试
|
|
485
|
-
|
|
486
|
-
### PHPUnit 单元测试
|
|
487
|
-
```php
|
|
488
|
-
namespace Tests\Unit;
|
|
489
|
-
|
|
490
|
-
use PHPUnit\Framework\TestCase;
|
|
491
|
-
use App\Services\Calculator;
|
|
492
|
-
|
|
493
|
-
class CalculatorTest extends TestCase
|
|
494
|
-
{
|
|
495
|
-
private Calculator $calculator;
|
|
496
|
-
|
|
497
|
-
protected function setUp(): void
|
|
498
|
-
{
|
|
499
|
-
$this->calculator = new Calculator();
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
public function test_addition()
|
|
503
|
-
{
|
|
504
|
-
$result = $this->calculator->add(2, 3);
|
|
505
|
-
$this->assertEquals(5, $result);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
public function test_division_by_zero()
|
|
509
|
-
{
|
|
510
|
-
$this->expectException(\DivisionByZeroError::class);
|
|
511
|
-
$this->calculator->divide(10, 0);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
### Laravel 功能测试
|
|
517
|
-
```php
|
|
518
|
-
namespace Tests\Feature;
|
|
519
|
-
|
|
520
|
-
use Tests\TestCase;
|
|
521
|
-
use App\Models\User;
|
|
522
|
-
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
523
|
-
|
|
524
|
-
class UserApiTest extends TestCase
|
|
525
|
-
{
|
|
526
|
-
use RefreshDatabase;
|
|
527
|
-
|
|
528
|
-
public function test_can_create_user()
|
|
529
|
-
{
|
|
530
|
-
$response = $this->postJson('/api/users', [
|
|
531
|
-
'name' => 'John Doe',
|
|
532
|
-
'email' => 'john@example.com',
|
|
533
|
-
'password' => 'password123'
|
|
534
|
-
]);
|
|
535
|
-
|
|
536
|
-
$response->assertStatus(201)
|
|
537
|
-
->assertJsonStructure(['id', 'name', 'email']);
|
|
538
|
-
|
|
539
|
-
$this->assertDatabaseHas('users', [
|
|
540
|
-
'email' => 'john@example.com'
|
|
541
|
-
]);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
```
|
|
545
|
-
|
|
546
|
-
## 性能优化
|
|
547
|
-
|
|
548
|
-
### 缓存策略
|
|
549
|
-
```php
|
|
550
|
-
use Illuminate\Support\Facades\Cache;
|
|
551
|
-
|
|
552
|
-
// 基础缓存
|
|
553
|
-
$users = Cache::remember('users.all', 3600, function () {
|
|
554
|
-
return User::all();
|
|
555
|
-
});
|
|
556
|
-
|
|
557
|
-
// 标签缓存
|
|
558
|
-
Cache::tags(['users', 'posts'])->put('user.1.posts', $posts, 3600);
|
|
559
|
-
Cache::tags(['users'])->flush();
|
|
560
|
-
|
|
561
|
-
// 缓存锁
|
|
562
|
-
Cache::lock('process-order-' . $orderId, 10)->get(function () {
|
|
563
|
-
// 独占处理
|
|
564
|
-
});
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
### 数据库优化
|
|
568
|
-
```php
|
|
569
|
-
// 预加载关联
|
|
570
|
-
$users = User::with(['posts', 'comments'])->get();
|
|
571
|
-
|
|
572
|
-
// 延迟预加载
|
|
573
|
-
$users->load('posts.comments');
|
|
574
|
-
|
|
575
|
-
// 只查询需要的列
|
|
576
|
-
User::select('id', 'name', 'email')->get();
|
|
577
|
-
|
|
578
|
-
// 分块处理
|
|
579
|
-
User::chunk(100, function ($users) {
|
|
580
|
-
foreach ($users as $user) {
|
|
581
|
-
// 处理
|
|
582
|
-
}
|
|
583
|
-
});
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
## 安全最佳实践
|
|
587
|
-
|
|
588
|
-
### 输入验证
|
|
589
|
-
```php
|
|
590
|
-
use Illuminate\Http\Request;
|
|
591
|
-
|
|
592
|
-
class UserController extends Controller
|
|
593
|
-
{
|
|
594
|
-
public function store(Request $request)
|
|
595
|
-
{
|
|
596
|
-
$validated = $request->validate([
|
|
597
|
-
'name' => 'required|string|max:255',
|
|
598
|
-
'email' => 'required|email|unique:users',
|
|
599
|
-
'password' => 'required|min:8|confirmed',
|
|
600
|
-
'age' => 'nullable|integer|min:18|max:120'
|
|
601
|
-
]);
|
|
602
|
-
|
|
603
|
-
return User::create($validated);
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
### SQL 注入防护
|
|
609
|
-
```php
|
|
610
|
-
// ✅ 正确:参数绑定
|
|
611
|
-
$users = DB::select('SELECT * FROM users WHERE email = ?', [$email]);
|
|
612
|
-
|
|
613
|
-
// ✅ 正确:查询构建器
|
|
614
|
-
$users = DB::table('users')->where('email', $email)->get();
|
|
615
|
-
|
|
616
|
-
// ❌ 错误:字符串拼接
|
|
617
|
-
$users = DB::select("SELECT * FROM users WHERE email = '$email'");
|
|
618
|
-
```
|
|
619
|
-
|
|
620
|
-
### CSRF 保护
|
|
621
|
-
```php
|
|
622
|
-
// Blade 表单
|
|
623
|
-
<form method="POST" action="/users">
|
|
624
|
-
@csrf
|
|
625
|
-
<input type="text" name="name">
|
|
626
|
-
<button type="submit">Submit</button>
|
|
627
|
-
</form>
|
|
628
|
-
|
|
629
|
-
// API 排除
|
|
630
|
-
protected $except = [
|
|
631
|
-
'api/*',
|
|
632
|
-
];
|
|
633
|
-
```
|
|
634
|
-
|
|
635
|
-
## 框架对比
|
|
636
|
-
|
|
637
|
-
| 特性 | Laravel | Symfony |
|
|
638
|
-
|------|---------|---------|
|
|
639
|
-
| 学习曲线 | 平缓 | 陡峭 |
|
|
640
|
-
| ORM | Eloquent | Doctrine |
|
|
641
|
-
| 模板引擎 | Blade | Twig |
|
|
642
|
-
| 适用场景 | 快速开发 | 企业级 |
|
|
643
|
-
| 性能 | 中等 | 较高 |
|
|
644
|
-
| 生态 | 丰富 | 模块化 |
|
|
645
|
-
|
|
646
|
-
## 工具清单
|
|
647
|
-
|
|
648
|
-
| 工具 | 用途 |
|
|
649
|
-
|------|------|
|
|
650
|
-
| Laravel | 全栈框架 |
|
|
651
|
-
| Symfony | 企业级框架 |
|
|
652
|
-
| Composer | 依赖管理 |
|
|
653
|
-
| PHPUnit | 单元测试 |
|
|
654
|
-
| Laravel Pint | 代码格式化 |
|
|
655
|
-
| PHPStan | 静态分析 |
|
|
656
|
-
| Laravel Telescope | 调试工具 |
|
|
657
|
-
| Laravel Horizon | 队列监控 |
|
|
658
|
-
|
|
659
|
-
---
|