# Arrays
# Destructuring 7.1
میتوانید با شکستن یک آرایه، مقادیر آن را در متغیرهای جداگانهای قرار دهید:
$array = [1, 2, 3];
// Using the list syntax:
list($a, $b, $c) = $array;
// Or the shorthand syntax:
[$a, $b, $c] = $array;
همچنین میتوانید از برخی المنتها چشمپوشی کنید:
[, , $c] = $array;
// $c = 3
همچنین میتوانید از کلیدها برای این کار استفاده کنید:
$array = [
'a' => 1,
'b' => 2,
'c' => 3,
];
['c' => $c, 'a' => $a] = $array;
# Rest and Spread Operators 5.6
مقادیر یک آرایه میتواند در یک فانکشن پخش شود:
$array = [1, 2];
function foo(int $a, int $b) { /* … */ }
foo(...$array);
فانکشنها میتوانند سایر متغیرها را با همان عملگر ... دریافت کنند:
function foo($first, ...$other) { /* … */ }
foo('a', 'b', 'c', 'd', …);
این پارامترها از Hint Typing هم پشتیبانی میکنند:
function foo($first, string ...$other) { /* … */ }
foo('a', 'b', 'c', 'd', …);
$a = [1, 2];
$b = [3, 4];
$result = [...$a, ...$b]; // [1, 2, 3, 4]
# Attributes 8.0
میتوانید با #[Attribute]
ویژگی سفارشی خود را بسازید!
#[Attribute]
class ListensTo
{
public string $event;
public function __construct(string $event)
{
$this->event = $event;
}
}
میتوانید ویژگیها را به پراپرتیها، کلاسها (بینام = Anonymous)، توابع، ثوابت، closureها و آرگومانهای توابع اضافه کنید:
#[
Route(Http::POST, '/products/create'),
Autowire,
]
class ProductsCreateController
{
public function __invoke() { /* … */ }
}
از reflection
برای گرفتن آنها استفاده کنید. میتوانید برای فیلترکردن نتیجه، آرگومانهای اختیاری را به getAttributes
ارائه دهید:
$attributes = $reflectionClass->getAttributes(
ContainerAttribute::class,
ReflectionAttribute::IS_INSTANCEOF
);
# Cosmetics
# Class Names 8.0
در PHP8 میتوانید از ::class
بر روی آبجکتها استفاده کنید:
Order::class;
$object::class;
# Numeric Values 8.0
از _
برای قالببندی دادههای عددی استفاده کنید:
$price = 100_10;
// $100 and 10 cents
# Trailing Commas 8.0
کاماهای پایانی میتوانند در جاهای مختلفی استفاده شوند:
- آرایهها
- فراخوانی توابع
- تعریفکردن توابع
- عبارت
use
در Closureها
# Exceptions 8.0
از این به بعد میتوانید از throw
در جاهای زیادی استفاده کنید:
$error = fn($message) => throw new Error($message);
$input = $data['input'] ?? throw new Exception('Input not set');
همچنین دیگر مجبور نیستید که استثنا را از طریق یک متغیر بگیرید:
try {
// …
} catch (SpecificException) {
throw new OtherException();
}
# Match 8.0
شبیه switch
, اما قدرتمندتر؛ دیگر به
break
نیازی نیست، شرطهای مرکب میسازیم و یک مقدار را به عنوان خروجی دریافت میکنیم:
$message = match ($statusCode) {
200, 300 => null,
400 => 'not found',
500 => 'server error',
default => 'unknown status code',
};
# Dealing with null
# Null Coalescing 7.0
وقتی یک پراپرتی null
بود، از این طریق میتوانید جایگزینی برای آن تعیین کنید:
$paymentDate = $invoice->paymentDate ?? Date::now();
با مقادیر تودرتو هم کار میکند:
$input = $data['few']['levels']['deep'] ?? 'foo';
میتوانید از عملگر null coalescing assignment
استفاده کنید تا اگر متغیر اصلی null بود، مقدار جایگزین در هردو نوشته شود:
$temporaryPaymentDate = $invoice->paymentDate ??= Date::now();
// $invoice->paymentDate is now also set
# Nullsafe Operator 8.0
متدهای زنجیرهوار که در آنها احتمال null
آمدن وجود دارد را ایمن نگه دارید:
$invoice
->getPaymentDate()
?->format('Y-m-d');
زنجیرهی متدها، متدهای متعددی را بیاورید:
$object
?->methodA()
?->methodB()
?->methodC();
# Named Arguments 8.0
بدون اهمیتدادن به جای آرگومانها، از نام استفاده کنید:
setcookie(
name: 'test',
expires: time() + 60 * 60 * 2,
);
همچنین میتوانید از array spreading
نیز استفاده کنید:
$data = [
'name' => 'test',
'expires' => time() + 60 * 60 * 2,
];
setcookie(...$data);
# Performance
# The JIT 8.0
با مشخصکردن buffer size
در تنظیمات ini، JIT را فعال کنید. همچنین میتوانید بین دو مد function
و tracing
به آسانی تغییر حالت دهید:
opcache.jit_buffer_size=100M
opcache.jit=function
; opcache.jit=tracing
# Preloading 7.4
opcache.preload
را به تنظیمات ini اضافه کنید:
opcache.preload=/path/to/project/preload.php
هر فایلی که در اسکریپت preloading.php فراخوانی شده باشد، تا زمانی که سرور ریستارت نشود، در حافظه preload خواهد شد.
# Property Promotion 8.0
از پیشوندهای public
، protected
و private
استفاده کنید تا به عنوان پراپرتی کلاس تعریف شوند:
class CustomerDTO
{
public function __construct(
public string $name,
public string $email,
public DateTimeImmutable $birth_date,
) {}
}
هنوز هم میتوانید بدنهی constructor را اضافه کنید و دو نوع promoted و غیر promoted را در پراپرتیهایتان داشته باشید:
class MyClass
{
public string $b;
public function __construct(
public string $a,
string $b,
) {
assert($this->a !== 'foo');
$this->b = $b;
}
}
# Short Closures 7.4
Closureهای کوتاه، به فضای بیرون از scope خود دسترسی دارند و تنها اجازهی یک عبارت را میدهند که به طور خودکار return خواهد شد:
array_map(
fn($x) => $x * $this->modifier,
$numbers
);
# Types
# Built-in Types
طی انتشار نسخههای PHP 7.x و PHP 8، چندین نوع دادهای اضافه شده است:
-
نوع
void
: به این معنا که چیزی return نشده است 7.1 -
نوع
static
: کلاس فعلی یا فرزند آن را نشان میدهد 8.0 -
نوع
object
: هرچیزی که یک Object باشد 7.2 -
نوع
mixed
: همهچیز 8.0
# Typed properties 7.4
به پراپرتیهای کلاس خود، نوع دادهای را هم اضافه کنید:
class Offer
{
public ?string $offerNumber = null;
public Money $totalPrice;
}
مراقب حالت مقداردهی نشده یا uninitialized
باشید؛ این حالت در هنگام خواندن یک پراپرتی بررسی میشود، نه وقتی که از کلاسی نمونه میسازید:
$offer = new Offer();
$offer->totalPrice; // Error
# Union Types 8.0
چندین نوع دادهای را با هم ترکیب کنید؛ به این معنا که ورودی باید موافق یکی از این انواع باشد:
interface Repository
{
public function find(int|string $id);
}