SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-23

تعطيل WP-Cron واستخدام cron النظام مع WP-CLI

يتوقف WP-Cron في المواقع الهادئة ويتراكم في المزدحمة لأنه يعمل عند تحميل الصفحات فقط. انقله إلى cron النظام باستخدام WP-CLI وتحقق من تنفيذ المهام.

ما هو wp-cron ولماذا يستبدله cron النظام

WP-Cron هو مجدول المهام المضمّن في WordPress، ولا يعمل إلا عندما يطلب أحدهم صفحة. لا شيء داخل WordPress يوقظ نفسه تلقائياً. عند كل طلب لا يُخدَم من ذاكرة التخزين المؤقت، يقرأ WordPress قائمة المهام المجدولة. وإذا حان موعد إحدى المهام، يرسل طلب HTTP ثانياً إلى نفسه على /wp-cron.php لتنفيذها. يتيح لك نقل هذه المهمة إلى cron النظام تشغيلها مرة واحدة وفق جدول ثابت يمكن التنبؤ به، سواء زار الموقع ألف مستخدم في تلك الدقيقة أم لم يزره أحد.

ينفّذ العمل الفعلي سطران: ثابت في wp-config.php، وإدخال في crontab. أما بقية هذا الدليل فتشرح ما لا يوضحه هذان السطران. ستعرف المستخدم الذي يجب أن يعمل الحساب باسمه، وكيف تثبت أن الأحداث المجدولة نُفِّذت فعلاً، والطرق الثلاث التي يفشل بها الإعداد من دون عرض أي رسالة على الموقع.

تستخدم الأمثلة /srv/www/example.com بصفته دليل WordPress، وwww-data بصفته مستخدم خادم الويب. استبدل المسارات والمستخدمين بقيمك الخاصة في جميع المواضع.

ما الزائر الذي تسبب في تكلفة cron على موقع مزدحم

تدفع كل مطالبة غير موجودة في ذاكرة التخزين المؤقت تكلفة هذا الفحص. يحمّل WordPress الخيار cron، ويقارن الطوابع الزمنية، وعندما يحين موعد مهمة ما يستدعي spawn_cron()، الذي يرسل مطالبة loopback غير متزامنة إلى /wp-cron.php. لا ينتظر الزائر النتيجة. لكن أحد عمال PHP ينتظرها. على VPS صغير يشغّل PHP-FPM مع pm.max_children = 5، تحتجز مهمة مجدولة بطيئة خُمس سعة PHP لديك طوال مدة تنفيذها، ومن المرجح جداً أن تبدأ خلال أكثر دقائقك ازدحاماً، لأن عدد تحميلات الصفحات يكون أكبر حينها.

يحد WordPress من التكرارات. إذ ينشئ قفلاً يستمر لمدة WP_CRON_LOCK_TIMEOUT، ومدته الافتراضية 60 ثانية، لذلك لا يبدأ الزوار المتزامنون عملية منفصلة لكل منهم. يحد القفل من التكرار. لكنه لا ينقل العمل خارج مسار الطلب.

احسب عدد مرات تشغيلها على خادمك قبل أن تقرر أنها مؤثرة. يظهر كل loopback في سجل وصول خادم الويب:

sudo grep -c 'wp-cron.php' /var/log/nginx/access.log

يكتب Apache في /var/log/apache2/access.log بدلاً من ذلك. يمثّل عدد بالآلاف يومياً تكلفة فعلية. وهذا نوع من الأرقام ينبغي أن تقيسه على خادمك بنفسك، لا أن تقرأه في مقال، كما تفعل عند إجراء اختبار أداء لـVPS قبل أي تغيير آخر وبعده.

تغيّر التخزين المؤقت الصورة. إذا قدّمت ذاكرة تخزين مؤقت للصفحات معظم الطلبات بصيغة HTML ثابتة، فلن يعمل PHP لهذه الطلبات، ولذلك لا يحدث فحص cron. يبدأ الموقع المزدحم الذي يستخدم تخزيناً مؤقتاً مكثفاً في التصرف مثل الموقع الهادئ أدناه.

