آموزش برنامه نویسی PHP-جلسه شانزدهم

آموزش برنامه نویسی PHP-جلسه شانزدهم

وقتی یک شی را ایجاد می‌کنیم می توانیم به وسیله constructor یا سازنده، متغیرها را مقداردهی اولیه کنیم.

Table of contents [Show] [Hide]

آموزش Constructor و Destructor در PHP؛ سازنده و مخرب در برنامه‌نویسی شی‌گرا

در برنامه‌نویسی شی‌گرا (OOP) در PHP، Constructor و Destructor دو متد ویژه هستند که در چرخه حیات یک شیء نقش مهمی دارند. سازنده زمانی که یک شیء ایجاد می‌شود به صورت خودکار اجرا می‌شود و برای مقداردهی اولیه ویژگی‌های شیء کاربرد دارد. از طرف دیگر، مخرب زمانی که شیء از بین می‌رود یا دیگر مورد استفاده نیست، اجرا می‌شود و می‌توان از آن برای انجام عملیات پایانی و آزادسازی منابع استفاده کرد.

در این مقاله با مفهوم __construct() و __destruct()، نحوه استفاده از آن‌ها، تفاوتشان با متدهای معمولی، کاربردهای واقعی و نکات مهم هنگام استفاده از این متدها در PHP آشنا می‌شویم.


Constructor در PHP چیست؟

در PHP به متدی که هنگام ایجاد یک Object به صورت خودکار اجرا می‌شود، Constructor یا سازنده گفته می‌شود.

سازنده با نام زیر تعریف می‌شود:

 
__construct()
 

مهم‌ترین کاربرد Constructor این است که هنگام ایجاد شیء، اطلاعات اولیه مورد نیاز آن را مشخص کنیم.

برای مثال فرض کنید یک کلاس برای نگهداری اطلاعات میوه ایجاد کرده‌ایم:

 
<?php

class Fruit
{
    public $name;
    public $color;

    function __construct($name)
    {
        $this->name = $name;
    }

    function get_name()
    {
        return $this->name;
    }
}

$apple = new Fruit("Apple");

echo $apple->get_name();

?>
 

در این مثال، زمانی که دستور زیر اجرا می‌شود:

 
$apple = new Fruit("Apple");
 

متد __construct() به صورت خودکار اجرا می‌شود و مقدار "Apple" را دریافت می‌کند.

سپس این مقدار در ویژگی $name ذخیره می‌شود:

 
$this->name = $name;
 

در نتیجه مقدار $name مربوط به شیء $apple برابر با Apple خواهد بود.


چرا از Constructor استفاده می‌کنیم؟

فرض کنید Constructor وجود نداشته باشد. در این حالت ممکن است مجبور شویم بعد از ایجاد هر شیء، ویژگی‌های آن را به صورت جداگانه مقداردهی کنیم.

برای مثال:

 
<?php

class Fruit
{
    public $name;

    function set_name($name)
    {
        $this->name = $name;
    }
}

$apple = new Fruit();

$apple->set_name("Apple");

?>
 

در این روش ابتدا Object ساخته می‌شود و سپس با استفاده از set_name() مقدار آن را مشخص می‌کنیم.

اما با استفاده از Constructor می‌توانیم مقدار اولیه را همان لحظه ایجاد Object مشخص کنیم:

 
$apple = new Fruit("Apple");
 

بنابراین Constructor باعث می‌شود فرآیند ایجاد و مقداردهی اولیه Object ساده‌تر و ساختار کد منظم‌تر شود.


ساخت Constructor در PHP

برای تعریف Constructor کافی است داخل کلاس متدی با نام __construct ایجاد کنیم:

 
<?php

class Fruit
{
    public $name;

    function __construct($name)
    {
        $this->name = $name;
    }
}

?>
 

نکته مهم این است که __construct دو علامت زیرخط در ابتدا و دو علامت زیرخط در انتهای نام خود دارد:

 
__construct
 

این موضوع را هنگام نوشتن کد باید با دقت رعایت کنید.


استفاده از پارامتر در Constructor

یکی از مهم‌ترین قابلیت‌های Constructor این است که می‌توانیم هنگام ایجاد Object اطلاعات مورد نیاز را به آن ارسال کنیم.

