قابلیت ارتقای مشخصه سازنده در PHP – به زبان ساده


به زودی شاهد انتشار رسمی جدیدترین نسخه از زبان برنامهنویسی پیاچپی به نام PHP 8 خواهیم بود که قابلیتها و امکانات تازه زیادی را معرفی میکند. یکی از این امکانات مهم «ارتقای مشخصه سازنده» (Constructor Property Promotion) نام دارد. این قابلیت موجب میشود که بخش زیادی از کدهای تکراری که در زمان ساخت اشیای ساده مانند «اشیای مقداری» (VO) و «اشیای انتقال داده» (DTO) باید مینوشتیم، کاهش یابند. در این مقاله به توضیح قابلیت ارتقای مشخصه سازنده در PHP میپردازیم.
به طور خلاصه ارتقای مشخصه موجب میشود که بتوانیم فیلدهای کلاس، تعریف سازنده و انتسابهای متغیر را در یک ساختار منفرد در لیست پارامتر سازنده ترکیب کنیم. به این ترتیب به جای این که به روش قدیم کدی مانند زیر بنویسیم:
میتوانیم از کدی مانند زیر استفاده کنیم:
طرز کار قابلیت ارتقای مشخصه سازنده در PHP چگونه است؟
ایده اصلی این قابلیت کاملاً ساده است. ما میخواهیم همه مشخصههای کلاس، انتسابهای مقادیر و پیشوندهای پارامتر سازنده مانند public ،protected یا private را حذف کنیم.
PHP ساختار جدیدی دریافت میکند و آن را در پسزمینه پیش از اجرای عملی کد، به ساختار قدیمی تبدیل میکند.
بنابراین در ساختار جدید از کدی مانند زیر استفاده کنیم:
که جایگزین کد قدیمی زیر شده است:
توجه کنید که مقدار پیشفرض روی مشخصه کلاس تعیین نشده است، بلکه روی آرگومان متد در سازنده تعیین گشته است.
مشخصات مشخصه ارتقا یافته
در این بخش به بررسی مشخصههای این قابلیت جدید و کارهایی که میتوانیم یا نمیتوانیم با آن انجام دهیم میپردازیم. در این خصوص موارد ظریف زیادی وجود دارند که باید به آنها توجه داشته باشیم.
کاربرد صرف در سازندهها
توجه کنید که مشخصههای ارتقا یافته را تنها میتوان در سازندهها (Constructors) استفاده کرد. این موضوع شاید بدیهی به نظر برسد، اما برای روشنتر شدن موضوع لازم بود که دوباره یادآوری کنیم.
امکان استفاده از هر دو روش وجود ندارد
شما نمیتوانید یک مشخصه کلاس و یک مشخصه ارتقا یافته را با نام یکسان اعلان کنید. این موضوع منطقی هم نیست، زیرا مشخصه ارتقا یافته در عمل در زمان اجرا به مشخصه کلاس ترجمه میشود:
مشخصههای بدون نوع مجاز هستند
امکان ارتقای مشخصههای فاقد نوع وجود دارد، با این حال با توجه به رویکردهای PHP مدرن، بهتر است که هر چیزی را نوعبندی کنید.
مقادیر ساده پیشفرض
مشخصههای ارتقا یافته میتوانند مقادیر پیشفرض داشته باشند، اما عبارتهایی مانند …new مجاز نیستند.
ترکیب مشخصههای ارتقا یافته و معمولی
همه مشخصههای سازنده نباید ارتقا یابند و شما میتوانید آنها را ترکیب و تطبیق دهید.
البته در زمان ترکیب ساختارها باید هوشیار باشید، اگر این کار موجب میشود که کد روشن نباشد، بهتر است به جای آن از سازنده معمولی استفاده کنید.
دسترسی به مشخصههای ارتقا یافته از بدنه سازنده
شما مجاز به خواندن مشخصههای ارتقا یافته از بدنه سازنده هستید. این موضوع میتواند در صورت نیاز به بررسیهای اعتبارسنجی بیشتر، مفید باشد. شما میتوانید از هر دو نوع متغیرهای لوکال و متغیر وهلهای استفاده کنید و هر دو نوع به درستی کار میکنند.
کامنتهای مستندسازی روی مشخصههای ارتقا یافته
امکان افزودن توضیحهای مستندسازی به مشخصههای ارتقا یافته وجود دارد و همچنان در زمان رفلکشن در دسترس شما قرار دارند.
خصوصیتها
همانند کامنتهای مستندسازی که در بخش قبل اشاره کردیم، امکان استفاده از «خصوصیتها» (Attributes) روی مشخصههای ارتقا یافته وجود دارد. زمانی که این موارد transpile میشوند، روی هر دو نوع پارامتر سازنده و همچنین مشخصه کلاس در دسترس قرار میگیرند.
که به حالت زیر transpile میشود:
در سازندههای مجرد مجاز نیستند
شاید حتی ندانید که نوعی از سازندهها به نام «سازندههای مجرد» (Abstract Constructors) وجود دارند، اما به هر حال باید بدانید که مشخصههای ارتقا یافته روی این نوع از سازندهها مجاز نیستند.
روی خصیصهها مجاز هستند
اما از سوی دیگر امکان استفاده از مشخصههای ارتقا یافته روی «خصیصهها» (Traits) وجود دارد. این وضعیت منطقی است چون ساختار تبدیل یافته (Transpiled) نیز در خصیصهها مجاز است.
Var پشتیبانی نمیشود
توسعهدهندگان پیشکسوت و باتجربه PHP ممکن است در گذشته دور از کلیدواژه var برای اعلان متغیرهای کلاس استفاده کرده باشند. باید اشاره کنیم که امکان استفاده از آن در مشخصههای ارتقا یافته وجود ندارد. تنها کلیدواژههای مجاز شامل موارد public ،protected و private هستند.
پارامترهای نامعین (Variadic) نمیتوانند ارتقا یابند
از آنجا که نمیتوانید دادهای را به نوعی از «آرایه نوعها» (array of type) تبدیل کنید، امکان ارتقای پارامترهای نامعین نیز وجود ندارد.
در این مورد باید از ژنریکها استفاده کنیم.
Reflection برای isPromoted
هر دو گزینه ReflectionProperty و ReflectionParameter اینک دارای یک متد به نام isPromoted هستند که بررسی میکند آیا مشخصه کلاس یا پارامتر متد ارتقا یافته است.
وراثت
از آنجا که سازندههای PHP لزومی به تبعیت از اعلان سازنده والد خود ندارند، بنابراین به طور مختصر میتوان اشاره کرد که وراثت در مشخصههای ارتقا یافته مجاز است. با این حال اگر نیاز به ارسال مشخصهها از سازنده فرزند به سازنده والد باشد، باید آنها را به صورت دستی ارسال کنید:
سخن پایانی
به این ترتیب به انتهای این مقاله با موضوع مشخصههای ارتقا یافته در PHP میرسیم. استفاده از این قابلیت جدید PHP 8 موجب سهولت زیادی در فرایند کارها میشود و از این رو پیشنهاد میکنیم، آن را جایگزین روش قدیمی اعلان مشخصههای کلاس بکنید.