مقدمه ای در متدهای جادویی PHP
بدیهی ست که متدهای جادویی خاص زبان PHP نیستند ولی بحث ما در مورد وردپرس و به طبع آن زبان PHP و رفتار این متدها در این زبان برنامه نویسی ست.
متدهای جادویی php یکسری متدهای خاص تعریف شده درون کلاس ها هستند که در زمانهای مشخصی (در حین عملکرد یک شئ) میتوانند به صورت اتوماتیک فعال شده و روند نرمال (یا پیش فرض) پردازش را در PHP تغییر دهند.
ممکن است یک برنامه نویس با تجربه PHP کمتر با این متدها مشکلی داشته باشد . اما از آنجا که توسعه دهندگان وردپرس اغلب با توابع و ساختار این CMS درگیر هستند گاه ممکن است در استفاده از آنها با عدم توجه به خواص ویژه آنها دچار مشکلاتی شوند.
در این مقاله سعی کردیم بیشتر نکات و چالش های متد های جادوی را در مورد توسعه وردپرس بررسی نماییم.
با شناخت کافی از متدهای جادویی می توانیم رفتار یک شئ را به گونه دلخواه در شرایط خاص تغییر دهیم ، زیرا این توابع در شرایط یاد شده می توانند روند رویداد کدهای شما را تغییر می دهند.
چند نکته در مورد متدهای جادویی:
- آنها در همه کلاس ها به صورت پیش فرض تعریف شده اند و قابل حذف یا تعریف مجدد نیستند.
- از لحاظ سینتکس این متدها با دو زیر خط (__) شروع می شوند.
- در شرایط خاص به صورت خودکار فراخوانی می شوند و نیاز به فراخوانی ندارند.
- اسامی آنها رزرو شده ست و نباید در محیط PHP برای موارد دیگر استفاده شوند.
- به جز سه مورد اول (لیست فوق_تصویر_) همه متد های جادویی از نظر visibility باید به صورت عمومی (public) تعریف شوند. (در غیر اینصورت اخطار WARNING دریافت می شود.)
- در دو مورد اول (لیست فوق_تصویر_) نباید نوع خروجی (return type) ذکر شود(در PHP 8 و بعد از آن) .در غیر اینصورت خطای FETAL دریافت خواهد شد.
علاوه بر نکات عمومی فوق هر کدام نکات و کاربرد خاص خود را دارند که به برخی موارد اشاره میکنیم.
__construct()
پر استفاده ترین متد جادویست. بلافاصله بعد از ساخت هر شئ محتویات قابل اجرای آن به صورت اتوماتیک فورا اجرا می شوند. و پراپرتی های تعریف شده در آن در دسترس قرار می گیرند.
با توجه به اینکه میتوانیم از طریق پارامترها اطلاعات (data) مختلفی را به اشیاء ساخته شده از یک کلاس تزریق نماییم.
این آرگومان های متفاوت که در حین نمونه سازی (instantiation) به یک شئ پاس داده میشود باعث میشود که بتوانیم اشیاء را به دلخواه خود تغییر دهیم. (customization)
در وردپرس با استفاده از همین خصوصیت تهیه کوئری های متمایز از یک کلاس ثابت WP_QUERY مثال بسیار خوبیست .
—-
کاربرد دوم آنها تنظیم توالی رویدادهاست به طوریکه ابتدا قبل از استفاده از یک شئ برخی رویدادها مقدار دهی شده و اماده استفاده می شوند تا در مرحله بعد پس از استفاده یا هنگام صدا زدن شئ مذکور آماده باشند.
مثال این مورد ساخت و آماده سازی یک بدنه HTML و مقدار دهی آن تا در هنگام نمونه سازی آماده شود و در مرحله بعد هر زمان ککه توسعه دهنده لازم بداند هنگام اجرای کامل متدهای شئ مذکور ، مورد استفاده قرارگیرند.
برای سومین مثال در این مورد می توان به ایجاد هوک ها ی وردپرس در متد سازنده اشاره کرد ، اما هر چند می توان هوک ها را در متد های سازنده (constructor) ایجاد نمود ، اما (طبق نظر مولفین مختلف) به نظر نمی رسد این کار به دلایل مختلف روش مناسبی باشد و best practice به حساب نمیاید . زیرا کلاس را به استفاده موردی تبدیل میکند و قدرت استفاده ها ی متعدد رو از کلاس صلب می کند (reusable) . در ضمن ابهاماتی در استفاده از this$ ایجاد می نماید( به ویژه زمان unhook نمودن قلاب مذکور ). هر چند روش هایی برای حل مشکلات فوق عنوان شده است اما در کل توصیه به استفاده از قلاب ها خارج از متد های سازنده است.
__get()
__set()
به طور کلی در زبان PHP متد های سِتِر و گِتِر (setter & getter) سبب دریافت و تنظیم مقادیر پراپرتی هایی (Properties) هستند.
حال این متدهای جادویی همین اعمال را در مورد پراپرتی هایی که قابل دسترسی نیستند (inaccessible) انجام می دهند.
این متغییر های inaccessible در کلاس مذکور تعریف نشده اند یا در آن منطقه (scope) قابل دستیابی نیستند، یعنی به صورت private یا protected تعریف شده اند.
این الگو به خصوص زمانی مفید است که ما بخواهیم متغییرهایی را داخل کلاس مقدار دهی نماییم و از خارج کلاس به انها دسترسی داشته باشیم بدون اینکه بتوانیم انها را تغییر دهیم.
__sleep()
__wakeup()
__toString()
موقعیت های زیادی پیش میاید که بخواهیم خروجی یک شئ رو به صورت یک رشته نمایش دهیم. یا در موقعیت خاص به جای تولید خطا به کاربر یک رشته نمایش داده شود.
در وردپرس یک مثال مفید و پرکاربرد وقتیست که بخواهیم اطلاعاتی را به صورت شئ در دیتابیس (MYSQL) ذخیره نماییم. برای اینکار درPHP و به تبع آن وردپرس از متدهای serializing استفاده میشود .
وقتی یک شئ یا آرایه به تابع ()serialize پاس داده میشود در ابتدا و به صورت خودکار مجیک متد ()sleep__ فراخوانی و اجرا می شود. همینطور زمان اجرای تابع ()unserialize ابتدا ()wakeup__ فراخوانی و اجرا می شود.
چون فراخوانی و اجرای این متدهای جادویی به صورت خودکار انجام میشود برای جلوگیری از سواستفاده های احتمالی و ایجاد تغییرات بر روی داده ها باید محتاط بود و نکات ایمنی را در انتقال و فراخوانی اطلاعات به پایگاه داده اجرا نمود.
یک استفاده مرسوم از این متدها برای کاهش حجم اشیاء و صرفه جویی در حافظه است. مثلا زمانی که قبل از ذخیره اطلاعات نیاز به یک سری عملیات ریاضی یا محاسبات اضافیست میتوان این محاسبات را در متد جادویی انجام و تنها نتیجه در پایگاه داده ذخیره شود تا از انباشت اطلاعات غیر ضروری اجتناب شود.
یک مثال جالب و کاربردی برای این مورد مثلا میزان نرخ تبدیل یک وب سایت در یک افزونه سئو یا امثالهم است. برای به دست آوردن این نرخ تبدیل باید محاسباتی بر روی میزان بازدید و تعداد کاربرانی که عملکردی داشته اند انجام شود . می توان کلیه محاسبات در هنگام تحویل داده ها به دیتابیس در متد ()sleep__ انجام و تنها نتیجه در پایگاه داده ذخیره شود.
متدهای جادویی با استفاده کمتر در وردپرس :
__destruct()
متدهای مخرب (destruct) هنگامی که میخواهیم به عملیات یک شئ بعد از انجام عملیات مورد نظر خاتمه داد از آن استفاده می شود.
در مورد متد های مخرب باید گفت که نسبت به متد های سازنده کاربرد کمتری دارند. اما نکته مهم در مورد انها اینستکه هنگام اجرا قبل از اینکه سبب خاتمه رویدادها و متدهای نمونه ساخته شده از یک کلاس میشوند برای آخرین بار متدهای داخل نمونه را اجرا و مقادیر داخل متدها را باز میگردانند که در جای خود می تواند مورد استفاده باشد.
__invoke()
در شرایطی که یک شئ به صورت یک متد فراخوانی شود این متد جادویی به صورت خودکار فراخوانی و اجرا میشود و میتواند متغییری که ب صورت آرگومان به آن پاس داده شده را بازگرداند.
– این متد جادویی کمتر در وردپرس استفاده میشود .
__debugInfo()
این مجیک متد زمانی فعال می شود که متد var_dump بر روی ان ابجکت صدا زده شود . و می تواند مجموعه اطلاعاتی را به صورت یک آرایه به توسعه دهنده ارائه نماید. مورد استفاده آن در دیباگ است.
__isset()
__unset()
این دو متد جادویی مانند ()set__ و ()get__ فعال شدنشان با پراپرتی های inaccessible در ارتباط هستند
یعنی اگربر روی پراپرتی که به صورت public یا protected تعریف شده یا اصلا تعریف نشده است ،متد های ()isset و ()empty صدا زده شود ()isset__ به طور خود بخود فعال میشود و اگر از ()unset استفاده شود مجیک متد ()unset__ به طور خودکار فعال میگردد.
__call()
__callStatic()
این دو متد جادویی مانند ()set__ و ()get__ و __isset()یا __unset()
هستند اما به جای پراپرتی با متدهای inaccessible در ارتباط هستند و زمانی فعال میشوند که متدی که قابل دسترس نیست (یا تعریف نشده یا قابل دستیابی در آن اسکوپ نیست) صدا می شوند .
__callStatic() برای متدهای استاتیک و __call() برای سایر متدها.
توضیح انتهایی:
با توجه به اینکه هر کدام از موارد فوق با ارائه نمونه و مثال های عینی بهتر درک خواهند شد به زودی ویدیویی تکمیلی برای این مقاله تهیه و در انتها اضافه خواهد شد که مثال های عملی آنها را بهتر بازگو نماییم.
رفرنس ها:
The Ultimate Guide To Object-Oriented PHP For WordPress Developers (eBook) (last edition 2019) PHP 8.2 Dynamic Properties and Magic Methods | WP Contributor EP013 Magic Methods in PHP - Explained with Code Examples (webrewrite.com) https://phppot.com/php/php-magic-methods/ https://www.geeksforgeeks.org/what-are-magic-methods-and-how-to-use-them-in-php/ PHP Magic Methods Cheatsheet (tutsplus.com)