برای مثال:

 
<?php

class User
{
    public $name;
    public $email;

    function __construct($name, $email)
    {
        $this->name = $name;
        $this->email = $email;
    }
}

$user = new User("Ali", "ali@example.com");

echo $user->name;
echo "<br>";
echo $user->email;

?>
 

در این مثال Constructor دو پارامتر دریافت می‌کند:

 
$name
$email
 

هنگام ایجاد Object نیز این مقادیر را ارسال کرده‌ایم:

 
$user = new User("Ali", "ali@example.com");
 

در نتیجه ویژگی‌های Object در همان زمان ایجاد مقداردهی می‌شوند.


$thisدر Constructor چیست؟

در مثال‌های بالا عبارت زیر را مشاهده کردیم:

 
$this->name = $name;
 

$this به Object جاری اشاره می‌کند؛ یعنی همان شیئی که متد در حال اجرا روی آن فراخوانی شده است.

برای مثال:

 
$this->name = $name;
 

یعنی مقدار پارامتر $name را در ویژگی name مربوط به Object فعلی قرار بده.

برای درک بهتر:

 
function __construct($name)
{
    $this->name = $name;
}
 

در اینجا:

  • $name پارامتری است که به Constructor ارسال شده است.
  • $this->name ویژگی Object است.
  • مقدار پارامتر در ویژگی Object ذخیره می‌شود.

مقداردهی چند ویژگی با Constructor

Constructor می‌تواند چند ویژگی را هم‌زمان مقداردهی کند.

برای مثال:

 
<?php

class Fruit
{
    public $name;
    public $color;
    public $price;

    function __construct($name, $color, $price)
    {
        $this->name = $name;
        $this->color = $color;
        $this->price = $price;
    }
}

$apple = new Fruit("Apple", "Red", 100);

echo $apple->name;
echo "<br>";
echo $apple->color;
echo "<br>";
echo $apple->price;

?>
 

در اینجا هنگام ایجاد Object، سه مقدار به Constructor ارسال شده است:

 
$apple = new Fruit("Apple", "Red", 100);
 

و Constructor این مقادیر را در ویژگی‌های Object ذخیره می‌کند.


Constructor با مقدار پیش‌فرض

گاهی اوقات می‌خواهیم یک پارامتر مقدار پیش‌فرض داشته باشد تا در صورت ارسال نشدن مقدار، برنامه بتواند از مقدار مشخصی استفاده کند.

برای مثال:

 
<?php

class User
{
    public $name;
    public $role;

    function __construct($name, $role = "User")
    {
        $this->name = $name;
        $this->role = $role;
    }
}

$user = new User("Ali");

echo $user->name;
echo "<br>";
echo $user->role;

?>
 

در این مثال اگر مقدار role ارسال نشود، مقدار پیش‌فرض "User" استفاده خواهد شد.


Constructor در چند Object

هر بار که از یک کلاس Object جدیدی ایجاد کنیم، Constructor همان Object اجرا می‌شود.

برای مثال:

 
<?php

class Fruit
{
    public $name;

    function __construct($name)
    {
        $this->name = $name;
    }
}

$apple = new Fruit("Apple");
$banana = new Fruit("Banana");
$orange = new Fruit("Orange");

echo $apple->name;
echo "<br>";
echo $banana->name;
echo "<br>";
echo $orange->name;

?>
 

در این مثال سه Object ایجاد شده و Constructor برای هر کدام به صورت خودکار اجرا می‌شود.


Destructor در PHP چیست؟

در مقابل Constructor، در PHP متدی به نام Destructor یا مخرب وجود دارد.

Destructor با نام زیر تعریف می‌شود:

 
__destruct()
 

این متد زمانی اجرا می‌شود که Object در حال از بین رفتن باشد.

به زبان ساده، Constructor در ابتدای چرخه حیات Object کاربرد دارد و Destructor برای عملیات پایانی Object مورد استفاده قرار می‌گیرد.

ساختار کلی آن به شکل زیر است:

 
function __destruct()
{
    // عملیات پایانی
}
 

ساخت Destructor در PHP

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

 
<?php

class Fruit
{
    public $name;
    public $color;

