إطار Laravel
Laravel Pint وجودة الكود
Laravel Pint وجودة الكود
جودة الكود أساسية للتطبيقات القابلة للصيانة. Laravel Pint هو مصلح أسلوب كود PHP ذو رأي مبني على PHP-CS-Fixer، مصمم خصيصاً لمشاريع Laravel. جنباً إلى جنب مع أدوات التحليل الثابت، يضمن أن كودك نظيف ومتسق وخالٍ من الأخطاء.
مقدمة إلى Laravel Pint
ما هو Laravel Pint؟
Laravel Pint هو مصلح أسلوب كود بدون تكوين يفرض معايير ترميز متسقة عبر تطبيق Laravel الخاص بك. يأتي مُكوّناً مسبقاً بأسلوب ترميز Laravel لكن يمكن تخصيصه لمطابقة تفضيلات فريقك.
الميزات الرئيسية:- لا يتطلب تكوين - يعمل خارج الصندوق
- مبني على PHP-CS-Fixer
- يدعم إعدادات Laravel و PER و PSR-12 و Symfony
- سريع وفعال - يصلح فقط ما تغير
- تكامل IDE و CI/CD
تثبيت واستخدام Laravel Pint
// يأتي Pint مثبتاً مسبقاً مع Laravel 9+
// للمشاريع القديمة، قم بتثبيته:
composer require laravel/pint --dev
// تشغيل Pint لإصلاح أسلوب الكود
./vendor/bin/pint
// التحقق بدون الإصلاح (مفيد لـ CI)
./vendor/bin/pint --test
// إصلاح ملفات أو دلائل محددة
./vendor/bin/pint app/Models
./vendor/bin/pint app/Http/Controllers/UserController.php
// معاينة التغييرات بدون تطبيقها
./vendor/bin/pint --dry-run
// إظهار الإخراج المطول
./vendor/bin/pint -v
// استخدام إعداد مسبق محدد
./vendor/bin/pint --preset psr12
تكوين Pint
أنشئ ملف pint.json في جذر مشروعك لتخصيص القواعد:
// pint.json
{
"preset": "laravel",
"rules": {
"simplified_null_return": true,
"braces": false,
"new_with_braces": {
"anonymous_class": true,
"named_class": true
},
"no_unused_imports": true,
"ordered_imports": {
"sort_algorithm": "alpha"
},
"single_quote": true,
"trailing_comma_in_multiline": {
"elements": ["arrays"]
}
},
"exclude": [
"vendor",
"storage",
"bootstrap/cache"
]
}
// بديل: استخدم تكوين PHP
// pint.php
<?php
return [
'preset' => 'laravel',
'rules' => [
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'default' => 'single_space',
],
'blank_line_after_namespace' => true,
'blank_line_after_opening_tag' => true,
'blank_line_before_statement' => [
'statements' => ['return'],
],
],
];
تكامل Git:
أضف Pint كخطاف pre-commit لإصلاح أسلوب الكود تلقائياً قبل الالتزام:
# .husky/pre-commit
#!/bin/sh
./vendor/bin/pint --test || (
./vendor/bin/pint
git add .
)
التحليل الثابت مع PHPStan و Larastan
يقوم PHPStan بإجراء تحليل ثابت للعثور على الأخطاء دون تشغيل الكود. Larastan هو غلاف PHPStan مع قواعد خاصة بـ Laravel.
// تثبيت Larastan
composer require larastan/larastan --dev
// إنشاء تكوين phpstan.neon
// phpstan.neon
includes:
- vendor/larastan/larastan/extension.neon
parameters:
paths:
- app
- config
- database
- routes
# المستوى يذهب من 0 إلى 9 (الأكثر صرامة)
level: 6
# تجاهل أخطاء محددة
ignoreErrors:
- '#Call to an undefined method .*::factory\(\)#'
# التحقق من الأنواع المفقودة
checkMissingIterableValueType: false
checkGenericClassInNonGenericObjectType: false
# قواعد مخصصة
excludePaths:
- vendor
- storage
- bootstrap/cache
// تشغيل PHPStan
./vendor/bin/phpstan analyse
// إصلاح ما يمكن إصلاحه تلقائياً
./vendor/bin/phpstan analyse --generate-baseline
// استخدام حد الذاكرة للمشاريع الكبيرة
./vendor/bin/phpstan analyse --memory-limit=2G
مشاكل PHPStan الشائعة والحلول
// المشكلة: الخاصية ليس لها نوع أو نوع مختلط
// سيء
class User extends Model
{
protected $fillable;
}
// جيد
class User extends Model
{
/** @var array<string> */
protected $fillable = ['name', 'email'];
}
// المشكلة: الدالة ليس لها نوع إرجاع
// سيء
public function getUsers()
{
return User::all();
}
// جيد
public function getUsers(): Collection
{
return User::all();
}
// المشكلة: لا يتم قراءة/كتابة الخاصية أبداً
// استخدم تعليقات PHPStan
/** @phpstan-ignore-next-line */
private $unusedProperty;
// المشكلة: دالة غير محددة على نموذج Eloquent
/** @var \App\Models\User $user */
$user = User::find(1);
$user->posts(); // PHPStan الآن يعرف عن هذه العلاقة
// أو استخدم PHPDoc على النموذج
/**
* @property-read \Illuminate\Database\Eloquent\Collection<Post> $posts
* @method \Illuminate\Database\Eloquent\Relations\HasMany posts()
*/
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
IDE Helper للإكمال التلقائي الأفضل
Laravel IDE Helper ينشئ PHPDocs لواجهات Laravel ونماذجها لتحسين الإكمال التلقائي لـ IDE:
// تثبيت IDE Helper
composer require --dev barryvdh/laravel-ide-helper
// إنشاء ملفات المساعدة
php artisan ide-helper:generate
php artisan ide-helper:models
php artisan ide-helper:meta
// إنشاء تلقائي عند تحديث composer
// composer.json
{
"scripts": {
"post-update-cmd": [
"@php artisan ide-helper:generate",
"@php artisan ide-helper:models --nowrite",
"@php artisan ide-helper:meta"
]
}
}
// إضافة إلى .gitignore
_ide_helper.php
_ide_helper_models.php
.phpstorm.meta.php
// إنشاء PHPDoc للنماذج
php artisan ide-helper:models --write
// هذا يضيف PHPDoc إلى نماذجك:
/**
* App\Models\User
*
* @property int $id
* @property string $name
* @property string $email
* @property \Illuminate\Support\Carbon|null $email_verified_at
* @property string $password
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection $notifications
* @property-read \Illuminate\Database\Eloquent\Collection $posts
* @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereName($value)
*/
class User extends Authenticatable
{
// ...
}
أفضل ممارسات IDE Helper:
- أنشئ ملفات المساعدة في التطوير، التزم بها في التحكم بالإصدار
- أعد إنشاءها بعد إضافة واجهات أو نماذج أو دوال جديدة
- استخدم
--nowriteلإنشاء ملفات PHPDoc منفصلة بدلاً من تعديل النماذج - راجع PHPDocs المولدة - أحياناً يحتاج التصحيح اليدوي
أدوات التصحيح في Laravel
// Laravel Debugbar - شريط تصحيح قوي
composer require barryvdh/laravel-debugbar --dev
// Telescope - مساعد تصحيح أنيق لـ Laravel
composer require laravel/telescope --dev
php artisan telescope:install
php artisan migrate
// الوصول إلى Telescope
// زيارة: http://your-app.test/telescope
// Ray - أداة تصحيح سطح المكتب من Spatie
composer require spatie/laravel-ray --dev
// الاستخدام
ray('تصحيح هذا');
ray($user, $posts);
ray()->table($users);
ray()->measure(fn() => expensive_operation());
// Clock - مساعد تصحيح لـ Laravel
use Illuminate\Support\Facades\Date;
Date::setTestNow('2024-01-01 12:00:00');
now(); // يرجع 2024-01-01 12:00:00
// تصحيح الاستعلامات
DB::enableQueryLog();
// استعلاماتك هنا
dd(DB::getQueryLog());
// أو استخدم مستمع الاستعلامات
DB::listen(function ($query) {
logger($query->sql, $query->bindings, $query->time);
});
أفضل ممارسات مراجعة الكود
ما الذي تبحث عنه في مراجعات الكود:
1. البنية والتصميم:
- هل يتبع الكود مبادئ SOLID؟
- هل المسؤوليات منفصلة بشكل صحيح؟
- هل الكود قابل لإعادة الاستخدام والصيانة؟
- هل هناك أي روائح كود (دوال طويلة، فئات إلهية)؟
- الاستخدام الصحيح لعلاقات Eloquent
- قواعد التحقق الصحيحة
- الترخيص بالسياسات
- استعلامات قاعدة البيانات محسّنة (منع N+1)
- وظائف الطابور للمهام طويلة المدى
- لا توجد ثغرات حقن SQL
- حماية CSRF موجودة
- المصادقة والترخيص الصحيحين
- لا توجد بيانات حساسة في السجلات أو الاستجابات
- التحقق من صحة المدخلات وتطهيرها
- استعلامات قاعدة البيانات محسّنة
- استراتيجية التخزين المؤقت الصحيحة
- لا حلقات أو عمليات غير ضرورية
- التحميل الكسول مقابل التحميل الحريص
- تغطية الاختبار الكافية
- الاختبارات ذات معنى وقابلة للصيانة
- الحالات الحدية مغطاة
إعداد التكامل المستمر
// سير عمل GitHub Actions
// .github/workflows/laravel.yml
name: Laravel CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
laravel-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, xml, bcmath
coverage: xdebug
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Create Database
run: |
mkdir -p database
touch database/database.sqlite
- name: Run Pint
run: ./vendor/bin/pint --test
- name: Run PHPStan
run: ./vendor/bin/phpstan analyse
- name: Execute tests
env:
DB_CONNECTION: sqlite
DB_DATABASE: database/database.sqlite
run: php artisan test --coverage
- name: Upload coverage reports
uses: codecov/codecov-action@v3
تمرين 1: أعد أدوات جودة الكود:
- ثبت Laravel Pint وأنشئ تكويناً مخصصاً
- ثبت Larastan وكوّنه بالمستوى 6
- ثبت IDE Helper وأنشئ ملفات المساعدة
- قم بتشغيل جميع الأدوات وإصلاح المشاكل المبلغ عنها
- أضف خطافات pre-commit للفحوصات التلقائية
- وثق معايير الترميز لفريقك
تمرين 2: قم بإجراء مراجعة شاملة للكود:
- حدد وحدة تحكم موجودة في مشروعك
- تحقق من تلميحات الأنواع وأنواع الإرجاع الصحيحة
- تحقق من معالجة الأخطاء والتحقق الصحيح
- ابحث عن مشاكل استعلام N+1
- اقترح تحسينات للقراءة
- أنشئ قائمة مراجعة لمراجعات الكود المستقبلية
تمرين 3: أنشئ خط أنابيب CI/CD:
- أعد GitHub Actions أو GitLab CI لمشروع Laravel الخاص بك
- كوّن الاختبار التلقائي عند كل دفع
- أضف فحوصات Pint و PHPStan إلى خط الأنابيب
- كوّن الإبلاغ عن تغطية الكود
- أضف النشر التلقائي إلى التدريج عند الدمج في develop
- أعد الإشعارات لفشل البناء