نسخه ی 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

در قسمت قبلی برخی از ویژگی های جدید را بررسی کردیم و در این قسمت موارد باقی مانده را تکمیل خواهیم کرد.

ارائه ی نسخه ی دوم Arrow Function ها

همانطور که می دانید در زبان PHP ساختن توابع ناشناس (anonymous functions) کار نسبتا پیچیده و سختی است و نگهداری از کدهای آن نیز زمان بر است. به همین خاطر یک RFC جدید ارائه شد که syntax جدیدی برای arrow function ها در نظر می گیرد و با استفاده از آن می توانیم کد خود را بسیار تمیز تر و ساده تر بنویسیم.

فرض کنید چنین کدی داشته باشیم:

function cube($n){
	return ($n * $n * $n);
}
$a = [1, 2, 3, 4, 5];
$b = array_map('cube', $a);
print_r($b);

این تابع یک آرگومان گرفته و آن را سه بار در خودش ضرب می کند اما ناشناس نیست و یک تابع عادی محسوب می شود. این مسئله باعث شده است تابعی بسازیم که شاید فقط یک بار از آن استفاده کنیم! با معرفی arrow function در نسخه ی 7.4 زبان PHP می توانیم کد بالا را به صورت زیر بنویسیم:

$a = [1, 2, 3, 4, 5];
$b = array_map(fn($n) => $n * $n * $n, $a);
print_r($b);

همانطور که انتظار داریم هر عضو آرایه سه بار در خودش ضرب می شود و خروجی به شکل زیر خواهد بود:

Array
(
    [0] => 1
    [1] => 8
    [2] => 27
    [3] => 64
    [4] => 125
)

همچنین در حال حاضر توابع ناشناس می توانند با استفاده از use از متغیرهایی که در scope پدرشان باشند استفاده کنند. به طور مثال:

$factor = 10;
$calc = function($num) use($factor){
	return $num * $factor;
};

همانطور که می بینید متغیر factor خارج از scope تابع است اما با use در دسترس آن قرار می گیرد. این مسئله چیز جدیدی نیست اما در arrow function های جدید در نسخه ی 7.4 زبان PHP دیگر نیازی به استفاده از use نیست و به صورت خودکار در دسترس تابع قرار می گیرند (به این موضوع implicit by-value scope binding می گوییم). بر همین اساس می توانیم کد بالا را به شکل زیر بنویسیم:

$factor = 10;
$calc = fn($num) => $num * $factor;

در این حالت خود PHP می داند که منظور شما از factor چیست، البته شما نمی توانید متغیری را که متعلق به Scope پدر است ویرایش کنید.

معرفی اپراتور Null Coalescing Assignment

همانطور که می دانید در نسخه ی 7 زبان PHP یک اپراتور جدید به نام coalesce operator معرفی شد که اپراتوری بسیار کاربردی بود. به طور مثال:

$username = $_GET['user'] ?? ‘nobody';

این کد می گوید اگر پارامتری به نام user از طریق متد GET (از طریق URL) ارسال شده بود، متغیر username را برابر مقدار این پارامتر ارسالی قرار داده و در غیر این صورت آن را برابر با رشته ی nobody قرار بده! بدون این اپراتور باید کدمان را به شکل زیر می نوشتیم:

$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

بنابراین این اپراتور بسیار کاربردی است اما اگر کد ما طولانی تر باشد چطور؟

$this->request->data['comments']['user_id'] = $this->request->data['comments']['user_id'] ?? 'value';

حتما شما هم متوجه شده اید که این کد کمی طولانی و شلوغ شده است به همین دلیل در این RFC تصمیم گرفته شد که اپراتور جدیدی به نام null coalescing assignment operator معرفی شود (علامت =??). ما با استفاده از این اپراتور جدید می توانیم کد بالا را به صورت زیر خلاصه کنیم:

یعنی اگر userid را در بخش کامنت ها داشتیم که هیچ اما اگر وجود نداشت یک مقدار پیش فرض (در کد بالا رشته ی value) را برای آن قرار بده. توجه داشته باشید که coalesce operator یک اپراتور مقایسه ای است در حالی که null coalescing assignment operator یک متغیر انتسابی می باشد.

نسخه ی دوم Typed Properties

همانطور که می دانید در زبان PHP قابلیتی به نام type hint وجود دارد که به ما اجازه می دهد نوع متغیرهای پاس داده شده به آرگومان یک تابع را مشخص کنیم. این قابلیت در نسخه ی 5 زبان PHP ارائه شده و از نسخه ی 7.2 به بعد می توانیم از آن در نوع داده های object نیز استفاده کنیم. در نسخه ی 7.4 زبان PHP این موضوع بیشتر تعمیم داده شده است و حالا می توانیم از آن ها در خصوصیات کلاس ها نیز استفاده کنیم:

class User {
	public int $id;
	public string $name;
}

این قابلیت، تمام انواع داده ها را به جز void و callable پشتیبانی می کند. ما می توانیم از این قابلیت در خصوصیات استاتیک نیز استفاده کنیم:

public static iterable $staticProp;

همچنین استفاده از آن با var نیز بدون مشکل است:

var bool $flag;