    function __construct($name, $color)
    {
        $this->name = $name;
        $this->color = $color;
    }

    function __destruct()
    {
        echo "The fruit is {$this->name} and the color is {$this->color}.";
    }
}

$apple = new Fruit("Apple", "Red");

?>
 

در این مثال زمانی که Object مربوط به $apple از بین برود، متد __destruct() اجرا می‌شود.


آیا Destructor کلاس را حذف می‌کند؟

یک نکته مهم در مورد Destructor وجود دارد.

گاهی گفته می‌شود:

Destructor برای حذف کلاس استفاده می‌شود.

این توضیح دقیق نیست.

Destructor برای حذف کلاس استفاده نمی‌شود؛ بلکه متدی است که هنگام از بین رفتن یک Object اجرا می‌شود.

بنابراین بهتر است Destructor را به عنوان متدی برای انجام عملیات پایانی مربوط به Object در نظر بگیریم.

PHP مدیریت حافظه و چرخه حیات Objectها را خودش انجام می‌دهد و در شرایط مناسب Objectهایی که دیگر مورد استفاده نیستند را از بین می‌برد.


کاربرد واقعی Destructor چیست؟

یکی از کاربردهای مهم Destructor انجام عملیات نهایی و آزادسازی منابع است.

برای مثال، فرض کنید یک Object با یک فایل، اتصال یا منبع خاصی کار می‌کند و می‌خواهیم هنگام پایان کار، عملیات لازم را انجام دهیم.

در چنین شرایطی Destructor می‌تواند برای انجام عملیات پایانی مورد استفاده قرار بگیرد.

یک مثال ساده:

 
<?php

class FileHandler
{
    public $file;

    function __construct($file)
    {
        $this->file = $file;

        echo "File opened.";
    }

    function __destruct()
    {
        echo "File handler finished.";
    }
}

$file = new FileHandler("data.txt");

?>
 

این مثال صرفاً برای نمایش مفهوم چرخه حیات Object است. در پروژه‌های واقعی، مدیریت فایل‌ها و منابع باید با روش مناسب و کنترل خطا انجام شود.


تفاوت Constructor و Destructor در PHP

Constructor و Destructor هر دو متدهای ویژه PHP هستند، اما در زمان و هدف استفاده تفاوت دارند.

ConstructorDestructor
__construct()__destruct()
هنگام ایجاد Object اجرا می‌شودهنگام از بین رفتن Object اجرا می‌شود
برای مقداردهی اولیه استفاده می‌شودبرای عملیات پایانی استفاده می‌شود
در ابتدای چرخه حیات Object کاربرد دارددر پایان چرخه حیات Object کاربرد دارد
می‌تواند پارامتر دریافت کندمعمولاً بدون پارامتر تعریف می‌شود

به صورت ساده می‌توان گفت:

Constructor → آماده‌سازی Object

Destructor → پایان کار Object


مثال کامل Constructor و Destructor

حالا یک مثال کامل‌تر را بررسی کنیم:

 
<?php

class Product
{
    public $name;
    public $price;

    function __construct($name, $price)
    {
        $this->name = $name;
        $this->price = $price;

        echo "Product created.<br>";
    }

    function show_product()
    {
        echo "Product: " . $this->name . "<br>";
        echo "Price: " . $this->price . "<br>";
    }

    function __destruct()
    {
        echo "Product object destroyed.";
    }
}

$product = new Product("Laptop", 1500);

$product->show_product();

?>
 

در این مثال چند مرحله اتفاق می‌افتد:

مرحله اول: ایجاد Object

 
$product = new Product("Laptop", 1500);
 

در این لحظه Constructor به صورت خودکار اجرا می‌شود.

مرحله دوم: مقداردهی ویژگی‌ها

Constructor مقادیر زیر را دریافت می‌کند:

 
Laptop
1500
 

و آنها را در ویژگی‌های Object قرار می‌دهد.

مرحله سوم: اجرای متد

سپس متد show_product() اجرا می‌شود و اطلاعات محصول را نمایش می‌دهد.

مرحله چهارم: پایان عمر Object

وقتی Object از بین برود، PHP متد __destruct() را اجرا می‌کند.


