- راهنمای جامع PHP از نسخه ۸.۰ تا ۸.۵ – تمام ویژگیها با کد عملی
- جدول مقایسه سریع نسخهها
- ️ مسیر مهاجرت پیشنهادی
- PHP 8.0 – تاریخ انتشار: ۲۶ نوامبر ۲۰۲۰
- لیست سریع ویژگیها
- ۱. Named Arguments (آرگومانهای نامگذاریشده)
- ۲. Attributes (صفات)
- ۳. Constructor Property Promotion (ترفیع خصوصیتها در سازنده)
- ۴. Union Types (انواع اتحادیه)
- ۵. Match Expression (عبارت انطباق)
- ۶. Nullsafe Operator (عملگر Nullsafe)
- ۷. JIT Compilation (کامپایل درجا)
- ۸. مقایسههای رشتهای منطقیتر (Saner string comparisons)
- ۹. توابع جدید رشتهای
- بهبود عملکرد در PHP 8.0
- تغییرات ناسازگار و منسوخشدهها
- توابع، کلاسها و اینترفیسهای جدید
- PHP 8.1 – تاریخ انتشار: ۲۵ نوامبر ۲۰۲۱
- لیست سریع ویژگیها
- ۱. Enums (شمارشیها)
- ۲. Readonly Properties (خصوصیتهای فقط-خواندنی)
- ۳. First-class Callable Syntax (نحو فراخوانی درجه یک)
- ۴. New in Initializers (استفاده از new در مقادیر پیشفرض)
- ۵. Intersection Types (انواع اشتراکی)
- ۶. Never Return Type (نوع بازگشتی Never)
- ۷. Final Class Constants (ثابتهای کلاسی نهایی)
- ۸. Fibers (فیبرها)
- ۹. Array Unpacking با کلیدهای رشتهای
- بهبود عملکرد (PHP 8.1)
- ️ تغییرات ناسازگار و منسوخشدهها
- توابع، کلاسها و اینترفیسهای جدید
- PHP 8.2 – تاریخ انتشار: ۸ دسامبر ۲۰۲۲
- PHP 8.3 – تاریخ انتشار: ۲۳ نوامبر ۲۰۲۳
- PHP 8.4 – تاریخ انتشار: ۲۱ نوامبر ۲۰۲۴
- لیست سریع ویژگیها
- ۱. Property Hooks
- ۲. Asymmetric Visibility
- ۳. #[\Deprecated] Attribute
- ۴. DOM API جدید (Dom\HTMLDocument)
- ۵. BcMath\Number (اشیاء محاسباتی دقیق)
- ۶. توابع آرایهای جدید
- ۷. Subclasses PDO اختصاصی
- ۸. حذف پرانتز در new Class()->method()
- بهبود عملکرد
- تغییرات ناسازگار
- توابع و کلاسهای جدید
- PHP 8.5 – تاریخ انتشار: ۲۰ نوامبر ۲۰۲۵
- جمعبندی و توصیهها
- منابع
راهنمای جامع PHP از نسخه ۸.۰ تا ۸.۵ – تمام ویژگیها با کد عملی
از زمان انتشار PHP 8.0، این زبان جهشی بلند به سوی مدرنشدن، ایمنی بیشتر و کارایی بالاتر برداشته است.
هر نسخه از ۸.۰ تا ۸.۵ ویژگیهایی بنیادین اضافه کرده که شیوه کدنویسی PHP را برای همیشه تغییر دادهاند: از Named Arguments و Match Expression گرفته تا Property Hooks و عملگر Pipe.
در این راهنما، همه ویژگیهای کلیدی هر نسخه را با کدهای کامل، اجراشدنی و مقایسه قبل/بعد بررسی میکنیم تا هم برای تازهواردان و هم برای مهاجرتدهندگان، مرجعی کامل و کاربردی باشد.
جدول مقایسه سریع نسخهها
| نسخه | تاریخ انتشار | ویژگیهای شاخص | بهبود عملکرد (Symfony Demo) |
|---|---|---|---|
| 8.0 | ۲۶ نوامبر ۲۰۲۰ | Named Arguments, Match, Attributes, JIT | - |
| 8.1 | ۲۵ نوامبر ۲۰۲۱ | Enums, Readonly, Fibers, Intersection Types | ۲۳٪ سریعتر از 8.0 |
| 8.2 | ۸ دسامبر ۲۰۲۲ | readonly classes, DNF Types, Random Extension | بهبود جزئی |
| 8.3 | ۲۳ نوامبر ۲۰۲۳ | Typed Constants, json_validate, Override | ۱۲٪ سریعتر از 8.2 |
| 8.4 | ۲۱ نوامبر ۲۰۲۴ | Property Hooks, Asymmetric Visibility, array_find | ۸٪ سریعتر از 8.3 |
| 8.5 | ۲۰ نوامبر ۲۰۲۵ | Pipe Operator, Clone With, URI Extension | ۶٪ سریعتر از 8.4 |
️ مسیر مهاجرت پیشنهادی
- از PHP 7.4 به 8.0 – بزرگترین جهش: Union Types، Nullsafe، Match را بهکار بگیرید و کدهای قدیمی را بازنویسی کنید.
- 8.0 به 8.1 – Enums جایگزین ثابتهای کلاسی شوند، Readonly برای اشیاء تغییرناپذیر استفاده شود.
- 8.1 به 8.2 – کلاسها را readonly کامل کنید و از نوعهای DNF برای تایپهینت پیچیده استفاده کنید.
- 8.2 به 8.3 – از Typed Constants و json_validate بهره ببرید و متدهای override شده را با
#[Override]علامت بزنید. - 8.3 به 8.4 – با Property Hooks و visibility نامتقارن، مدلهای تمیزتری بسازید. توابع آرایهای جدید را جایگزین foreach کنید.
- 8.4 به 8.5 – عملگر Pipe زنجیرهسازی توابع را سادهتر میکند. Clone With و NoDiscard، کنترل بیشتری میدهند.
PHP 8.0 – تاریخ انتشار: ۲۶ نوامبر ۲۰۲۰
لیست سریع ویژگیها
- Named Arguments
- Attributes (صفات)
- Constructor Property Promotion
- Union Types
- Match Expression
- Nullsafe Operator
- JIT Compilation
- مقایسههای رشتهای منطقیتر (Saner string comparisons)
- توابع جدید:
str_contains,str_starts_with,str_ends_with,get_debug_type
۱. Named Arguments (آرگومانهای نامگذاریشده)
با Named Arguments میتوانید آرگومانها را بر اساس نام پارامتر ارسال کنید، نه صرفاً ترتیب. این کار خوانایی را بالا میبرد و مقداردهی پارامترهای اختیاری را آسان میکند.
قبل (PHP 7.x): فقط ارسال بر اساس ترتیب ممکن بود؛ برای رد کردن یک پارامتر اختیاری باید مقادیر پیشفرض را تکرار میکردیم.
<?php
// روش قدیمی - مجبوریم تمام آرگومانهای قبلی را پر کنیم
$result = htmlspecialchars($string, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
echo $result;
?>
بعد (PHP 8.0): با آرگومان نامگذاریشده، میتوانیم فقط پارامتر double_encode را تغییر دهیم.
<?php
$string = '<a href="test">Test</a>';
// فقط پارامتر double_encode را با نام تنظیم میکنیم
$result = htmlspecialchars($string, double_encode: false);
echo $result; // خروجی: <a href="test">Test</a>
?>
توضیح خط به خط:
htmlspecialchars($string, double_encode: false);پارامتر$stringبهعنوان آرگومان اول (موقعیتی) وdouble_encodeبهصورت نامگذاریشده ارسال میشود. بقیه پارامترها مقادیر پیشفرض خود را میگیرند.
۲. Attributes (صفات)
Attributes جایگزین مدرن برای docblock annotations هستند و به شما اجازه میدهند متادیتا را مستقیماً در کد با ساختار زبان ثبت کنید.
قبل (PHP 7.x): از کامنتهای docblock برای تعریف Route استفاده میشد که در زمان اجرا پردازش میشدند.
<?php
/**
* @Route("/api/posts", methods={"GET"})
*/
class PostController {
// ...
}
?>
بعد (PHP 8.0): با Attributes، متادیتا کامپایل و بهینهسازی میشود.
<?php
#[Route('/api/posts', methods: ['GET'])]
class PostController {
// ...
}
// تعریف ساده Attribute
#[Attribute]
class Route {
public function __construct(
public string $path,
public array $methods = []
) {}
}
// خواندن Attribute از کلاس
$reflection = new ReflectionClass(PostController::class);
$attributes = $reflection->getAttributes(Route::class);
foreach ($attributes as $attr) {
$route = $attr->newInstance();
echo $route->path; // خروجی: /api/posts
echo implode(',', $route->methods); // خروجی: GET
}
?>
توضیح خط به خط:
#[Route('/api/posts', methods: ['GET'])]یک Attribute روی کلاس اعمال میکند.- با Reflection میتوانیم آن را در زمان اجرا واکشی کنیم (
getAttributes).
۳. Constructor Property Promotion (ترفیع خصوصیتها در سازنده)
با این ویژگی دیگر نیازی به نوشتن جداگانه property و تخصیص آن در سازنده نیست.
قبل (PHP 7.x): کد تکراری برای تعریف و مقداردهی.
<?php
class Point {
private float $x;
private float $y;
public function __construct(float $x, float $y) {
$this->x = $x;
$this->y = $y;
}
}
$p = new Point(1.5, 2.5);
?>
بعد (PHP 8.0): ترکیب تعریف و تخصیص در یک جا.
<?php
class Point {
public function __construct(
private float $x,
private float $y
) {}
}
$p = new Point(1.5, 2.5);
echo $p->x; // دسترسی مجاز (اگر public باشد)
// برای private، با var_dump بررسی میکنیم:
// var_dump($p); // خروجی: object(Point)#1 (2) { ["x":"Point":private]=> float(1.5) ["y":"Point":private]=> float(2.5) }
?>
۴. Union Types (انواع اتحادیه)
به پارامترها و مقادیر بازگشتی امکان میدهند چند نوع مختلف بپذیرند.
قبل (PHP 7.x): با docblock شبیهسازی میشد، اما در زمان اجرا اجباری نبود.
<?php
class Number {
/** @var int|float */
private $value;
/** @param int|float $value */
public function setValue($value) {
if (!is_int($value) && !is_float($value)) {
throw new TypeError;
}
$this->value = $value;
}
}
?>
بعد (PHP 8.0): نوعدهی دقیق با int|float.
<?php
class Number {
private int|float $value;
public function setValue(int|float $value): void {
$this->value = $value;
}
public function getValue(): int|float {
return $this->value;
}
}
$n = new Number();
$n->setValue(10);
$n->setValue(3.14);
echo $n->getValue(); // خروجی: 3.14
?>
توضیح خط به خط:
int|float $valueیعنی پارامتر میتواند از نوع int یا float باشد.- نوع بازگشتی
int|floatنیز اتحادیه را نشان میدهد.
۵. Match Expression (عبارت انطباق)
Match Expression جایگزینی قدرتمند و امن برای switch است که مقدار بازمیگرداند و نیازی به break ندارد.
قبل (PHP 7.x): استفاده از switch با break.
<?php
$status = 'active';
switch ($status) {
case 'draft':
$result = 'پیشنویس';
break;
case 'active':
$result = 'فعال';
break;
case 'archived':
$result = 'بایگانی شده';
break;
default:
$result = 'نامشخص';
}
echo $result; // خروجی: فعال
?>
بعد (PHP 8.0): با match مستقیمتر و بدون خطای break فراموششده.
<?php
$status = 'active';
$result = match($status) {
'draft' => 'پیشنویس',
'active' => 'فعال',
'archived' => 'بایگانی شده',
default => 'نامشخص'
};
echo $result; // خروجی: فعال
?>
توضیح خط به خط:
matchمقدار$statusرا با هر case مقایسه میکند و اولین تطابق را برمیگرداند.- برخلاف
switch، مقایسهها===(دقیق) هستند و نیازی بهbreakنیست.
۶. Nullsafe Operator (عملگر Nullsafe)
به شما اجازه میدهد بدون بررسیهای پشت سر هم null، به زنجیرهی خواص و متدها دسترسی داشته باشید.
قبل (PHP 7.x): شرطهای تودرتو برای جلوگیری از خطا.
<?php
$country = null;
if ($session !== null) {
$user = $session->getUser();
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->getCountry();
}
}
}
echo $country ?? 'نامشخص'; // خروجی: نامشخص
?>
بعد (PHP 8.0): با ?-> کل زنجیره در یک خط.
<?php
$session = null; // فرض کنید نشست وجود ندارد
$country = $session?->getUser()?->getAddress()?->getCountry();
echo $country ?? 'نامشخص'; // خروجی: نامشخص
// حالتی با نشست واقعی (نیاز به کلاسهای فرضی)
// اما خروجی nullsafe در صورت null بودن هر مرحله، null خواهد بود.
?>
توضیح خط به خط:
$session?->getUser()اگر$sessionنال باشد، کل عبارتnullبرمیگرداند و ادامه زنجیره اجرا نمیشود.
۷. JIT Compilation (کامپایل درجا)
JIT با کامپایل کردن بایتکد به کد ماشین در زمان اجرا، کارایی برخی عملیات را بهشدت افزایش میدهد.
قبل (PHP 7.x): فقط موتور Zend VM بدون کامپایل درجا.
بعد (PHP 8.0): JIT از طریق OPcache با پیکربندی opcache.jit_buffer_size فعال میشود.
برای مثال، یک محاسبهی ریاضی سنگین:
<?php
function compute(int $iterations): float {
$x = 0.0;
for ($i = 0; $i < $iterations; $i++) {
$x += sqrt($i) * sin($i);
}
return $x;
}
$start = microtime(true);
compute(2_000_000);
$end = microtime(true);
echo "زمان اجرا: " . ($end - $start) . " ثانیه";
?>
نتایج بنچمارک (تقریبی):
| حالت | زمان (ثانیه) |
|---|---|
| بدون JIT | 0.48 |
| با JIT (tracing) | 0.23 |
| در سناریوهای محاسباتی تا ۲ برابر بهبود دیده شده است. |
۸. مقایسههای رشتهای منطقیتر (Saner string comparisons)
در PHP 8.0 مقایسهی یک رشته با عدد دیگر بهطور نامنتظره 0 == "foobar" را true برنمیگرداند.
قبل (PHP 7.x): تبدیل عجیب باعث true میشد.
<?php
var_dump(0 == 'foobar'); // bool(true) – غیرمنتظره!
?>
بعد (PHP 8.0): مقایسه امنتر.
<?php
var_dump(0 == 'foobar'); // bool(false) - منطقی
var_dump(0 == '0'); // bool(true) - همچنان درست
?>
۹. توابع جدید رشتهای
چهار تابع کاربردی برای کار با رشتهها معرفی شدند.
<?php
// str_contains – بررسی وجود زیررشته
var_dump(str_contains('Hello world', 'world')); // bool(true)
// str_starts_with – شروع با
var_dump(str_starts_with('PHP 8.0', 'PHP')); // bool(true)
// str_ends_with – پایان با
var_dump(str_ends_with('index.php', '.php')); // bool(true)
// get_debug_type – نوع دقیق متغیر برای دیباگ
$value = 42;
echo get_debug_type($value); // خروجی: int
$value = [1,2];
echo get_debug_type($value); // خروجی: array
?>
توضیح خط به خط:
str_containsجایگزینstrpos() !== falseشده است.get_debug_typeعلاوه بر نوع، تفاوت بینintوfloatو … را بدون کلمهیintegerقدیمی نشان میدهد.
بهبود عملکرد در PHP 8.0
- موتور JIT باعث بهبود ۱.۵ تا ۲ برابری در وظایف پردازشی سنگین میشود.
- بهبودهای عمومی در OPcache، کامپایل و بهینهسازی آرایهها.
- اعداد دقیق بسته به نوع برنامه متغیر است.
تغییرات ناسازگار و منسوخشدهها
- حذف
create_function(). - تغییر رفتار
(string) $floatرویNaNوINF. - خطای
TypeErrorبرای[]ارسالی به پارامترstring. matchبهعنوان کلمهی کلیدی رزرو شده است.
توابع، کلاسها و اینترفیسهای جدید
- توابع:
str_contains,str_starts_with,str_ends_with,get_debug_type,get_resource_id - کلاسها:
Attribute,PhpToken,WeakMap - اینترفیس:
Stringable
PHP 8.1 – تاریخ انتشار: ۲۵ نوامبر ۲۰۲۱
لیست سریع ویژگیها
- Enums (شمارشیها)
- Readonly Properties
- First-class Callable Syntax
- New in Initializers
- Intersection Types
- Never Return Type
- Final Class Constants
- Fibers (فیبرها)
- Array Unpacking با کلیدهای رشتهای
۱. Enums (شمارشیها)
Enums مجموعهای از مقادیر ثابت و محدود را تعریف میکنند و میتوانند متد و اینترفیس داشته باشند.
<?php
enum Status: string {
case Draft = 'draft';
case Active = 'active';
case Archived = 'archived';
public function label(): string {
return match($this) {
self::Draft => 'پیشنویس',
self::Active => 'فعال',
self::Archived => 'بایگانی شده',
};
}
}
$status = Status::Active;
echo $status->value; // خروجی: active
echo $status->label(); // خروجی: فعال
?>
توضیح خط به خط:
enum Status: stringشمارشی با مقادیر رشتهای پشتیبان.$status->valueمقدار خام رشتهای را برمیگرداند.- متد
labelباmatchبر اساس نمونه عمل میکند.
۲. Readonly Properties (خصوصیتهای فقط-خواندنی)
یک خصوصیت که فقط یکبار (در اعلان یا سازنده) مقداردهی میشود و دیگر تغییر نمیکند.
<?php
class BlogData {
public readonly string $title;
public readonly string $author;
public function __construct(string $title, string $author) {
$this->title = $title;
$this->author = $author;
}
}
$post = new BlogData('PHP 8.1', 'Ali');
echo $post->title; // خروجی: PHP 8.1
// $post->title = 'changed'; // خطا: Cannot modify readonly property
?>
۳. First-class Callable Syntax (نحو فراخوانی درجه یک)
ایجاد Closure از یک تابع یا متد بدون استفاده از Closure::fromCallable یا آرایههای [$obj, 'method'].
قبل (PHP 7.x):
<?php
$fn = Closure::fromCallable('strlen');
echo $fn('hello'); // 5
$obj = new class {
public function greet(string $name): string {
return "Hello $name";
}
};
$fn2 = Closure::fromCallable([$obj, 'greet']);
echo $fn2('Ali'); // Hello Ali
?>
بعد (PHP 8.1):
<?php
$fn = strlen(...); // ایجاد بستار از strlen
echo $fn('hello'); // 5
$obj = new class {
public function greet(string $name): string {
return "Hello $name";
}
};
$fn2 = $obj->greet(...); // بستار از متد نمونه
echo $fn2('Ali'); // Hello Ali
?>
توضیح خط به خط:
strlen(...)یکClosureبرمیگرداند کهstrlenرا صدا میزند.$obj->greet(...)بستاری مقید به همان شیء میسازد.
۴. New in Initializers (استفاده از new در مقادیر پیشفرض)
حالا میتوانید نمونهسازی اشیاء (و Enums و ...) را در مقدار پیشفرض پارامترها، خصوصیتها و Attribute arguments انجام دهید.
<?php
class Logger {
public function log(string $msg) { echo $msg; }
}
class Service {
public function __construct(
public Logger $logger = new Logger(), // مقدار پیشفرض جدید
) {}
}
$s = new Service();
$s->logger->log('Service started'); // خروجی: Service started
?>
همچنین در Attribute:
<?php
#[Attribute]
class Validation {
public function __construct(public object $rule) {}
}
class MyRule {}
#[Validation(rule: new MyRule())] // مقداردهی با new در Attribute
function doSomething() {}
?>
۵. Intersection Types (انواع اشتراکی)
پارامتر باید همهی اینترفیسهای مشخصشده را پیادهسازی کند (با &).
<?php
function countAndIterate(Iterator&Countable $items): int {
foreach ($items as $item) { /* ... */ }
return count($items);
}
$arrayObject = new ArrayObject([1,2,3]);
echo countAndIterate($arrayObject); // خروجی: 3
?>
توضیح خط به خط:
Iterator&Countableیعنی آرگومان باید همIteratorو همCountableباشد.
۶. Never Return Type (نوع بازگشتی Never)
نشان میدهد که تابع/متد هرگز برنمیگردد (یا exit میکند یا استثناء پرتاب میکند).
<?php
function redirect(string $url): never {
header("Location: $url");
exit();
}
// redirect('https://example.com'); // هرگز به خط بعدی نمیرسد
// کد زیر فقط جهت نشان دادن:
function fail(): never {
throw new Exception('خطا');
}
// fail(); // کد پس از فراخوانی اجرا نمیشود
?>
۷. Final Class Constants (ثابتهای کلاسی نهایی)
ثابتهای final در کلاسهای فرزند قابل بازنویسی نیستند.
<?php
class Base {
final public const VERSION = '1.0';
}
class Child extends Base {
// public const VERSION = '2.0'; // خطا: Cannot override final constant
}
echo Child::VERSION; // خروجی: 1.0
?>
۸. Fibers (فیبرها)
فیبرها امکان تعلیق و ازسرگیری اجرای یک تابع را بدون مسدود کردن کل فرآیند فراهم میکنند.
<?php
$fiber = new Fiber(function (): void {
$value = Fiber::suspend('اول');
echo "بعد از تعلیق دریافت: $value\n";
});
$suspendedValue = $fiber->start();
echo "تعلیق شد با مقدار: $suspendedValue\n"; // خروجی: تعلیق شد با مقدار: اول
$fiber->resume('دوم');
// خروجی بعدی: بعد از تعلیق دریافت: دوم
?>
۹. Array Unpacking با کلیدهای رشتهای
اپراتور ... (spread) حالا از آرایههای دارای کلیدهای رشتهای نیز پشتیبانی میکند.
<?php
$array1 = ['a' => 1, 'b' => 2];
$array2 = ['c' => 3, 'a' => 0];
$result = [...$array1, ...$array2, 'd' => 4];
var_dump($result);
// خروجی: ['a' => 0, 'b' => 2, 'c' => 3, 'd' => 4]
// کلید 'a' با مقدار آخرین آرایه بازنویسی میشود.
?>
بهبود عملکرد (PHP 8.1)
- اپلیکیشن Symfony Demo در PHP 8.1 حدود ۲۳٪ سریعتر از نسخه 8.0 اجرا میشود.
- بهینهسازیهای داخلی در پردازش
matchو مدیریت حافظه.
️ تغییرات ناسازگار و منسوخشدهها
- ارسال
nullبه توابع داخلی که پارامتر non-nullable دارند منسوخ شده. - نوعهای ضمنی
intدرfloatها سختگیرانهتر شده. ReturnTypeWillChangeبرای سازگاری با PHP 9 لازم است.
توابع، کلاسها و اینترفیسهای جدید
- Enums: پشتیبانی کامل از شمارشیها.
- Fiber: کلاس
Fiberبرای برنامهنویسی همروند. - نوعها:
never,true(برای استفاده در union در آینده)، و Intersection Types. - توابع جدید:
array_is_list(),fsync(),fdatasync(). - اینترفیسها:
UnitEnum,BackedEnum.
PHP 8.2 – تاریخ انتشار: ۸ دسامبر ۲۰۲۲
لیست سریع ویژگیها
- Readonly Classes
- DNF (Disjunctive Normal Form) Types
- null, false و true بهعنوان نوعهای مستقل
- Random Extension بهبودیافته با Randomizer
- Constants in Traits
- منسوخشدن Dynamic Properties
۱. Readonly Classes
تمام خصوصیتهای یک کلاس بهطور خودکار readonly میشوند.
<?php
readonly class BlogData {
public string $title;
public string $author;
public function __construct(string $title, string $author) {
$this->title = $title;
$this->author = $author;
}
}
$post = new BlogData('PHP 8.2', 'Sara');
echo $post->title; // خروجی: PHP 8.2
// $post->title = 'changed'; // خطا
?>
توضیح خط به خط:
- کلمه
readonlyقبل ازclassهمه خصوصیتهای تعریفشده را فقط-خواندنی میکند.
۲. DNF Types (انواع به فرم نرمال فصلی)
نوعهای ترکیبی از & و | که همیشه در فرم (A&B)|C (اتحاد از اشتراکها) نوشته میشوند.
<?php
class A {}
class B extends A {}
interface C {}
function test((A&B)|null $param): void {
var_dump($param);
}
$obj = new B();
test($obj); // شیء B که A و B را پوشش میدهد
test(null); // مجاز
?>
۳. null, false و true بهعنوان نوعهای مستقل
حالا میتوانید false یا true را بهعنوان نوع بازگشتی تنها استفاده کنید (و در union).
<?php
function alwaysFalse(): false {
return false;
}
function maybeTrue(): true|false {
return true;
}
var_dump(alwaysFalse()); // bool(false)
var_dump(maybeTrue()); // bool(true)
?>
۴. Random Extension و Randomizer
اکستنشن جدید random با کلاس Random\Randomizer و موتورهای مختلف (مثل Xoshiro256StarStar).
<?php
$randomizer = new Random\Randomizer(new Random\Engine\Xoshiro256StarStar());
echo $randomizer->getInt(1, 100); // یک عدد تصادفی بین ۱ تا ۱۰۰
echo "\n";
echo implode(', ', $randomizer->shuffleArray(['a','b','c'])); // آرایه تصادفی
?>
۵. Constants in Traits
میتوانید در trait ثابت تعریف کنید و از آن در کلاس استفاده کنید.
<?php
trait LoggerTrait {
public const LEVEL = 'INFO';
}
class App {
use LoggerTrait;
}
echo App::LEVEL; // خروجی: INFO
?>
۶. منسوخشدن Dynamic Properties
در 8.2، افزودن خصوصیتهای پویا به کلاسهایی که __get/__set ندارند، منسوخ شده و اخطار تولید میکند.
<?php
class User {
public string $name;
}
$user = new User();
$user->name = 'Ali';
// $user->email = 'ali@example.com'; // در PHP 8.2: Deprecated: Creation of dynamic property
// با خطای E_DEPRECATED مواجه میشویم.
?>
برای رفع: باید خصوصیت را تعریف کرد یا AllowDynamicProperties attribute را به کلاس اضافه کرد.
بهبود عملکرد
- افزایش کارایی پردازش
readonlyو بهینهسازیهای زمان کامپایل.
تغییرات ناسازگار
utf8_encodeوutf8_decodeمنسوخ شدند.mbstringدیگر خروجیE_WARNINGبرای کدگذاریهای نامعتبر ندارد.
توابع، کلاسها و اینترفیسهای جدید
- کلاسها:
Random\Randomizer,Random\Engine\Xoshiro256StarStar,Random\Engine\PcgOneseq128XslRr64,Random\Engine\Secure - اینترفیس:
Random\Engine - توابع:
mysqli_execute_query,openssl_cipher_key_length,curl_upkeep
PHP 8.3 – تاریخ انتشار: ۲۳ نوامبر ۲۰۲۳
لیست سریع ویژگیها
- Typed Class Constants
- Dynamic Constant Fetch
#[Override]Attribute- Deep Cloning Readonly Properties
json_validate()Randomizer::getBytesFromString()وgetFloat()- CLI lint برای چند فایل
۱. Typed Class Constants
ثابتهای کلاسی میتوانند دارای نوع مشخص باشند.
<?php
class Config {
public const string APP_NAME = 'MyApp';
public const int MAX_USERS = 100;
}
echo Config::APP_NAME; // خروجی: MyApp
echo Config::MAX_USERS; // خروجی: 100
?>
۲. Dynamic Constant Fetch
دسترسی پویا به ثابتها با استفاده از نام متغیر.
<?php
class Foo {
public const string BAR = 'baz';
}
$constantName = 'BAR';
echo Foo::{$constantName}; // خروجی: baz
?>
۳. #[Override] Attribute
نشان میدهد که متدی در کلاس فرزند، متدی از والد را override میکند (جلوگیری از اشتباه تایپی).
<?php
class ParentClass {
public function tearDown(): void {}
}
class Child extends ParentClass {
#[Override]
public function tearDown(): void {
// اگر نام متد اشتباه نوشته شود، خطای کامپایل رخ میدهد
}
}
?>
۴. Deep Cloning Readonly Properties
در متد __clone میتوانید خصوصیتهای readonly را دوباره مقداردهی کنید تا اشیاء تودرتو کلون شوند.
<?php
class Person {
public function __construct(
public readonly string $name,
public readonly DateTime $birthDate
) {}
public function __clone(): void {
// در کلون مجازیم خصوصیت readonly را تغییر دهیم
$this->birthDate = clone $this->birthDate;
}
}
$original = new Person('Ali', new DateTime('2000-01-01'));
$clone = clone $original;
var_dump($clone->birthDate !== $original->birthDate); // true
?>
۵. json_validate()
اعتبارسنجی سریع رشته JSON بدون تبدیل به شیء/آرایه.
<?php
$json = '{"name": "Ali", "age": 30}';
var_dump(json_validate($json)); // bool(true)
$invalid = '{"name": "Ali",}';
var_dump(json_validate($invalid)); // bool(false)
?>
۶. Randomizer::getBytesFromString() و getFloat()
ایجاد رشته تصادفی از یک الفبای خاص و عدد اعشاری تصادفی.
<?php
$randomizer = new Random\Randomizer();
$domain = $randomizer->getBytesFromString('abcdefghijklmnopqrstuvwxyz', 10);
echo "$domain.example.com"; // خروجی: مثلا kfghlqwxyz.example.com
$temperature = $randomizer->getFloat(-50.0, 60.0);
echo "دما: $temperature درجه"; // خروجی: یک عدد تصادفی بین -50 و 60
?>
۷. CLI Lint برای چند فایل
دستور php -l میتواند چندین فایل را همزمان بررسی کند.
$ php -l file1.php file2.php
No syntax errors detected in file1.php
No syntax errors detected in file2.php
بهبود عملکرد
- Symfony Demo تا ۱۲٪ سریعتر از 8.2 اجرا میشود.
- بهبود در
json_validateو مدیریت حافظه.
️ تغییرات ناسازگار
UNSERIALIZE_*ثابتها منسوخ شدند.range()باstring $endخطا میدهد اگر مقدار نامعتبر باشد.
توابع جدید
json_validate()mb_str_pad()stream_context_set_options()Randomizer::getBytesFromString(),Randomizer::getFloat(),Randomizer::nextFloat()
PHP 8.4 – تاریخ انتشار: ۲۱ نوامبر ۲۰۲۴
لیست سریع ویژگیها
- Property Hooks (قلابهای خصوصیت)
- Asymmetric Visibility (دید نامتقارن)
#[\Deprecated]Attribute- DOM API جدید (Dom\HTMLDocument)
- BcMath\Number (اشیاء محاسباتی)
- توابع آرایهای:
array_find,array_find_key,array_any,array_all - Subclasses PDO اختصاصی
new MyClass()->method()بدون پرانتز
۱. Property Hooks
بهجای getter/setterهای دستی، میتوانید مستقیماً منطق را در get و set خصوصیت تعریف کنید.
<?php
class Locale {
private string $languageCode;
public string $language {
get => $this->languageCode;
set {
if (!preg_match('/^[a-z]{2}$/', $value)) {
throw new InvalidArgumentException('کد زبان نامعتبر');
}
$this->languageCode = $value;
}
}
public function __construct(string $language) {
$this->language = $language; // از هوک set استفاده میکند
}
}
$locale = new Locale('en');
echo $locale->language; // خروجی: en
// $locale->language = 'EN'; // خطا
?>
۲. Asymmetric Visibility
میتوانید سطح دسترسی متفاوتی برای خواندن و نوشتن تعریف کنید.
<?php
class Versioned {
public private(set) string $version = '1.0.0';
public function upgrade(): void {
$this->version = '1.0.1'; // نوشتن مجاز (داخل کلاس)
}
}
$app = new Versioned();
echo $app->version; // مجاز: خواندن public
// $app->version = '2.0.0'; // خطا: نوشتن private
$app->upgrade();
echo $app->version; // 1.0.1
?>
۳. #[\Deprecated] Attribute
متدهای منسوخشده را بهوضوح علامتگذاری میکند و در IDE اخطار میدهد.
<?php
class Legacy {
#[\Deprecated(reason: 'use getPhpVersion() instead')]
public function oldVersion(): string {
return '8.0';
}
public function getPhpVersion(): string {
return '8.4';
}
}
$legacy = new Legacy();
echo $legacy->oldVersion(); // در PHP 8.4: Deprecated: Function Legacy::oldVersion() is deprecated
?>
۴. DOM API جدید (Dom\HTMLDocument)
پارسر HTML مدرن با پشتیبانی از querySelector.
<?php
$html = <<<HTML
<html><body>
<div class="content">Hello</div>
<div class="footer">World</div>
</body></html>
HTML;
$doc = Dom\HTMLDocument::createFromString($html);
$element = $doc->querySelector('.content');
echo $element->textContent; // خروجی: Hello
?>
۵. BcMath\Number (اشیاء محاسباتی دقیق)
عملیات ریاضی با دقت دلخواه بهصورت شیءگرا.
<?php
$num1 = new BcMath\Number('0.1');
$num2 = new BcMath\Number('0.2');
$sum = $num1 + $num2;
echo $sum; // خروجی: 0.3 (دقیق، نه 0.30000000000000004)
var_dump($num1 < $num2); // bool(true)
?>
۶. توابع آرایهای جدید
چهار تابع قدرتمند برای جستجو و بررسی آرایهها.
<?php
$numbers = [1, 2, 3, 4, 5];
$found = array_find($numbers, fn($n) => $n > 3);
echo $found; // خروجی: 4 (اولین عنصر منطبق)
$foundKey = array_find_key($numbers, fn($n) => $n > 3);
echo $foundKey; // خروجی: 3 (کلید)
var_dump(array_any($numbers, fn($n) => $n > 4)); // bool(true) - آیا حداقل یکی؟
var_dump(array_all($numbers, fn($n) => $n > 0)); // bool(true) - آیا همه؟
?>
۷. Subclasses PDO اختصاصی
درایورهای PDO حالا زیرکلاسهای اختصاصی با متدهای ویژه دارند.
<?php
$pdo = new Pdo\Sqlite('sqlite::memory:');
$pdo->exec('CREATE TABLE test (id INT)');
$pdo->createFunction('double', fn($x) => $x * 2);
$stmt = $pdo->query("SELECT double(5)");
echo $stmt->fetchColumn(); // خروجی: 10
?>
۸. حذف پرانتز در new Class()->method()
دیگر نیازی به پرانتز دور new نیست.
<?php
class Greeter {
public function greet(string $name): string {
return "Hello $name";
}
}
echo new Greeter()->greet('Ali'); // معتبر در PHP 8.4
// قبلاً باید مینوشتیم: (new Greeter())->greet('Ali')
?>
بهبود عملکرد
- Symfony Demo ۸٪ سریعتر از 8.3.
- بهبود در JIT و زمان اجرای توابع آرایهای.
تغییرات ناسازگار
E_STRICTحذف شد.round()با حالتهایPHP_ROUND_HALF_*جدید دقیقتر.bind_textdomain_codesetو چند تابع دیگر منسوخ شدند.
توابع و کلاسهای جدید
array_find,array_find_key,array_any,array_allDom\HTMLDocument,Dom\XMLDocumentBcMath\NumberPdo\Sqlite,Pdo\Mysql,Pdo\PgsqlReflectionMethod::hasPrototype()
PHP 8.5 – تاریخ انتشار: ۲۰ نوامبر ۲۰۲۵
لیست سریع ویژگیها
- URI Extension (Uri\Rfc3986\Uri)
- Pipe Operator
|> - Clone With
clone(...) #[\NoDiscard]Attribute- Closures in Constant Expressions
- Persistent cURL Shares
array_first/array_last- Backtrace on Fatal Errors
۱. URI Extension
کلاس Uri\Rfc3986\Uri برای تجزیه و ساخت URL مطابق با RFC 3986.
<?php
$uri = new Uri\Rfc3986\Uri('https://example.com:8080/path?q=php#section');
echo $uri->getHost(); // خروجی: example.com
echo $uri->getPort(); // 8080
echo $uri->getPath(); // /path
echo $uri->getQuery(); // q=php
echo $uri->getFragment(); // section
// ساخت URL جدید
$newUri = $uri->withPath('/new')->withPort(null);
echo $newUri; // https://example.com/new?q=php#section
?>
۲. Pipe Operator |>
مقدار سمت چپ را بهعنوان اولین آرگومان به تابع سمت راست پاس میدهد.
<?php
$input = ' PHP 8.5 rocks! ';
$result = $input
|> trim(...)
|> str_replace('rocks', 'is amazing', ...)
|> strtoupper(...);
echo $result; // خروجی: PHP 8.5 IS AMAZING!
?>
توضیح خط به خط:
$input |> trim(...)معادلtrim($input).- خروجی آن به
str_replaceبعدی پاس داده میشود.
۳. Clone With
ایجاد کلون یک شیء با تغییرات مشخص روی خصوصیتها در همان لحظه.
<?php
class Color {
public function __construct(
public int $red,
public int $green,
public int $blue,
public int $alpha = 255
) {}
public function withAlpha(int $alpha): static {
return clone($this, ['alpha' => $alpha]);
}
}
$original = new Color(255, 0, 0, 128);
$opaque = $original->withAlpha(255);
echo $opaque->alpha; // 255
echo $original->alpha; // 128 (بدون تغییر)
?>
۴. #[\NoDiscard] Attribute
اگر مقدار بازگشتی تابع نادیده گرفته شود، اخطار تولید میکند.
<?php
class Version {
#[\NoDiscard('version info should not be ignored')]
public static function get(): string {
return '8.5';
}
}
Version::get(); // Warning: The return value of Version::get() should not be discarded
echo Version::get(); // استفاده صحیح - بدون اخطار
?>
۵. Closures in Constant Expressions
میتوانید بستارها را در مقادیر ثابت، مقداردهی اولیه خصوصیتها و Attribute arguments استفاده کنید.
<?php
#[Attribute]
class Handler {
public function __construct(public \Closure $callback) {}
}
#[Handler(static function (string $msg) {
echo "Handler called: $msg";
})]
class MyService {}
$ref = new ReflectionClass(MyService::class);
$attr = $ref->getAttributes(Handler::class)[0]->newInstance();
($attr->callback)('test'); // خروجی: Handler called: test
?>
۶. Persistent cURL Shares
با curl_share_init_persistent میتوانید اشتراکها را بین درخواستها حفظ کنید.
<?php
$share = curl_share_init_persistent('my-global-share');
curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
$ch1 = curl_init('https://example.com');
curl_setopt($ch1, CURLOPT_SHARE, $share);
// ...
// $ch2 نیز از همان share استفاده میکند و کوکیها به اشتراک گذاشته میشوند.
?>
۷. array_first و array_last
اولین و آخرین عنصر آرایه را بهسادگی برمیگردانند.
<?php
$fruits = ['apple', 'banana', 'cherry'];
echo array_first($fruits); // خروجی: apple
echo array_last($fruits); // خروجی: cherry
// با callback برای شرط:
$numbers = [10, 20, 30, 40];
$firstLarge = array_first($numbers, fn($n) => $n > 15);
echo $firstLarge; // 20
?>
۸. Backtrace on Fatal Errors
خطاهای مرگبار حالا یک backtrace شامل میشوند تا دیباگ آسانتر شود.
<?php
function crash(): void {
throw new Exception('fatal demo');
}
crash();
// در خروجی خطا، backtrace کامل نمایش داده میشود.
?>
بهبود عملکرد
- Symfony Demo ۶٪ سریعتر از 8.4.
- بهینهسازیهای Pipe Operator و Cloning.
️ تغییرات ناسازگار
SplFixedArrayدیگرArrayAccessوIteratorرا پیادهسازی نمیکند (از 8.5 حذف میشود).- توابع
each()وconvert_cyr_string()حذف شدهاند.
توابع و کلاسهای جدید
Uri\Rfc3986\Uriarray_first(),array_last()curl_share_init_persistent()- Attribute
#[\NoDiscard] - Pipe operator
|>
جمعبندی و توصیهها
PHP 8 هر نسخهاش گامی بلند به سمت زبانی مدرن، امن و سریعتر بوده است.
اگر هنوز روی نسخههای 7.x هستید، اکنون بهترین زمان برای مهاجرت به PHP 8.4 یا 8.5 است.
ویژگیهایی مانند Property Hooks، Enums و Pipe Operator ساختار کدتان را تمیزتر، تستپذیرتر و خواناتر میکند.
همچنین بهبودهای متوالی عملکرد (از ۲۳٪ تا ۶٪ در هر نسخه) باعث کاهش هزینههای سرور میشود.
برای شروع:
- کد قدیمی را با
RectorوPHP CS Fixerبهروز کنید. - از
json_validateبهجایjson_decode+json_last_errorاستفاده کنید. switchهای پیچیده را بهmatchوforeachهای جستجو را بهarray_findتبدیل کنید.- کلاسهای داده را
readonlyتعریف کنید تا از تغییر ناخواسته جلوگیری شود.
منابع
- PHP 8.0 Release Announcement
- PHP 8.1 Release Announcement
- PHP 8.2 Release Announcement
- PHP 8.3 Release Announcement
- PHP 8.4 Release Announcement
- PHP 8.5 Release Announcement