پشتیبانی شاخه با به‌روز بودن وصله فرق دارد

در جدول رسمی پشتیبانی که در ۲۵ اکتبر ۲۰۲۶ بررسی شد، پشتیبانی امنیتی شاخهٔ ۸٫۲ پی‌اچ‌پی تا پایان دسامبر ۲۰۲۶ ادامه دارد. نزدیک‌شدن این تاریخ برای مدیر سایت نشانهٔ برنامه‌ریزی مهاجرت است. این موضوع با شمارهٔ آخرین وصله فرق دارد؛ ممکن است شاخه هنوز پشتیبانی شود ولی نسخهٔ نصب‌شدهٔ شما وصله‌های تازه را نداشته باشد. هر دو وضعیت باید جداگانه بررسی شوند و از یک عدد نتیجهٔ کامل امنیتی نگیرید.

نخست نسخهٔ واقعی محیط اجرا و افزونه‌های بارگذاری‌شده را ثبت کنید. خروجی خط فرمان الزاماً همان مفسر سرویس وب نیست؛ میزبان می‌تواند برای خط فرمان، پردازشگر وب و هر سایت نسخه‌های متفاوت داشته باشد. ابزار نمونه فقط محیطی را گزارش می‌کند که در آن اجرا شده است. صفحهٔ نمایش اطلاعات کامل پی‌اچ‌پی را برای گرفتن این موجودی روی اینترنت عمومی منتشر نکنید، چون می‌تواند اطلاعات حساس تنظیمات را آشکار کند.

جمع‌آوری نسخهٔ واقعی و سیاست دارای تاریخ

سیاست نمونه تاریخ پایان پشتیبانی شاخه‌ها را از جدول رسمی ثبت می‌کند و مهلت بازبینی کوتاهی دارد. نتیجه می‌تواند پشتیبانی فعال، پشتیبانی امنیتی محدود یا نیاز به بازبینی باشد. شاخهٔ ناشناخته و نسخهٔ پیش‌انتشار خودکار پذیرفته نمی‌شوند. برای بسته‌های وصله‌شدهٔ توزیع لینوکس، وضعیت پشتیبانی فروشنده و گزارش امنیتی همان بسته نیز لازم است؛ جدول بالادستی به‌تنهایی قرارداد پشتیبانی توزیع را توصیف نمی‌کند.

با php php_inventory.php > php-inventory.json موجودی محیط آزمایش را ثبت کنید و سپس python check_support.py php-inventory.json را اجرا کنید. خروجی ابزار شاخه را ارزیابی می‌کند و وصله‌ای نصب نمی‌کند. اجرای python -m unittest test_support.py حالت‌های مرزی، تاریخ انقضا و شاخهٔ ناشناخته را بررسی می‌کند. اگر سیاست منقضی شد، ابتدا جدول رسمی را بخوانید و داده را بازبینی کنید؛ تغییر ساعت سیستم راه حل معتبر نیست.

پیش از مهاجرت، سازگاری افزونه‌ها، قالب‌ها، کتابخانه‌های پروژه و اتصال پایگاه داده را با نسخهٔ هدف در محیط جدا بسنجید. کدهای منسوخ، تفاوت نوع‌ها و خطاهای ثبت‌شده می‌توانند فقط در مسیرهای کم‌استفاده ظاهر شوند. ورود مدیر، بارگذاری فایل، پردازش متن فارسی و کارهای زمان‌بندی‌شده را در فهرست آزمون بگذارید. راهنمای مهاجرت هر شاخهٔ میانی را نیز بررسی کنید، خصوصاً اگر از چند نسخهٔ قدیمی عبور می‌کنید.

کدهای کامل و قابل ذخیره

چهار فایل زیر را در یک پوشه ذخیره کنید. دستورهای اجرا و بررسی در متن آمده‌اند؛ هیچ کد با سه‌نقطه جایگزین نشده است.

1. ثبت نسخه و افزونه‌های محیط اجرا

نام فایل: php_inventory.php؛ همهٔ سطرها را با همین نام ذخیره کنید.