ما الزائر الذي تسبّب في تعطل cron على موقع هادئ

لا يوجد زوار، إذن لا يوجد cron. الموقع الذي يحصل على عدد قليل من الزيارات يومياً يشغّل مهامه المجدولة عدداً مماثلاً من المرات يومياً، وفي لحظات عشوائية تحددها أوقات وصول هذه الزيارات.

تتشابه الأعراض جميعاً. تبقى مقالة مجدولة للنشر عند الساعة 09:00 في قائمة المقالات مع وضع علامة Missed schedule عليها، إلى أن يحمّل أحدهم صفحة. تتخطى إضافات النسخ الاحتياطي مهمة الليل. تتأخر عمليات البحث عن التحديثات، لذلك لا تعرض لوحة التحكم أي تحديثات، رغم صدور تحديث أمني بالفعل. تصل رسائل الطلبات وإشعارات التجديد وتحذيرات انتهاء الصلاحية متأخرة.

لا يسجل أي من ذلك خطأً. فمن منظور WordPress، لم تتأخر المهمة، لأنها لم تبدأ أصلاً.

الخطوة 1: عطّل مُشغّل الزائر في wp-config.php

افتح /srv/www/example.com/wp-config.php وأضف الثابت التالي:

define( 'DISABLE_WP_CRON', true );

ضعه فوق السطر الذي يحتوي على /* That's all, stop editing! Happy publishing. */، لأن السطر الموجود أسفل ذلك التعليق يتطلب wp-settings.php، وفي wp-settings.php يربط WordPress فحص cron بـ init. إذا عرّفت الثابت بعد ذلك require، فسيكون تعريفه متأخراً ولن يغيّر أي شيء، بينما سيبدو الملف صحيحاً ويستمر المُشغّل في العمل.

تأكد من أن السطر موجود في الموضع المقصود:

grep -n "DISABLE_WP_CRON\|stop editing" /srv/www/example.com/wp-config.php

لا يمنع هذا الثابت جدولة الأحداث. تواصل الإضافات إضافة المهام إلى قائمة الانتظار كما في السابق. وهو يمنع تحميلات الصفحات فقط من تشغيل قائمة الانتظار، ما يعني أن قائمة الانتظار لن تعمل إطلاقاً الآن حتى تُكمل الخطوة 3.

كما أنه لا يمنع الطلبات المباشرة إلى /wp-cron.php. يظل بإمكان أي شخص طلب عنوان URL هذا، وهذا لا يسبب عادةً مشكلة لأن الملف يشغّل فقط المهام المستحقة. ويظل حظر هذا العنوان في إعدادات خادم الويب اختيارياً. وإذا حظرته، فسيتوقف أيضاً عمل البديل curl الموجود قرب نهاية هذا الدليل.

الخطوة 2: تثبيت WP-CLI

WP-CLI هي أداة سطر الأوامر الرسمية لـ WordPress. تحتاج إلى ملف PHP الثنائي لسطر الأوامر، وهو حزمة منفصلة عن وحدة PHP الخاصة بخادم الويب.

php -v
sudo apt install -y php-cli

ثبّت WP-CLI من إصدار phar، فهذا ما يوصي به دليل التثبيت الرسمي:

cd /tmp
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
php wp-cli.phar --info
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info

يطبع php wp-cli.phar --info مسار ملف PHP الثنائي وإصدار PHP وإصدار WP-CLI. إذا طبع القيم الثلاث، فهذا يعني أن phar يعمل. اعتباراً من August 2026، يحدد دليل التثبيت PHP 7.2.24 كحد أدنى، بينما يأتي Ubuntu 24.04 مع PHP 8.3، لذلك يتجاوز خادم حديث هذا الحد بكثير. حدّثه لاحقاً باستخدام sudo wp cli update.