چه زمانی Destructor اجرا می‌شود؟

زمان اجرای Destructor به چرخه حیات Object و مدیریت حافظه PHP بستگی دارد.

برای مثال اگر Object دیگر مرجعی نداشته باشد و قابل استفاده نباشد، PHP می‌تواند آن را از بین ببرد و Destructor را اجرا کند.

همچنین در پایان اجرای اسکریپت، Objectهای باقی‌مانده نیز از بین می‌روند و Destructor مربوط به آنها می‌تواند اجرا شود.

به همین دلیل نباید ترتیب اجرای Destructorها را در برنامه‌های پیچیده بدون در نظر گرفتن وابستگی‌های Objectها فرض کرد.


حذف دستی Object و Destructor

در PHP می‌توان با unset() یک متغیر حاوی Object را از بین برد:

 
<?php

class User
{
    public $name;

    function __construct($name)
    {
        $this->name = $name;
    }

    function __destruct()
    {
        echo "Object destroyed.";
    }
}

$user = new User("Ali");

unset($user);

?>
 

در این مثال با اجرای:

 
unset($user);
 

متغیر $user حذف می‌شود و در شرایطی که Object دیگر مرجع دیگری نداشته باشد، Destructor می‌تواند اجرا شود.


آیا می‌توان Constructor را چند بار اجرا کرد؟

Constructor به صورت خودکار هنگام ایجاد Object اجرا می‌شود.

اگر چند Object از یک کلاس ایجاد کنیم، برای هر Object Constructor یک بار در زمان ایجاد همان Object اجرا می‌شود:

 
$user1 = new User("Ali");
$user2 = new User("Sara");
$user3 = new User("Reza");
 

در این مثال سه Object ایجاد شده و Constructor برای هر Object اجرا خواهد شد.

اگر بخواهیم Constructor را دوباره اجرا کنیم، معمولاً بهتر است به جای این کار، یک متد معمولی برای تغییر یا به‌روزرسانی اطلاعات Object طراحی کنیم.


Constructor و Type Declaration در PHP

در نسخه‌های جدید PHP می‌توان نوع پارامترها و ویژگی‌ها را نیز مشخص کرد. این کار باعث می‌شود کد خواناتر و کنترل نوع داده‌ها دقیق‌تر شود.

برای مثال:

 
<?php

class Product
{
    public string $name;
    public float $price;

    function __construct(string $name, float $price)
    {
        $this->name = $name;
        $this->price = $price;
    }
}

$product = new Product("Laptop", 1500.50);

echo $product->name;
echo "<br>";
echo $product->price;

?>
 

در اینجا مشخص کرده‌ایم که:

 
$name
 

باید از نوع string باشد و:

 
$price
 

باید از نوع float باشد.

استفاده از Type Declaration در پروژه‌های حرفه‌ای می‌تواند به خوانایی، نگهداری و کاهش خطاهای مربوط به نوع داده کمک کند.


Constructor Property Promotion در PHP

در نسخه‌های جدید PHP قابلیتی به نام Constructor Property Promotion نیز وجود دارد که می‌تواند تعریف Propertyها و Constructor را کوتاه‌تر کند.

برای مثال، به جای نوشتن:

 
class Product
{
    public string $name;
    public float $price;

    public function __construct(string $name, float $price)
    {
        $this->name = $name;
        $this->price = $price;
    }
}
 

می‌توان در نسخه‌های پشتیبان‌کننده از این قابلیت نوشت:

 
class Product
{
    public function __construct(
        public string $name,
        public float $price
    ) {
    }
}
 

در این روش، Propertyها مستقیماً در پارامترهای Constructor تعریف می‌شوند و PHP مقدار آنها را برای Object تنظیم می‌کند.


نکات مهم درباره Constructor و Destructor

هنگام استفاده از این دو متد بهتر است چند نکته را در نظر داشته باشید:

۱. نام آنها باید دقیق باشد

نام Constructor:

 
__construct()
 

و نام Destructor:

 
__destruct()
 

است.

تعداد و جایگاه علامت‌های _ اهمیت دارد.

۲. Constructor برای مقداردهی اولیه است