<?php
// CLI inventory; compare separately with the actual FPM/Apache service.
$extensions = get_loaded_extensions();
sort($extensions);
echo json_encode([
    'version' => PHP_VERSION,
    'sapi' => PHP_SAPI,
    'integer_bytes' => PHP_INT_SIZE,
    'extensions' => $extensions,
    'timezone' => date_default_timezone_get(),
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), PHP_EOL;

این فایل بخشی از مثال کامل بالاست؛ ترتیب اجرا، پیش‌نیازها و محدودیت‌های نتیجه در متن مقاله توضیح داده شده است.

2. تقویم پشتیبانی با مهلت بازبینی

نام فایل: support_policy.json؛ همهٔ سطرها را با همین نام ذخیره کنید.

{
  "reviewed": "2026-10-25",
  "reviewBy": "2026-11-08",
  "source": "https://www.php.net/supported-versions.php",
  "branches": {
    "8.2": {"activeUntil": "2024-12-31", "securityUntil": "2026-12-31"},
    "8.3": {"activeUntil": "2025-12-31", "securityUntil": "2027-12-31"},
    "8.4": {"activeUntil": "2026-12-31", "securityUntil": "2028-12-31"},
    "8.5": {"activeUntil": "2027-12-31", "securityUntil": "2029-12-31"}
  }
}

این فایل بخشی از مثال کامل بالاست؛ ترتیب اجرا، پیش‌نیازها و محدودیت‌های نتیجه در متن مقاله توضیح داده شده است.

3. ارزیابی شاخه بدون نصب و تغییر

نام فایل: check_support.py؛ همهٔ سطرها را با همین نام ذخیره کنید.

import argparse
from datetime import date
import json
from pathlib import Path
import re


def assess(version, policy, today):
    if not date.fromisoformat(policy['reviewed']) <= today <= date.fromisoformat(policy['reviewBy']):
        return 'policy-needs-review'
    match = re.fullmatch(r'(\d+\.\d+)\.\d+(?:-[A-Za-z0-9.+~]+)?', version)
    if not match:
        return 'unknown-version'
    branch = policy['branches'].get(match[1])
    if branch is None:
        return 'unlisted-branch-review-official-table'
    if today > date.fromisoformat(branch['securityUntil']):
        return 'end-of-life'
    if today > date.fromisoformat(branch['activeUntil']):
        return 'security-only-plan-migration'
    return 'active-branch-check-latest-patch'


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('inventory', type=Path)
    args = parser.parse_args()
    policy = json.loads(Path(__file__).with_name('support_policy.json').read_text())
    inventory = json.loads(args.inventory.read_text(encoding='utf-8'))
    result = assess(inventory['version'], policy, date.today())
    print(json.dumps({'branchAssessment': result, 'sapi': inventory.get('sapi')}))
    raise SystemExit(0 if result.startswith('active-branch') else 1)

این فایل بخشی از مثال کامل بالاست؛ ترتیب اجرا، پیش‌نیازها و محدودیت‌های نتیجه در متن مقاله توضیح داده شده است.

4. آزمون تاریخ مرزی و نسخهٔ ناشناخته

نام فایل: test_support.py؛ همهٔ سطرها را با همین نام ذخیره کنید.

from datetime import date
import json
from pathlib import Path
import unittest
from check_support import assess


class SupportTests(unittest.TestCase):
    def setUp(self):
        self.policy = json.loads(Path(__file__).with_name('support_policy.json').read_text())
        self.today = date(2026, 10, 25)

    def test_branch_states(self):
        self.assertEqual(assess('8.2.34', self.policy, self.today), 'security-only-plan-migration')
        self.assertEqual(assess('8.5.11', self.policy, self.today), 'active-branch-check-latest-patch')
        self.assertIn('unlisted', assess('7.4.33', self.policy, self.today))

    def test_unknown_and_stale(self):
        self.assertEqual(assess('8.6.0RC3', self.policy, self.today), 'unknown-version')
        self.assertEqual(assess('8.5.11', self.policy, date(2026, 11, 9)), 'policy-needs-review')

    def test_exact_security_end_boundary(self):
        policy = {**self.policy, 'reviewBy': '2027-01-02'}
        self.assertEqual(assess('8.2.34', policy, date(2026, 12, 31)), 'security-only-plan-migration')
        self.assertEqual(assess('8.2.34', policy, date(2027, 1, 1)), 'end-of-life')


if __name__ == '__main__':
    unittest.main()

این فایل بخشی از مثال کامل بالاست؛ ترتیب اجرا، پیش‌نیازها و محدودیت‌های نتیجه در متن مقاله توضیح داده شده است.

برنامهٔ مهاجرت همراه با آزمون افزونه و سرویس وب

برای انتشار، نسخهٔ سرویس وب، تنظیمات پردازشگر و بسته‌های مورد نیاز را همراه شواهد آزمون ثبت کنید. امکان بازگشت به محیط قبلی و نسخهٔ پشتیبان داده باید آماده باشد؛ تغییر قالب داده ممکن است بازگشت صرف مفسر را ناکافی کند. پس از انتشار، نسخهٔ واقعی سرویس و خطاهای برنامه را دوباره بررسی کنید. برنامهٔ خوب ارتقا بر تاریخ پشتیبانی، وصلهٔ جاری و سازگاری خود برنامه متکی است، نه صرفاً بزرگ‌تر بودن شمارهٔ نسخه.

چک‌لیست اجرای عملی

  • نسخهٔ خط فرمان با سرویس وب جداگانه تطبیق داده شود.
  • پشتیبانی شاخه و آخرین وصله جدا بررسی شوند.
  • سیاست تاریخ‌دار پس از انقضا بازبینی شود.
  • سازگاری افزونه، داده و مسیر بازگشت آزمون شود.

منابع

تدوین و راهنمای عملی: دانشنامه لیان.