شغّل WP-CLI باستخدام مستخدم الموقع، ولا تشغّله أبداً باستخدام root:

sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com core version

يرفض WP-CLI بدء التشغيل عند تشغيله باستخدام root:

Error: YIKES! It looks like you're running this as root.

ويقترح استخدام --allow-root. لا تستخدم ذلك هنا. يوضّح نمط الفشل الأول أدناه السبب.

لاحظ أيضاً أن sudo -u www-data -i لا يعمل، لأن shell تسجيل الدخول لهذا الحساب هو /usr/sbin/nologin، وستحصل على This account is currently not available.. يؤدي تمرير الأمر مباشرة إلى sudo -u إلى تجاوز shell تسجيل الدخول، ولذلك يعمل الأمر بشكل سليم.

تحقق الآن من أن WordPress نفسه يقرأ الثابت من الخطوة 1:

sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com eval 'var_dump( DISABLE_WP_CRON );'

يطبع ذلك bool(true). يشير الخطأ الفادح المتعلق بثابت غير معرّف إلى أن السطر define() لم يُنفّذ بعد، ويعني ذلك عادةً أنه وُضع بعد السطر require.

الخطوة 3: أضف إدخال cron بالمستخدم الصحيح

المستخدم الصحيح هو الذي يملك الملفات التي يكتب فيها PHP. تحقق من الطرفين:

stat -c '%U %G' /srv/www/example.com/wp-content/uploads
grep -E '^(user|group) = ' /etc/php/8.3/fpm/pool.d/www.conf

في تثبيت Ubuntu الافتراضي، تكون الإجابتان www-data. إذا منحت الموقع PHP-FPM pool خاصاً به وبمستخدم خاص به، وهو الوضع المعتاد عند إعداد كل موقع على حدة في حزمة LAMP على Ubuntu 24.04، فاستخدم ذلك المستخدم في كل ما يلي.

أنشئ دليلاً للسجلات يمكن لذلك المستخدم الكتابة فيه:

sudo install -d -o www-data -g www-data -m 750 /var/log/wp-cron

حرّر crontab لذلك المستخدم:

sudo crontab -u www-data -e

أضف سطراً واحداً:

*/5 * * * * /usr/bin/flock -n /run/lock/wp-cron-example.lock /usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now >> /var/log/wp-cron/example.log 2>&1

تفصيلاً. يشغّل */5 المهمة كل خمس دقائق. يأخذ flock -n ملف قفل ويتوقف فوراً إذا كانت عملية سابقة لا تزال تحتفظ به. يحدد /usr/local/bin/wp المسار المطلق الذي يحتاج إليه cron. يتيح --path تشغيل الأمر من أي دليل عمل. يشغّل --due-now الأحداث التي حان وقتها فقط، بدلاً من تشغيل كل حدث في قائمة الانتظار. يوجّه redirect المخرجات العادية والأخطاء إلى ملف واحد يمكنك قراءته.

هذا redirect ليس اختيارياً من الناحية العملية. يرسل cron مخرجات المهمة بالبريد إلى مستخدمها، ولا تحتوي معظم صور VPS على mail transfer agent مثبت، ثم يسجل cron (CRON) info (No MTA installed, discarding output) ويتخلص من المخرجات. يحافظ الملف على الدليل.

تحقق من حفظ الملف:

sudo crontab -u www-data -l

لعدة مواقع، استخدم سطراً لكل موقع مع توزيع الدقائق بحيث لا تبدأ كلها في الوقت نفسه:

*/5 * * * * /usr/bin/flock -n /run/lock/wp-cron-one.lock /usr/local/bin/wp --path=/srv/www/one.example.com cron event run --due-now >> /var/log/wp-cron/one.log 2>&1
2-59/5 * * * * /usr/bin/flock -n /run/lock/wp-cron-two.lock /usr/local/bin/wp --path=/srv/www/two.example.com cron event run --due-now >> /var/log/wp-cron/two.log 2>&1

ينمو السجل بلا نهاية ما لم تدوّره. اكتب /etc/logrotate.d/wp-cron:

