نسخه ی 7.4 زبان PHP به زودی ارائه خواهد شد (قسمت اول)

19 آبان 1398
نسخه ی 7.4 زبان PHP به زودی ارائه خواهد شد

نسخه ی 7.4 زبان PHP به زودی ارائه خواهد شد (قسمت اول)

بر اساس اعلام های رسمی، نسخه ی 7.4 زبان PHP به زودی در 28 نوامبر سال 2019 (پایان همین ماه) ارائه خواهد شد بنابراین به نظرم خوب است که به ویژگی های جدید و حذفیات آن نگاهی بیندازیم. تاریخ های اعلام شده برای این بروزرسانی به صورت زیر هستند:

  • ششم ژوئن: انتشار PHP 7.4 Alpha 1
  • 18 جولای: انتشار PHP 7.4 Beta 1 – Feature freeze
  • 28 نوامبر: انتشار PHP 7.4 GA

ما انتظار داریم که با ارائه ی این بروز رسانی PHP از قبل سریع تر و قوی تر شود اما با همه ی این اوصاف قدرت اصلی PHP در نسخه ی 8 آن نمایان خواهد شد. در این نسخه قرار است JIT در PHP پیاده سازی شود که تغییر اصلی را ایجاد خواهد کرد. در واقع JIT مخفف Just In Time است و کاری که می کند کامپایل کردن قسمت هایی از سورس کد شما هنگام runtime است. همانطور که می دانید PHP زبانی است که کامپایل نمی شود و مفسر دارد (یعنی کدهای شما خط به خط برای CPU تفسیر و ترجمه می شود) اما با استفاده از JIT می توانیم قسمت هایی از کد را کامپایل کنیم بنابراین سرعت اجرا بسیار بالاتر می رود (دقیقا مانند اینکه قسمت هایی از سورس کد ما برای CPU کش شده باشد) اما تا انتشار نسخه ی 8 زمان زیادی باقی مانده است و ما فعلا بحث خود را روی PHP 7.4 محدود می کنیم.

اضافه شدن اپراتور spread به آرایه ها

همانطور که می دانید از نسخه ی 5.6 زبان PHP قابلیتی به نام Argument Unpacking وجود داشته است که کار آن باز کردن آرایه ها و Traversables (گردش پذیر) ها به صورت لیستی از آرگومان ها است. برای باز کردن یک آرایه باید مانند مثال زیر سه نقطه قبل از آن قرار بدهیم:

function test(...$args) { var_dump($args); }
test(1, 2, 3);

خروجی این کد اعداد 1 و 2 و 3 خواهند بود. این ویژگی تنها برای آرگومان های توابع قابل دسترس بود اما نسخه ی 7.4 زبان PHP آن را به آرایه ها نیز تعمیم می دهد. مثال:

$arr = [...$args];

به طور مثال فرض کنید که بخواهیم دو آرایه ی زیر را در هم ادغام کنیم یا به زبان دیگر آرایه ی اول را درون آرایه ی دوم قرار دهیم:

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];

خروجی این کد مقدار زیر خواهد بود:

// ['banana', 'orange', 'apple', 'pear', 'watermelon'];

همانطور که می بینید با استفاده از این اپراتور توانسته ایم موارد را از آرایه ی اول گرفته و در آرایه ی دوم قرار دهیم. قبل از معرفی این ویژگی برای آرایه ها باید از تابع Array_merge استفاده می کردیم تا دو آرایه را در هم ادغام کنیم. مزیت استفاده از این اپراتور در آرایه ها بالا رفتن سرعت برنامه است. در واقع صفحه ی RFC توضیح می دهد که:

Spread operator should have better performance than array_merge. That’s not only because the spread operator is a language structure while array_merge is a function, but also because compile time optimization can be performant for constant arrays.

به عبارت دیگر سرعت spread operator (به معنی «اپراتور پخش») از دو جهت از سرعت array_merge بیشتر خواهد بود:

  • array_merge یک تابع است در حالی که اپراتور spread یک ساختار زبانی (language structure) است بنابراین سریع تر اجرا خواهد شد.
  • بهینه سازی های زمان کامپایل برای آرایه های ثابت اجرا خواهند شد.

همچنین مزیت دیگر این اپراتور این است که می تواند روی هر شیء قابل گردش (traversable) اجرا شود در حالی که array_merge تنها روی آرایه ها کار می کند.

بنابراین اگر کد زیر را داشته باشیم:

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);

و آن را در نسخه ی 7.3 زبان PHP اجرا کنیم، خروجی زیر را می گیریم:

