PHP للبرمجة النظامية: من السكربتات إلى الخدمات الخلفية

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

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

ابدأ الدورة

عندما يتجاوز PHP حدود الويب

\n

تخيل موقفًا: تحتاج إلى كتابة خدمة خلفية (daemon) تراقب سجلات النظام، وتحللها، وترسل إشعارات إلى Telegram. أو ربما تحتاج إلى إنشاء جدولة مهام خاصة بك لا تعتمد على cron. أو ماذا لو أردت كتابة خادم ويب بسيط أو وكيل (proxy) خاص بك؟ معظم المطورين سيتجهون فورًا إلى Python أو Go أو C. ولكن ماذا لو أخبرتك أن PHP أيضًا قادرة على البرمجة النظامية؟ وبكفاءة عالية.

\n

PHP ليست مجرد لغة لـ"مواقع WordPress". إصدار CLI (واجهة سطر الأوامر) الخاص بها هو أداة متكاملة للإدارة النظامية، والتعامل مع العمليات، والمقابس الشبكية، وحتى إنشاء الخدمات الخلفية. في هذا المقال، سنشرح كيفية استخدام PHP للبرمجة النظامية، وسنقدم أمثلة كود حقيقية تعمل على Linux.

\n\n

التحضير: ما تحتاج معرفته

\n

أولاً، تأكد من تثبيت PHP مع دعم CLI والإضافات pcntl (إدارة العمليات)، posix (استدعاءات النظام)، و sockets (التعامل مع المقابس). في معظم توزيعات Linux، يمكنك فعل ذلك بأمر واحد:

\n
sudo apt install php-cli php-pcntl php-posix php-sockets
\n

يمكنك التحقق من توفر الإضافات باستخدام php -m | grep -E 'pcntl|posix|sockets'. إذا كانت كلها موجودة، فلنبدأ.

\n\n

التعامل مع العمليات: fork و exec

\n

يتيح لك PHP إنشاء عمليات فرعية باستخدام الدالة pcntl_fork(). هذه آلية قوية لتنفيذ المهام بشكل متوازٍ. لنلقِ نظرة على مثال يقوم بتشغيل ثلاث عمليات فرعية، كل منها تؤدي مهمتها الخاصة.

\n
<?php\n$workers = 3;\n$pids = [];\n\nfor ($i = 0; $i < $workers; $i++) {\n    $pid = pcntl_fork();\n    if ($pid == -1) {\n        die("فشل إنشاء العملية");\n    } elseif ($pid) {\n        // العملية الأم: حفظ معرف العملية الفرعية\n        $pids[] = $pid;\n        echo "تم إنشاء عملية فرعية PID: $pid\\n";\n    } else {\n        // العملية الفرعية\n        echo "العملية الفرعية " . getmypid() . " بدأت العمل\\n";\n        sleep(rand(2, 5)); // محاكاة العمل\n        echo "العملية الفرعية " . getmypid() . " انتهت\\n";\n        exit(0);\n    }\n}\n\n// العملية الأم تنتظر انتهاء جميع العمليات الفرعية\nforeach ($pids as $pid) {\n    pcntl_waitpid($pid, $status);\n    echo "العملية $pid انتهت بحالة $status\\n";\n}\n?>
\n

يوضح هذا الكود أساسيات تعدد المهام في PHP. يمكنك تشغيل مهام متوازية — تحليل السجلات، معالجة الملفات، تنفيذ طلبات الشبكة. في البرمجة النظامية، هذا الأسلوب لا غنى عنه عندما تحتاج إلى معالجة كميات كبيرة من البيانات دون حظر التيار الرئيسي.

\n\n

تنفيذ الأوامر الخارجية

\n

الدالة exec() ومتغيراتها (shell_exec()، system()) تسمح لك بتشغيل أي أوامر نظام. ولكن للبرمجة النظامية الحقيقية، من الأفضل استخدام proc_open() — فهي تمنحك تحكمًا كاملاً في الإدخال/الإخراج ومعرف العملية (PID).

\n
<?php\n$descriptorspec = [\n    0 => ["pipe", "r"],  // stdin\n    1 => ["pipe", "w"],  // stdout\n    2 => ["pipe", "w"]   // stderr\n];\n\n$process = proc_open('ping -c 4 8.8.8.8', $descriptorspec, $pipes);\n\nif (is_resource($process)) {\n    // قراءة المخرجات\n    $output = stream_get_contents($pipes[1]);\n    fclose($pipes[1]);\n    fclose($pipes[2]);\n    proc_close($process);\n    \n    echo "نتيجة ping:\\n$output";\n}\n?>
\n

هذا الأسلوب يسمح بدمج PHP مع أي أدوات نظام — من ps إلى ffmpeg.

\n\n

معالجة الإشارات: جعل الخدمة الخلفية مهذبة

\n

أي خدمة خلفية جادة يجب أن تتعامل بشكل صحيح مع إشارات نظام التشغيل. PHP عبر إضافة pcntl تسمح باعتراض الإشارات (SIGTERM، SIGHUP، SIGUSR1 وغيرها). هذه مهارة أساسية

المدونات

توصيات الكتب