/var/log/wp-cron/*.log {
    weekly
    rotate 4
    missingok
    notifempty
    compress
    create 640 www-data www-data
}

تحقق من صحة تحليله دون إجراء أي تغيير: sudo logrotate --debug /etc/logrotate.d/wp-cron.

الخطوة 4: تأكد من تنفيذ الأحداث المجدولة فعلياً

لا يثبت نجاح حفظ سطر crontab شيئاً. ابدأ بأبسط فحص، ثم انتقل تدريجياً إلى الفحص الذي يحسم الأمر فعلياً.

أولاً، هل بدأ cron الأمر؟ يكتب cron سجلاته في journal ضمن وحدته الخاصة:

journalctl -u cron.service --since "15 min ago" | grep wp

يبدو الإدخال السليم كما يلي، بعد حذف الطابع الزمني واسم المضيف من بدايته:

CRON[24913]: (www-data) CMD (/usr/bin/flock -n /run/lock/wp-cron-example.lock /usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now >> /var/log/wp-cron/example.log 2>&1)

يعني هذا السطر أن cron بدأ تشغيل الأمر بصفة www-data. ولا يوضح ما إذا كان الأمر قد نجح.

ثانياً، هل نفّذ WordPress أي شيء؟ اقرأ ملف السجل:

sudo tail -n 20 /var/log/wp-cron/example.log

يطبع WP-CLI سطراً واحداً لكل حدث، ثم يعرض الإجمالي:

Executed the cron event 'wp_version_check' in 0.418s.
Success: Executed a total of 2 cron events.

تُكتب الأخطاء في الملف نفسه، وهذا هو الغرض من 2>&1. لن تكون هناك أحداث مستحقة في معظم عمليات التشغيل، وسيُكتب قدر قليل جداً من البيانات. لذلك اقرأ الملف بعد تشغيل تعرف أن هناك أحداثاً تنتظر التنفيذ فيه.

ثالثاً، أثبت التنفيذ من البداية إلى النهاية. جدولة حدث مؤقت ومراقبة اختفائه:

sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com cron event schedule wp_cli_cron_check now
sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com cron event list --fields=hook,next_run_relative --format=csv | grep wp_cli_cron_check

انتظر فترة زمنية واحدة، ثم شغّل أمر القائمة مرة أخرى. يختفي الـhook لأن الحدث لمرة واحدة يُزال من قائمة الانتظار عند تشغيله. لا يسجّل أي plugin دالة callback باسم ذلك الـhook، لذلك لا يؤدي تشغيله إلى أي إجراء آخر على الموقع. إذا ظل الـhook معروضاً بعد فترتين زمنيتين، فهذا يعني أن قائمة الانتظار لا تُشغّل. ويحدد الفحصان الأولان ما إذا كانت المشكلة في cron أو WP-CLI.

لا تستخدم wp cron test لهذا الغرض. يتحقق ذلك الأمر من عمل إنشاء العمليات الذي يطلقه الزائر، ويصدر خطأ عندما تكون DISABLE_WP_CRON صحيحة. على خادم مُعدّ إعداداً صحيحاً، يكون الخطأ هو الناتج المتوقع وليس عطلاً.

بديل مؤقت systemd

إذا كانت المهام المجدولة الأخرى على الخادم تعمل بالفعل كـخدمات ومؤقتات systemd، فأضف WordPress إليها أيضاً. سيظهر كل تشغيل في systemctl list-timers، وسيُرسَل الخرج إلى السجل بدلاً من ملف تحتاج إلى تدويره.

اكتب /etc/systemd/system/wp-cron-example.service:

[Unit]
Description=Run due WordPress cron events for example.com

[Service]
Type=oneshot
User=www-data
Group=www-data
ExecStart=/usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now

ثم /etc/systemd/system/wp-cron-example.timer:

[Unit]
Description=Run WordPress cron for example.com every 5 minutes

[Timer]
OnCalendar=*:0/5
AccuracySec=30s
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now wp-cron-example.timer
systemctl list-timers wp-cron-example.timer
journalctl -u wp-cron-example.service -n 20

لن يشغّل systemd نسختين من الخدمة نفسها في الوقت ذاته، لذلك لا يحتاج هذا الإصدار إلى flock. يتيح Persistent=true تعويض تشغيل فائت أثناء إيقاف تشغيل الجهاز، وهو ما لا يستطيع إدخال crontab فعله.

اختر crontab أو المؤقت. يؤدي تشغيل كليهما للموقع نفسه إلى تفريغ قائمة الانتظار مرتين، وستظهر عمليات التشغيل المكررة لمهمة البريد الإلكتروني أو الطلبات لعملائك.

لماذا يجب ألا تُشغِّل مهمة cron بصلاحيات root

هذه أولى الطرق الثلاث التي يفشل بها الإعداد. إذا أضفت المهمة إلى crontab الخاص بـroot، يتوقف WP-CLI قبل أن ينفّذ أي شيء:

Error: YIKES! It looks like you're running this as root.

لا تعمل قائمة الانتظار، وإذا لم تكن قد أعدت توجيه المخرجات فلن ترى الرسالة. الإصلاح الخطير هو إضافة --allow-root، لأن كل ملف يكتبه أحد المكونات الإضافية أثناء ذلك التشغيل سيصبح مملوكاً لـroot. يعمل طلب الويب التالي بصلاحيات www-data، ولا يستطيع الكتابة في تلك الأدلة، ويبدأ الموقع بعرض رسائل مثل:

Unable to create directory wp-content/uploads/2026/08. Is its parent directory writable by the server?

أصلح الملكية، ثم انقل المهمة:

sudo chown -R www-data:www-data /srv/www/example.com/wp-content

يستخدم crontab الخاص بـroot وcrontab الخاص بـwww-data ملفين منفصلين، لذلك لا يؤدي حذف السطر من أحدهما إلى تعديل الآخر. تحقّق من كليهما:

sudo crontab -u root -l
sudo crontab -u www-data -l

سبب إبلاغ cron عن wp: not found

هذا هو الفشل الثاني. يوفّر cron للمستخدمين قيمة PATH قصيرة جداً، /usr/bin:/bin. ويُثبَّت WP-CLI في /usr/local/bin، وهو غير موجود في تلك القائمة. تبدأ المهمة، ثم تفشل خلال جزء من الثانية، ويحتوي السجل على سطر واحد:

/bin/sh: 1: wp: not found

اعرض بيئة cron بنفسك بدلاً من التخمين. أضف سطراً مؤقتاً:

*/5 * * * * env > /tmp/cron-env.txt 2>&1

