تحديد معدل الطلبات في PHP: تقييد تردد الطلبات لحماية الموقع

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

تحديد معدل الطلبات في PHP: دليل كامل للحماية من الأحمال الزائدة



تحديد معدل الطلبات (Rate Limiting) هو آلية حماية بالغة الأهمية لتطبيقات الويب. فهو يمنع إساءة استخدام موارد الخادم، ويحمي من هجمات DDoS، والتخمين العنيف لكلمات المرور، والبريد العشوائي. في PHP، توجد عدة طرق ومكتبات فعالة لتطبيق تحديد معدل الطلبات. في هذه المقالة، سنستعرض أفضل الأدوات، ومبادئ العمل، وأمثلة عملية.



ما هو تحديد معدل الطلبات ولماذا هو ضروري؟

يحدد تحديد معدل الطلبات الحد الأقصى لعدد الطلبات التي يمكن للعميل (عنوان IP، مستخدم، أو مفتاح API) تنفيذها خلال فترة زمنية محددة. الأهداف الرئيسية:

  • الحماية من DDoS — منع تحميل الخادم الزائد بواسطة البوتات
  • منع التخمين العنيف — تقييد محاولات تسجيل الدخول إلى النظام
  • توزيع عادل للموارد — وصول متساوٍ لجميع المستخدمين
  • توفير موارد الخادم — تقليل الحمل على قاعدة البيانات والمعالج


الخوارزميات الشائعة لتحديد معدل الطلبات

قبل اختيار مكتبة، من المهم فهم الخوارزميات الأساسية:

  • Token Bucket (دلو الرموز) — يراكم الرموز بمعدل معين، ويسمح باندفاعات مؤقتة في حركة المرور
  • Leaky Bucket (الدلو المتسرب) — يخفف حركة المرور، ويعالج الطلبات بمعدل ثابت
  • Fixed Window (النافذة الثابتة) — يحسب الطلبات خلال فترة زمنية ثابتة
  • Sliding Window (النافذة المنزلقة) — نسخة أكثر دقة، تراعي الطلبات في نافذة زمنية منزلقة


أفضل المكتبات لتحديد معدل الطلبات في PHP



1. Symfony Rate Limiter

مكون Symfony الرسمي، والذي يمكن استخدامه بشكل مستقل عن الإطار. يدعم Redis، APCu، والتخزين في الملفات.

composer require symfony/rate-limiter

مثال على الاستخدام:

<?phpuse Symfony\\Component\\RateLimiter\\RateLimiterFactory;use Symfony\\Component\\RateLimiter\\Storage\\InMemoryStorage;

$factory = new RateLimiterFactory([ 'id' => 'login', 'policy' => 'token_bucket', 'limit' => 10, 'rate' => ['interval' => '1 minute'],], new InMemoryStorage());

$limiter = $factory->create('user_123');

if ($limiter->consume()->isAccepted()) { // السماح بالطلب echo "تم السماح بالوصول";} else { // رفض الطلب http_response_code(429); echo "عدد الطلبات كبير جداً";}?>


2. PHP RateLimiter (بواسطة bantu)

مكتبة خفيفة الوزن للسيناريوهات البسيطة. تدعم Redis، Memcached، والملفات.

composer require bantu/php-ratelimiter

مثال:

<?phpuse bantu\\RateLimiter\\RateLimiterFactory;

$factory = new RateLimiterFactory();$limiter = $factory->createRedisRateLimiter( new \\Predis\\Client(), 'api_limit', 100, // حد الطلبات 3600 // النافذة بالثواني);

if ($limiter->hit($_SERVER['REMOTE_ADDR'])) { echo "تم قبول الطلب";} else { http_response_code(429); echo "تم استنفاد الحد";}?>


3. GrahamCampbell/Laravel RateLimiter

إذا كنت تعمل مع Laravel، فهذا حل أصلي. مدمج في الإطار بدءاً من الإصدار 8.

<?phpuse Illuminate\\Support\\Facades\\RateLimiter;

// تعريف المحدد في AppServiceProviderRateLimiter::for('api', function ($job) { return \\Illuminate\\Cache\\RateLimiting\\Limit::perMinute(60)->by($job->user->id ?: $job->ip());});

// الاستخدام في المتحكمpublic function store(Request $request){ if (RateLimiter::tooManyAttempts('send-message:'.$request->ip(), 5)) { return response('عدد الرسائل كبير جداً', 429)

توصيات