ویژگی تصویر

متد __construct() در PHP

  /  PHP   /  متد __construct() در PHP
بنر تبلیغاتی الف
آموزش PHP

متد __construct() در PHP نقش سازندهٔ شیء (constructor) را دارد؛ یعنی هر زمان که با عملگر new یک آبجکت ساخته می‌شود، اگر چنین متدی تعریف شده باشد اجرا می‌گردد. کارهای مرسوم در سازنده شامل مقداردهی اولیه به خواص، دریافت وابستگی‌ها، باز کردن ارتباط با دیتابیس یا فایل و اعتبارسنجی پارامترهای ورودی است.

قواعد و نکات پایه

  • نام متد باید دقیقاً __construct باشد؛ این یک «متد جادویی» است.
  • سازنده نمی‌تواند static باشد و بازگشتی هم ندارد.
  • می‌توان برای آن پارامتر، تایپ‌هینت، مقادیر پیش‌فرض، و ورودی‌های واریادی تعریف کرد.
  • قدیمی‌ترین سبک سازنده (متدی با همان نام کلاس) منسوخ شده است؛ از __construct استفاده کنید.
  • دید (visibility) می‌تواند public, protected یا private باشد — که الگوهای طراحی مثل Singleton را ممکن می‌سازد.
ویژگیتوضیح
قابل ارث‌بریدر کلاس فرزند می‌توانید سازنده را بازنویسی کرده و با parent::__construct() والد را فراخوانی کنید.
دیدتعیین‌کنندهٔ نحوهٔ ساخت شیء (مثلاً private برای Singleton).
استثناهامی‌توانید خطا (Exception) در سازنده پرتاب کنید تا از ساختن شیء با وضعیت نامعتبر جلوگیری شود.

مثال پایه

// مثال ساده سازنده
class User {
    private string $name;
    private int $age;
    
    public function __construct(string $name, int $age = 18) {
        $this->name = $name;
        $this->age = $age;
    }

    public function getProfile(): string {
        return "{$this->name}, age: {$this->age}";
    }
}

$user = new User("Ali", 30);
echo $user->getProfile();

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

وراثت و فراخوانی سازنده والد

// سازنده در کلاس‌های ارث‌بری
class BaseController {
    protected PDO $db;
    public function __construct(PDO $db) {
        $this->db = $db;
    }
}

class UserController extends BaseController {
    private string $serviceName;
    public function __construct(PDO $db, string $serviceName = 'user') {
        parent::__construct($db); // فراخوانی سازندهٔ والد
        $this->serviceName = $serviceName;
    }
}

در این نمونه، UserController برای استفاده از دیتابیس باید سازندهٔ والد را صدا بزند. رعایت این الگو از نشت منابع و مقداردهی ناقص جلوگیری می‌کند.

Dependency Injection در سازنده

// نمونهٔ DI با تایپ‌هینت
class Mailer {
    public function send(string $to, string $body) { /* ... */ }
}

class NotificationService {
    private Mailer $mailer;
    public function __construct(Mailer $mailer) {
        $this->mailer = $mailer;
    }
    public function notify(string $userEmail, string $msg) {
        $this->mailer->send($userEmail, $msg);
    }
}

اینجا از تزریق وابستگی (Dependency Injection) استفاده شده تا کلاس‌ها قابل تست و جدا از ایجاد نمونه‌های داخلی باشند. در پیاده‌سازی‌های پیشرفته‌تر می‌توان از containerها برای تزریق اتوماتیک بهره برد.

الگوی Singleton با سازندهٔ خصوصی

// الگوی Singleton
class Logger {
    private static ?Logger $instance = null;
    private function __construct(private string $file) {
        // باز کردن فایل یا تنظیم سطح لاگ
    }
    public static function getInstance(string $file = '/tmp/app.log'): Logger {
        if (self::$instance === null) {
            self::$instance = new Logger($file);
        }
        return self::$instance;
    }
    public function log(string $msg) { /* ... */ }
}

با private کردن سازنده، ساخت مستقیم شیء با new غیرممکن می‌شود و تنها طریق ایجاد نمونه، متد ایستا getInstance() است.

Constructor Property Promotion (PHP 8+)

// قبل از PHP 8
class Product {
    private string $name;
    private float $price;
    public function __construct(string $name, float $price) {
        $this->name = $name;
        $this->price = $price;
    }
}

// با PHP 8 — Property Promotion
class Product2 {
    public function __construct(private string $name, private float $price) {}
}

در PHP 8 می‌توانید با «promote» خواص را مستقیم در امضای سازنده تعریف کنید تا کد کوتاه‌تر و خواناتر شود. این ساختار علاوه بر کاهش تکرار، باعث کم شدن خطاهای انسانی می‌شود.

بهترین شیوه‌ها و نکات امنیتی

  • محدود کردن دید سازنده (مثلاً protected/private) برای کنترل فرآیند ساخت اشیاء در الگوهای خاص.
  • در صورت اتصال به منابع (فایل/دیتابیس)، از try/catch برای هندل کردن خطاها استفاده کنید و منابع را در destructor پاک کنید.
  • از پرتاب Exception در سازنده برای جلوگیری از ایجاد اشیاء ناپایدار بهره ببرید.
  • در کلاس‌های مشتق، سازنده والد را به صورت روشن فراخوانی کنید تا مقداردهی ناقص رخ ندهد.
  • در پروژه‌های بزرگ از Dependency Injection Container برای مدیریت سازنده‌ها و وابستگی‌ها استفاده کنید.

مثال: سازنده‌ای که خطا پرتاب می‌کند

// اعتبارسنجی در سازنده
class Config {
    private array $data;
    public function __construct(array $data) {
        if (empty($data['host'])) {
            throw new InvalidArgumentException("host required");
        }
        $this->data = $data;
    }
}

در این کد، اگر پیکربندی ضروری موجود نباشد، سازنده استثنا پرتاب می‌کند تا از ادامهٔ اجرای برنامه با پیکربندی نامعتبر جلوگیری شود.

جمع‌بندی

متد __construct() قلب مقداردهی اولیهٔ هر شیء در PHP است. آشنایی با نکات مربوط به دید، وراثت، dependency injection، و امکانات جدید مانند constructor property promotion باعث می‌شود کدهای خواناتر، امن‌تر و قابل تست‌تری بنویسید. الگوهای طراحی از قبیل Singleton یا Factory مستقیماً روی دید و پیاده‌سازی سازنده تکیه دارند، پس انتخاب درست امضاء و رفتار سازنده اهمیت بالایی دارد.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: