Trait در PHP 5.4

اسفند ۱۳, ۱۳۹۰ توسط : سعید

یکی از امکانات اضافه شده در php نسخه ۵٫۴ trait ها هستند.trait ها مشکل ارث بری چندگانه رو در پی اچ پی حل میکنن.تا قبل از این در پی اچ پی فقط میتونستیم از interface چندگانه استفاده کنیم اما در PHP 5.4 این محدودیت به وسیله trait حذف شد.

اساس کار traitبالا بردن قابلیت استفاده مجدد از کدهاست.در زبان برنامه نویسی مثل PHP که از ارث بری چندگانه پشتیبانی نمیکنه خیلی مفیده و میتونه reusability کدهارو بالا ببره و امکاناتی شبیه به ارث بری چندگانه رو در پی اچ پی در اختیار برنامه نویسان قرار بده.

چگونه از trait استفاده کنیم ؟

trait با کلمه کلیدی trait تعریف میشه :

trait first_trait
 {
 function first_method() { /* Code Here */ }
 function second_method() { /* Code Here */ }
 }

دقت کنید که trait ها رو نمیشه با استفاده از کلیمه کلیدی new مورد استفاده قرار داد .

برای استفاده از trait در کلاس مورد نظر از کلمه کلیدی use استفاده میکنیم :

 class first_class
   {
     // Using the Trait Here
     use first_trait;
   }

   $obj = new first_class();

   // Executing the method from trait
   $obj->first_method(); // valid
   $obj->second_method(); // valid
 

با استفاده از کلمه کلیدی use تونستیم trait مورد نظر رو در کلاس استفاده کردیم و میبینیم بعد از ایجاد یک نمونه از کلاس به متدهای داخل trait دسترسی داریم.

استفاده از چند trait

ما میتونیم از چند trait در یک کلاس استفاده کنیم.این امکان مانند ارث بری چندگانه عمل میکنه.

 trait first_trait
   {
     function first_method() { echo "method1"; }
   }

   trait second_trait
   {
     function second_method() { echo "method2"; }
   }

   class first_class
   {
     // now using more than one trait
     use first_trait, second_trait;
   }

   $obj= new first_class();

   // Valid
   $obj->first_method(); // Print : method1

   // Valid
   $obj->second_method(); // Print : method2
 

بعد از استفاده از دو trait در داخل کلاس first_class به متدهای هر دو trait دسترسی خواهیم داشت.

استفاده از یک trait در trait دیگر

یکی از قسمتهای جالب trait اینه که ما میتونیم داخل یک trait از یک trait دیگه استفاده کنیم.میشه گفت ارث بری در trait ها :

 trait first_trait
   {
     function first_method() { echo "method1"; }
   }

   trait second_trait
   {
     use first_trait;
     function second_method() { echo "method2"; }
   }

   class first_class
   {
     // now using
     use second_trait;
   }

   $obj= new first_class();

   // Valid
   $obj->first_method(); // Print : method1

   // Valid
   $obj->second_method(); // Print : method2
 

متدهای Abstract در trait

در trait ما میتونیم متدهای abstract تعریف کنیم.بعد از تعریف متد abstract در trait باید متد مورد نظر در کلاسی که از trait استفاده میکنه هم تعریف بشه. دقیقن مثل کلاسهای abstract :

 trait first_trait
   {
     function first_method() { echo "method1"; }
     // any class which use this trait must
     // have to implement below method.
     abstract public function second_method();
   }

   class first_method
   {
     use first_trait;

     function second_method()
     {
       /* Code Here */
     }
   }
 

تصادم در trait

هنگامی که از چند trait در یک کلاس استفاده میکنیم ممکنه متدهای پباده سازی شده در trait ها با هم همنام باشن که در این صورت با یک خطا مواجه خواهیم شد.

برای حل این مشکل با استفاده از کلمه کلیدی insteadof میتونیم به کامپایلر بفهمونیم که از کدام متد در کدام trait استفاده کنه.

 trait first_trait
   {
     function first_function()
     {
       echo "From First Trait";
     }
   }

   trait second_trait
   {
     function first_function()
     {
       echo "From Second Trait";
     }
   }

   class first_class
   {
     use first_trait, second_trait
     {
       // This class will now call the method
       // first function from first_trait only
       first_trait::first_function insteadof second_trait;
     }
   }

   $obj = new first_class();
   // Output: From First Trait
   $obj->first_function();
 

در دو trait تعریف شده یک متد با نام first_function تعریف شده.پس از استفاده از دو trait در خط :

 first_trait::first_function insteadof second_trait;
 

