从方法 return 实例化 Class 并将数据传递给构造函数 PHP

Instantiate Class from method return and pass data to constructor PHP

我有通知 class 称为 ProductNotification、OrderNotification 等,它们有一个邮件方法,returns 另一个 class 包含用于发送电子邮件的更多数据:

class ProductNotification {
    public function mail()
    {
        return ProductMail::class;
    }
}
class OrderNotification {
    public function mail()
    {
        return OrderMail::class;
    }
}

有没有办法从方法中实例化 ProductMail class,下面的方法不起作用,我不确定如何将另一个变量 $data 传递给构造函数。?

class BaseNotification {
    public function toMail()
    {
        return (new $this->mail())->to($email)->send();
    {
}

我知道如果 mail() 是 class 上的 属性,那么这是可能的,我可以通过 $data 传递给构造函数,如下所示, 但这是可能的方法吗?

class ProductNotification {
    public $mail = ProductMail::class;
}
class BaseNotification {
    public function toMail()
    {
        return (new $this->mail($data))->to($email)->send();
    {
}

您可以将class存储为toMail方法中的局部变量,然后实例化它。

class BaseNotification {
    public function toMail($data)
    {
        $mail_class = $this->mail();

        return new $mail_class($data);
    }
}

您不能通过方法调用实例化对象,但可以通过变量实例化。所以只需将方法的 return 调用分配给一个变量:

class ProductNotification extends BaseNotification {
    public function mail() {
        return ProductMail::class;
    }
}

class OrderNotification extends BaseNotification {
    public function mail() {
        return OrderMail::class;
    }
}

class BaseNotification {
    public function toMail()
    {
        $data = [];
        $class = $this->mail();
        return (new $class($data))->to($email)->send();
    {
}

尽管使用 mail() 方法构建邮件可能更简洁:

class ProductNotification extends BaseNotification {
    public function mail($data) {
        return new ProductMail($data);
    }
}

class OrderNotification extends BaseNotification {
    public function mail($data) {
        return new OrderMail($data);
    }
}

class BaseNotification {
    public function mail() {
        throw new \Exception("not implemented");
    }

    public function toMail()
    {
        $data = [];
        return $this->mail($data)->to($email)->send();
    {
}