اگر Object برای شروع کار به اطلاعات مشخصی نیاز دارد، Constructor محل مناسبی برای دریافت این اطلاعات است.

۳. Destructor برای حذف کلاس نیست

Destructor کلاس را حذف نمی‌کند؛ بلکه هنگام پایان عمر Object، عملیات پایانی مربوط به آن را انجام می‌دهد.

۴. Destructor را بیش از حد شلوغ نکنید

بهتر است Destructor فقط مسئول عملیات پایانی مرتبط با Object باشد و منطق پیچیده و غیرضروری داخل آن قرار نگیرد.

۵. چرخه عمر Object را در نظر بگیرید

زمان دقیق اجرای Destructor به چرخه عمر Object و مدیریت حافظه PHP وابسته است. بنابراین نباید صرفاً بر اساس محل قرار گرفتن یک دستور در کد، ترتیب اجرای تمام Destructorها را پیش‌بینی کرد.


جمع‌بندی

در برنامه‌نویسی شی‌گرا، Objectها چرخه حیات مشخصی دارند. یکی از ابزارهای مهم برای مدیریت این چرخه حیات، Constructor و Destructor هستند.

با استفاده از:

 
__construct()
 

می‌توانیم هنگام ایجاد Object، ویژگی‌های آن را مقداردهی اولیه کنیم. به همین دلیل دیگر در بسیاری از موارد نیازی نیست بعد از ایجاد Object، برای مقداردهی هر ویژگی متدهای جداگانه‌ای مانند set_name() را فراخوانی کنیم.

برای مثال:

 
$apple = new Fruit("Apple", "Red");
 

در همان لحظه ایجاد Object، اطلاعات مورد نیاز به Constructor ارسال می‌شود.

از طرف دیگر:

 
__destruct()
 

برای انجام عملیات پایانی در زمان از بین رفتن Object استفاده می‌شود و می‌تواند در سناریوهایی که نیاز به پایان دادن به کار با منابع وجود دارد مفید باشد.

به طور خلاصه:

 
ایجاد Object
      ↓
__construct()
      ↓
استفاده از Object
      ↓
پایان عمر Object
      ↓
__destruct()
 

درک صحیح Constructor و Destructor یکی از مباحث مهم برای ورود جدی‌تر به برنامه‌نویسی شی‌گرا در PHP است و در ادامه مسیر، هنگام کار با کلاس‌های پیچیده‌تر، ارث‌بری، Interfaceها، Dependency Injection و پروژه‌های واقعی PHP بارها با مفهوم چرخه حیات Objectها مواجه خواهید شد.

اشتراک گذاری :
مریم گوهرزاد
نویسنده

مریم گوهرزاد

مدرس و بنیانگذار هلدینگ آرتا رسانه. برنامه نویس و محقق حوزه بلاکچین و توسعه‌دهنده بلاکچین | متخصص Solidity | توسعه‌دهنده وب Full-Stackمن یک توسعه‌دهنده علاقه‌مند به فناوری‌های بلاکچین و وب ۳ هستم و در زمینه Solidity، توسعه قراردادهای هوشمند و ساخت برنامه‌های غیرمتمرکز (DApps) فعالیت می‌کنم. تمرکز من بر طراحی و پیاده‌سازی راهکارهایی است که در کنار بهره‌گیری از فناوری‌های نوین، عملکرد مناسب، امنیت و تجربه کاربری مطلوبی ارائه دهند.در کنار تخصص در حوزه بلاکچین، به عنوان یک توسعه‌دهنده وب Full-Stack نیز در طراحی و توسعه وب‌سایت‌ها و برنامه‌های تحت وب فعالیت می‌کنم. تجربه کار در بخش‌های Front-End و Back-End به من این امکان را داده است که پروژه‌ها را از مرحله ایده و طراحی تا توسعه و اجرا، با دیدی جامع دنبال کنم. در فرآیند توسعه، توجه ویژه‌ای به کدنویسی تمیز، معماری مناسب، طراحی واکنش‌گرا، عملکرد مطلوب و تجربه کاربری روان دارم.

TEST_VALUE_123
https://t.me/artarasaneh
tel:09193426251
https://wa.me/+989193426251
https://instagram.com/artarasaneh_com