به کامپایلر میگیم که متد first_function از first_trait مد نظر ما هست.با این کار دیگه دسترسی به متد first_function در second_trait نخواهیم داشت.در صورتی که ما به دو تا متد در دو trait نیاز داشته باشیم باید چه کار کنیم؟

با استفاده از کلمه کلیدی as میتونیم یک نام مجازی به تابع first_function در second_trait بدیم.

 trait first_trait
   {
     function first_function()
     {
       echo "From First Trait";
     }
   }

   trait second_trait
   {
     function first_function()
     {
       echo "From Second Trait";
     }
   }

   class first_class
   {
     use first_trait, second_trait
     {
       // This class will now call the method
       // first function from first_trait only
       first_trait::first_function insteadof second_trait;

       // first_function of second_traits can be
       // accessed with second_function
       second_trait::first_function as second_function;

     }
   }

   $obj = new first_class();
   // Output: From First Trait
   $obj->first_function();

   // Output: From Second Trait
   $obj->second_function();
 

در خط زیر :

 second_trait::first_function as second_function;
 

یک نام مجازی به متد first_function دادیم با نام second_function که بعد از این هر جا از متد second_function استفاده کنیم در حقیقت از متد first_function از second_trait داریم استفاده میکنیم.

نکاتی در مورد trait

– با استفاده از کلیمه کلیدی new استفاده نمیشن

– میتونن در trait های دیگه استفاده بشن

– در یک کلاس میشه از چند trait استفاده کرد

– از final , static , abstract پشتیبانی میکنه

– با استفاده از کلمات کلیدی insteadof , as میتونیم مشکلات تصادم یا همنام بودن متدهارو حل کرد.

 

منبع : http://www.xpertdeveloper.com/2011/11/trait-in-php/

ترجمه : سعید مقدم زاده

بازدید : ۳۴۶۳

حسین
اسفند ۱۴, ۱۳۹۰ @ ۱:۰۹ ق.ظ

عالی بود / خسته نباشی

اون نکته آخر هم در مورد اینکه php 5.4 هنوز stable نیست رو هم دیگه بهتره حذف کنین

پاسخ دادن
    سعید
    اسفند ۱۴, ۱۳۹۰ @ ۵:۲۰ ق.ظ

    ممنون
    ویرایش کردم 🙂

    پاسخ دادن
اسفند ۱۵, ۱۳۹۰ @ ۵:۲۲ ق.ظ

مطلب خوبی بود

ممنون

پاسخ دادن
    سعید
    اسفند ۲۳, ۱۳۹۰ @ ۵:۱۳ ق.ظ

    خواهش میکنم

    پاسخ دادن
علیرضا
اسفند ۲۴, ۱۳۹۰ @ ۳:۰۲ ق.ظ

سعید عالی بود. ولی میدونی ، من آدم تجربی هستم یعنی باید تجربه کنم تا تو مغزم بشینه. هنوز هم نیازمند این نشدم که تجربه اش کنم ولی برای شروع یک سوال می کنم ، ممنون میشم بهش پاسخ بدی.
۱٫ من قبل از ارائه این نسخه ، هرکاری می کردم از پراپرتی ها و متد های یک کلاس در کلاس دیگه بصورت شیء گرایی ایجاد کنم امکان پذیر نبود. آیا این trait همین کارو برای من انجام میده؟

پاسخ دادن
    سعید
    اسفند ۲۴, ۱۳۹۰ @ ۱۰:۲۱ ق.ظ

    خواهش میکنم علیرضا جان.
    trait همینطور که در بالا گفتم به منظور ایجاد قابلیت ارث بری چند گانه است.
    منظورت رو از”هرکاری می کردم از پراپرتی ها و متد های یک کلاس در کلاس دیگه بصورت شیء گرایی ایجاد کنم امکان پذیر نبود” رو متوجه نشدم.
    اگر میخوای از متدها و پروپرتی های یک کلاس در خارج از کلاس استفاده کنی باید به صورت public تعریف بشن.
    (اگر منظورت این نبود بیشتر توضیح بده.)

    موفق باشی.

    پاسخ دادن
تیر ۱۵, ۱۳۹۴ @ ۱۰:۳۲ ب.ظ

مرسی خیلی عالی بود .
واقعا دمت گرم

پاسخ دادن
بهزاد
تیر ۲۲, ۱۳۹۵ @ ۸:۴۳ ق.ظ

عالی بود سعید جان

پاسخ دادن

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *


*