اقرأ /tmp/cron-env.txt بعد مرور فترة واحدة، ثم احذف السطر. تكون قيمة PATH= في ذلك الملف مطابقة تماماً لما تحصل عليه مهمتك.

يوجد حلّان. استخدم المسار المطلق /usr/local/bin/wp، كما في الخطوة 3. أو عيّن PATH مرة واحدة في أعلى crontab، فوق كل سطر مهمة:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

يوجد الفخ نفسه في مستوى أدنى. يبدأ ملف wp phar بـ#!/usr/bin/env php، لذلك يجب أن يتمكن shell من العثور على php أيضاً. إذا كان PHP موجوداً خارج /usr/bin، وهو ما يحدث مع الإصدارات المبنية مخصّصاً وإصدارات لوحات التحكم، فستحصل على:

/usr/bin/env: 'php': No such file or directory

استدعِ المفسّر صراحةً في هذه الحالة، مثلاً /usr/local/bin/php /usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now.

لماذا يعيد الفاصل الزمني البالغ دقيقة واحدة المشكلة الأصلية

هذا هو الفشل الثالث. يبدو * * * * * أكثر أماناً من خمس دقائق، لكنه يعيدك إلى نقطة البداية في الموقع المزدحم. إذا استغرق أحد التشغيلات وقتاً أطول من الفاصل الزمني، يبدأ التشغيل التالي بينما لا يزال الأول قيد التنفيذ. بعد عشر دقائق، تصبح هناك عشرة عمليات PHP، تحتفظ كل منها بذاكرتها واتصالها الخاص بقاعدة البيانات.