حتی اگر بخواهیم برای یک خصوصیت مقدار پیش فرض تعیین کنیم باز هم می توانیم از این قابلیت استفاده کنیم:

public string $str = "foo";

مشخصا مقدار پیش فرض باید با type (در کد بالا int) یکی باشد وگرنه با خطا مواجه می شویم. همچنین تعیین یک نوع برای چند خصوصیت هیچ مشکلی ایجاد نخواهد کرد:

public float $x, $y;

سوال: اگر نوع داده را مشخص کنیم اما از آن پیروی نکنیم چه اتفاقی می افتد؟

پاسخ: این کار باعث ایجاد یک fatal error و توقف کامل برنامه می شود.

به مثال زیر توجه کنید:

class User {
	public int $id;
	public string $name;
}

$user = new User;
$user->id = 10;
$user->name = [];

در مثال بالا برای نام کاربر نوع داده ی string یا رشته را تعیین کرده ایم اما در هنگام ساخت یک شیء از این کلاس، نام را یک آرایه قرار داده ایم که باعث خطای زیر خواهد شد:

Fatal error: Uncaught TypeError: Typed property User::$name must be string, array used in /app/types.php:9

معرفی کلاس WeakReference

در نسخه ی 7.4 زبان PHP یک کلاس جدید به نام WeakReference ایجاد شده است که به کاربران اجازه می دهد که یک reference به شیء خاصی داشته باشند و در عین حال بتوانند آن را حذف کنند. در واقع این نوع از reference ها جلوی حذف شیء را نمی گیرند. مثال:

$object = new stdClass;
$weakRef = WeakReference::create($object);

var_dump($weakRef->get());
unset($object);
var_dump($weakRef->get());

خروجی اولین var_dump به شکل زیر است:

object(stdClass)#1 (0) {}

خروجی دومین var_dump نیز مقدار NULL خواهد بود بنابراین مطمئن می شویم که reference ما حذف شده است.

معرفی Preloading

این ویژگی جدید که پیشنهاد آقای Dmitry Stogov است از ویژگی های بسیار محبوب همه شده است چرا که سرعت و عملکرد برنامه ها را بالا می برد. همانطور که می دانید از نسخه ی 5.5.0 زبان PHP قابلیتی به نام OPCache به زبان PHP اضافه شده است. OPCache باعث می شود که bytecode های از قبل کامپایل شده ی یک اسکریپت را در حافظه ی اشتراکی (shared memory) ذخیره شود تا دیگر نیازی به بارگذاری و تجزیه ی اسکریپت ها برای هر درخواست نباشد. ویژگی جدید Preloading کاری می کند که کتابخانه ها و فریم ورک ها در مرحله ی module initialization (یکی از lifecycle های زبان PHP) درون OPCache بارگذاری شوند. خود آقای Dmitry می گوید:

On server startup – before any application code is run – we may load a certain set of PHP files into memory – and make their contents “permanently available” to all subsequent requests that will be served by that server. All the functions and classes defined in these files will be available to requests out of the box, exactly like internal entities.

ترجمه:

هنگام بالا آمدن سرور – قبل از اینکه هیچ کدی اجرا شود – ممکن است برخی از فایل های PHP را در مموری بارگذاری کنیم و محتوای آن ها را برای تمام درخواست های بعدی در دسترس سرور قرار دهیم. تمام کلاس ها و توابعی که در این فایل ها تعریف شده اند بدون فرآیند بارگذاری قابل دسترس تمام درخواست های بعدی خواهند بود، دقیقا مانند internal entity ها.

این قابلیت در فایل php.ini و توسط دستور opcache.preload کنترل می شود. این دستور مشخص می کند که یک اسکریپت خاص کامپایل شده و در هنگام راه اندازی سرور اجرا شوند. این فایل می تواند فایل های دیگری را که در آن include شده اند نیز preload کنند. البته خودتان نیز می توانید با استفاده از تابع ()opcache_compile_file آن ها را وارد کنید. برای اطلاعات بیشتر به صفحه ی رسمی وب سایت PHP مراجعه کنید.

البته نکته ی منفی نیز وجود دارد. بر اساس گفته ی RFC:

preloaded files remain cached in opcache memory forever. Modification of their corresponding source files won’t have any effect without another server restart.

یعنی فایل هایی که در opcache توسط ما preload شوند تا همیشه در حافظه باقی خواهند ماند و ویرایش سورس فایل آن ها هیچ تاثیری نخواهد داشت مگر آنکه سرور دوباره راه اندازی و ریستارت شود.

موارد دیگر

ویژگی های دیگری مانند معرفی مکانیسم جدید برای serialize کردن (توابع serialize و unserialize)، کم کردن اولویت اپراتور . نسبت به + و - و همچنین مشخص کردن عبارات پیچیده در اپراتور ternary نیز در نسخه ی 7.4 معرفی شده اند که می توانید به دنبال آن ها بروید. من سعی کردم مهم ترین موارد را برایتان ذکر کنم تا برای کار با نسخه ی 7.4 آماده باشید!

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

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

ممدرضا
22 آبان 1398
آقا نوکرم خیلی باحالی

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

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

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