تحديد معدل الطلبات في PHP: دليل كامل للحد من الطلبات

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

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

ابدأ الدورة

تحديد معدل الطلبات في PHP: حماية API وتحسين التحميل

\n

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

\n\n

الخوارزميات الأساسية لتحديد معدل الطلبات

\n

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

\n
    \n
  • Token Bucket (دلو الرموز) — الخوارزمية الأكثر مرونة. يحتوي الدلو على N من الرموز، كل طلب يستهلك رمزًا. يتم استعادة الرموز بمعدل محدد.
  • \n
  • Leaky Bucket (الدلو المتسرب) — تتم معالجة الطلبات بمعدل ثابت. يتم تجاهل الطلبات الزائدة أو وضعها في قائمة انتظار.
  • \n
  • Fixed Window (النافذة الثابتة) — يتم حساب الطلبات خلال فترة زمنية ثابتة (مثل 60 ثانية). بسيط، لكنه قد يسمح بذروات التحميل عند حدود النوافذ.
  • \n
  • Sliding Window (النافذة المنزلقة) — خوارزمية أكثر دقة، تأخذ في الاعتبار الطلبات في نافذة زمنية متحركة. تستخدم السجلات أو العدادات مع الطوابع الزمنية.
  • \n
\n\n

المكتبات الشائعة لتحديد معدل الطلبات في PHP

\n\n

1. Symfony Rate Limiter (symfony/rate-limiter)

\n

مكون Symfony الرسمي، لكنه يعمل أيضًا كمكتبة مستقلة. يدعم جميع الخوارزميات الرئيسية: Token Bucket، Fixed Window، Sliding Window. مثالي للمشاريع على Symfony أو Laravel.

\n
use Symfony\\Component\\RateLimiter\\RateLimiterFactory;\nuse Symfony\\Component\\RateLimiter\\Storage\\InMemoryStorage;\n\n$factory = new RateLimiterFactory([\n    'id' => 'api',\n    'policy' => 'token_bucket',\n    'limit' => 100,\n    'rate' => ['interval' => '1 minute'],\n], new InMemoryStorage());\n\n$limiter = $factory->create('user_123');\n\nif ($limiter->consume(1)->isAccepted()) {\n    // معالجة الطلب\n} else {\n    // إرجاع 429 Too Many Requests\n    header('HTTP/1.1 429 Too Many Requests');\n    echo json_encode(['error' => 'Rate limit exceeded']);\n}
\n\n

2. nikic/FastRoute مع middleware لتحديد معدل الطلبات

\n

حل خفيف للمشاريع بدون أطر عمل. يستخدم تطبيق PHP لـ Token Bucket مع تخزين في Redis أو Memcached.

\n
class RateLimitMiddleware {\n    private $redis;\n    private $maxRequests = 100;\n    private $window = 60; // ثانية\n\n    public function handle($request, $next) {\n        $key = 'rate_limit:' . $_SERVER['REMOTE_ADDR'];\n        $current = $this->redis->incr($key);\n        \n        if ($current === 1) {\n            $this->redis->expire($key, $this->window);\n        }\n\n        if ($current > $this->maxRequests) {\n            return new Response('Too Many Requests', 429);\n        }\n\n        return $next($request);\n    }\n}
\n\n

3. Laravel Rate Limiter (مدمج)

\n

في Laravel، تحديد معدل الطلبات مدمج في النواة. يستخدم Redis أو ذاكرة التخزين المؤقت. يدعم المحددات المسماة والتقسيم حسب المستخدمين.

\n
// في RouteServiceProvider\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Http\\Request;\n\nprotected function configureRateLimiting()\n{\n    RateLimiter::for('api', function (Request $request) {\n        return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());\n    });\n}\n\n// في المتحكم\npublic function index()\n{\n    $executed = RateLimiter::attempt(\n        'send-message:'.$user->id,\n        $perMinute = 5,\n        function() {\n            // إرسال الرسالة\n        }\n    );\n    \n    if (! $executed) {\n        return response('Too Many Attempts.', 429);\n    }\n}
\n\n

4. PHP RateLimit (php-rateLimit/php-rateLimit)

\n

مكتبة عالمية

توصيات