تحقق من التراكم مباشرة:

ps -eo etimes,user,args | grep '[c]ron event run'

يمثل etimes عمر العملية بالثواني. يكون السطر الواحد طبيعياً. أما ظهور عدة أسطر بأعمار تتجاوز الفاصل الزمني بكثير فيعني أن التشغيلات تتراكم. وعلى VPS صغير، ينتهي ذلك بخطأ Too many connections من MySQL، أو بإنهاء النواة لعملية PHP لاستعادة الذاكرة، ويمكنك تأكيد ذلك باستخدام sudo dmesg -T | grep -i 'killed process'.

يشغّل WP-CLI معالجات الأحداث مباشرة بدلاً من طلب wp-cron.php، لذلك لا ينطبق قفل WordPress البالغ 60 ثانية لمنع إنشاء عمليات مكررة هنا. إن flock -n في إدخال الخطوة 3 هو ما يمنع التداخل الآن. يخرج التشغيل المتخطى فوراً وبصمت، وهذا مقصود. يجب أن تعالج التداخل في crontab، لا أن تتوقع من نواة المضيف معالجته نيابةً عنك: حتى توزيع المهام المراعي للتخزين المؤقت المضاف في Linux kernel 7.2 يحدد النواة التي تستضيف العملية فقط، ولا يحدد أبداً عدد العمليات التي بدأتها.

اختر الفاصل الزمني استناداً إلى أقصر جدول تعتمد عليه فعلياً، وقِس مدة التشغيل أولاً:

time sudo -u www-data /usr/local/bin/wp --path=/srv/www/example.com cron event run --due-now

تُعد خمس دقائق قيمة افتراضية معقولة: فالمنشور المجدول في 09:00 يُنشر بحلول 09:05. وتكفي خمس عشرة دقيقة لموقع لا يحتوي على شيء حساس للوقت. أما دقيقة واحدة فتناسب المتاجر والإضافات المعتمدة على قوائم الانتظار التي تحتاج إليها فعلاً، وفقط بعد التأكد من أن التشغيل يكتمل خلال بضع ثوانٍ.

إذا تعذّر عليك تثبيت WP-CLI

تحظر بعض الاستضافات أدوات shell. يرسل طلب HTTP عادي إلى wp-cron.php المهام نفسها، لكن عبر طبقة الويب كاملة:

*/5 * * * * /usr/bin/curl -sS --max-time 120 "https://example.com/wp-cron.php?doing_wp_cron" > /dev/null

ما تفقده، بوضوح:

  • يحد خادم الويب وPHP-FPM مدة الطلب، لذلك قد تنقطع المهمة الطويلة قبل اكتمالها.
  • يجب أن تكون الشهادة صالحة، وإلا يتوقف curl مع SSL certificate problem. لذلك احرص على استمرار التجديدات باستخدام Certbot على nginx.
  • يجب ألا تخزّن ذاكرة التخزين المؤقت للصفحات wp-cron.php، وإلا تحصل طلبات cron على استجابة مخزّنة مؤقتاً ولا يُنفَّذ شيء.
  • لا تحصل على مخرجات لكل حدث، لذلك يكون الأثر الذي تركته المهمة الدليل الوحيد على تشغيلها.

يجعل -sS الأمر curl صامتاً عند النجاح، مع الاستمرار في طباعة الأخطاء. وهذا هو السلوك المطلوب في مهمة cron.

ما الذي ينبغي أن يُدرج أيضاً في جدول مهام الخادم