Parse error: syntax error, unexpected '...' (T_ELLIPSIS), expecting ']' in /app/spread-operator.php on line 3

در حالی که اجرای آن در نسخه ی 7.4 خروجی زیر را برمی گرداند:

array(5) {
	[0]=>
	string(6) "banana"
	[1]=>
	string(6) "orange"
	[2]=>
	string(5) "apple"
	[3]=>
	string(4) "pear"
	[4]=>
	string(10) "watermelon"
}

همچنین صفحه ی RFC توضیح می دهد که با استفاده از این اپراتور اجازه داریم یک آرایه را چندین بار گسترش دهیم. علاوه بر این اجازه داریم که از اپراتور spread در هر قسمتی از آرایه استفاده کنیم. در ضمن هیچ اهمیتی ندارد که آرایه هایمان را با استفاده از براکت های [] یا کلیدواژه ی array بسازیم. به طور مثال:

$arr1 = [1, 2, 3];
$arr2 = [...$arr1];
$arr3 = [0, ...$arr1];
$arr4 = array(...$arr1, ...$arr2, 111);
$arr5 = [...$arr1, ...$arr1];

به نظر شما اگر از آرایه های بالا خروجی بگیریم، مقدار چیست؟ سعی کنید خودتان به جواب برسید سپس جواب خود را به پاسخ آن مقایسه کنید:

$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; //[1, 2, 3]
$arr3 = [0, ...$arr1]; //[0, 1, 2, 3]
$arr4 = array(...$arr1, ...$arr2, 111); //[1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; //[1, 2, 3, 1, 2, 3]

ساده بود، مگر نه؟

همچنین شما اجازه دارید که آرایه های برگردانده شده توسط یک تابع را مستقیما در یک آرایه ی دیگر گسترش دهید:

function buildArray(){
	return ['red', 'green', 'blue'];
}
$arr1 = [...buildArray(), 'pink', 'violet', 'yellow'];

اگر کد بالا در نسخه ی 7.4 زبان PHP اجرا شود خروجی زیر را برمی گرداند:

array(6) {
	[0]=>
	string(3) "red"
	[1]=>
	string(5) "green"
	[2]=>
	string(4) "blue"
	[3]=>
	string(4) "pink"
	[4]=>
	string(6) "violet"
	[5]=>
	string(6) "yellow"
}

همچنین حتی اگر از  generator syntax استفاده کنید می توانید اپراتور Spread را برای آن پیاده سازی کنید:

function generator() {
	for ($i = 3; $i <= 5; $i++) {
		yield $i;
	}
}
$arr1 = [0, 1, 2, ...generator()];

البته حواستان باشد که اجازه ی گسترس آرایه های pass by reference را نخواهید داشت:

$arr1 = ['red', 'green', 'blue'];
$arr2 = [...&$arr1];

با اجرای کد بالا خطای زیر را دریافت می کنید:

Parse error: syntax error, unexpected '&' in /app/spread-operator.php on line 3

البته در صورتی که عناصر آرایه ی اول بر اساس reference ذخیره شده باشند، در آرایه ی نهایی (دوم) نیز بر اساس reference خواهند بود. به مثال زیر توجه کنید:

$arr0 = 'red';
$arr1 = [&$arr0, 'green', 'blue'];
$arr2 = ['white', ...$arr1, 'black'];

با اجرا کردن کد بالا و خروجی گرفتن از تابع دوم، پاسخ زیر به ما داده می شود:

array(5) {
	[0]=>
	string(5) "white"
	[1]=>
	&string(3) "red"
	[2]=>
	string(5) "green"
	[3]=>
	string(4) "blue"
	[4]=>
	string(5) "black"
}

بنابراین مقدار red در آرایه ی دوم هم از نوع pass by reference است.

در قسمت بعدی موارد باقی مانده را بررسی خواهیم کرد.

نویسنده شوید
دیدگاه‌های شما (2 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سید سجاد
19 آبان 1398
واقعا از انتشار این مطالب به روز لذت می برم. حتی قبل از اینکه یک نسخه رلیس بشه گذاشتینش عالیه

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امیر زوارمی
23 آبان 1398
سلام دوست عزیز، خوشحالم که توجه شما رو جلب کرده!

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سجاد
17 آبان 1398
خیلی خیلی ممنون بابت زحماتتون و اینکه مطالب به روز منتشر میکنید

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امیر زوارمی
23 آبان 1398
سلام دوست عزیز شما لطف دارید

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.