بعد أن يتولى cron النظامي قائمة انتظار WordPress، أبقِ بقية المهام الدورية للخادم في المكان نفسه حتى تتمكن من رؤيتها. يجب أن تتولاها التحديثات غير التفاعلية، لا سطر cron تديره يدوياً. أما تحديثات إضافات WordPress وقوالبه فهي قرار مختلف: يمكن أن يؤدي wp plugin update --all في crontab إلى تعطيل موقع يعمل عند الساعة 3 صباحاً من دون أن يراقبه أحد، لذلك نفّذ هذه التحديثات عمداً، أو مرّرها عبر بيئة تجريبية ونسخة احتياطية.

FAQ

هل يؤدي تعطيل WP-Cron إلى إيقاف نشر المنشورات المجدولة؟

لا، ما دام هناك شيء آخر يشغّل قائمة الانتظار. DISABLE_WP_CRON يوقف فقط تشغيل قائمة الانتظار عند تحميل الصفحات. وتبقى الأحداث مجدولة تماماً كما كانت. إذا ضُبط نشر منشور على الساعة 09:00، فسيُنشر في أول تشغيل لـcron بعد الساعة 09:00. لذلك، يؤدي الفاصل الزمني البالغ خمس دقائق إلى نشره بحلول الساعة 09:05. إذا ضبطت الثابت ولم تضف إدخال cron، فسيبقى المنشور في القائمة مميزاً بـMissed schedule إلى أن يشغّل شيء ما قائمة الانتظار.

أي مستخدم يجب أن يشغّل مهمة cron الخاصة بـWordPress؟

المستخدم الذي يملك الملفات التي يكتبها PHP، وهو www-data في تثبيت Ubuntu الافتراضي. تحقّق باستخدام stat -c '%U %G' /srv/www/example.com/wp-content/uploads، وقارن النتيجة بسطر user = في إعدادات تجمع PHP-FPM. يؤدي تشغيل المهمة بصلاحيات root إلى إيقاف WP-CLI مع ظهور خطأ YIKES، بينما يؤدي فرض تشغيلها باستخدام --allow-root إلى إنشاء ملفات يملكها root داخل wp-content، ولا يستطيع خادم الويب الكتابة إليها بعد ذلك.

كم مرة يجب أن يشغّل system cron مهمة cron الخاصة بـWordPress؟

كل خمس دقائق مناسبة لمعظم المواقع. اضبط الفاصل الزمني وفق أقصر جدولة تعتمد عليها فعلياً، واجعله أطول بهامش مناسب من الوقت الذي يستغرقه تشغيل واحد. يمكنك قياس ذلك بوضع time قبل أمر WP-CLI. تؤدي الفواصل الزمنية التي تبلغ دقيقة واحدة إلى تراكب عمليات التشغيل في المواقع المزدحمة، ما لم يحْمِها flock.

لماذا يفشل wp cron test بعد تعطيل WP-Cron؟

لأن هذا الأمر يختبر تشغيل المهام الذي يطلقه الزوار، ويُبلغ عن خطأ عندما تكون قيمة DISABLE_WP_CRON مضبوطة على true. هذه هي النتيجة الصحيحة على خادم مهيأ بهذه الطريقة. تحقّق من مسار system cron بدلاً من ذلك: اقرأ /var/log/wp-cron/example.log، أو جدْول حدثاً تجريبياً باستخدام wp cron event schedule، وتأكد من اختفائه من wp cron event list بعد التشغيل التالي.

هل أحتاج إلى WP-CLI، أم يكفي استخدام curl مع wp-cron.php؟

يعمل curl، وهو الخيار المناسب عندما لا يمكنك تثبيت WP-CLI. لكنه أبطأ لأنه يحمّل WordPress عبر خادم الويب، كما أنه مقيّد بمهلة الطلب. يشغّل WP-CLI الأحداث في عملية PHP من سطر الأوامر من دون مهلة ويب، ويطبع سطراً واحداً لكل حدث مع مدته. لذلك يوضح السجل بالضبط ما الذي شُغّل وكم استغرق تشغيله.