🎉 سال نو، مهارت نو، مشاوره رایگان نقشه راه برنامه نویسی (آفر ویژه ثبت نام قبل از افزایش قیمت 🔥)
۰ ثانیه
۰ دقیقه
۰ ساعت
۳ محمد فهیمی
استفاده از Mpdf
جامعه پی اچ پی ایجاد شده در ۰۵ فروردین ۱۴۰۰

سلام خسته نباشید

 

class PdfExporter extends Exporter
{
    protected $format='.pdf';
    public function exporter()
    {
        $file_name = "text-file-" . rand(100,999) . $this->format;
        $file_path= __DIR__."/files/$file_name";
        $mpdf = new \Mpdf\Mpdf();
        $mpdf->WriteHTML("{$this->data['title']},{$this->data['content']}");
        $mpdf->Output($file_path);   
        echo "$file_name successfully Created!\n";
    }
}

بنده کلاس pdf به این شکل نوشتم و خوبم کار میکنه ، ولی فکر نمیکنم کار درستی انجام داده باشم ، چون داخل یک کلاس من از یک کلاس دیگه ابجکت ساختم و این مشکلی نیست ؟

سلام و احترام

وابستگی باید از بیرون به داخل باشه ن از داخل به بیرون، کلاس بالا و متد exporter داره تعیین میکنه که چی میخواد اما این باید برعکس باشه و ما باید بهش بگیم چی رو باید استفاده کنی، برای مثال

<?php
class PdfExporter extends Exporter
{
    protected $format='.pdf';
    protected $pdfClass;
    public function __construct($pdfClass)
    {
        $this->pdfClass = $pdfClass;
    }
    public function exporter()
    {   
        $file_name = "text-file-" . rand(100,999) . $this->format;
        $file_path= __DIR__."/files/$file_name";
        $this->pdfClass->WriteHTML("{$this->data['title']},{$this->data['content']}");
        $this->pdfClass->Output($file_path);   
        echo "$file_name successfully Created!\n";
    }
}
$pdfExporter = new PdfExporter(new \Mpdf\Mpdf());
$pdfExporter->exporter();

اگه دقت کنید وقتی که داریم از کلاس new میکنیم بهش یک instance از کلاس \Mpdf\Mpdf رو پاس دادیم و داخل متد construct اون رو داخل یه property دخیره کردیم تا بتونیم داخل کلاس ازش استفاده کنیم. 

حالا اگه بعدا هم بخوایم از یه کلاس دیگه استفاده کنیم برای pdf میتونیم خیلی راحت موقع new کردن از کلاس PdfExporter یه instance دیگه از کلاس دیگه بهش پاس بدیم.

برای اینکه حتی مطمئن بشیم که همه کلاسی که به PdfExporter پاس میدیم متدهای WriteHTML و Output رو داشته باشن میتونیم این دوتا متد رو داخل یه interface بزاریم و این دو متد رو قرارداد کنیم تا مطمئن شیم همه کلاس‌ها این دو متد رو دارن.

اگه موردی که بهتون گفتم رو انجام دادید حتما توی کلاس construct هم مشخص کنید که هر instance که پاس داده شد از جنس همون interfaceی باشه که تعریف کردیم، برای مثال

 public function __construct(PDFInterface $pdfClass)
    {
        $this->pdfClass = $pdfClass;
    }

میبینید که برای پارامتر $pdfClass من  PDFInterface رو تعیین کردم و گفتم که حتما باید از همین جنس باشه، و اگه اگه کسی اومد به جای کلاس pdf یه کلاس Excel داد به خطا میخوره و میگه که حتما باید از جنش PDFInterface باشه.

توی ادامه دوره با این مواردی که بهتون گفتم کاملا آشنا میشید 

موفق باشید

امیر صالحی ۰۵ فروردین ۱۴۰۰، ۰۸:۰۹

با سلام

آقای صالحی به نظر شما این روش درست است؟

من اومدم constructor را به این شکل تعریف کردم برای دریافت پارامتر‌های data

    public function __construct($pdfClass, array $data)
    {
        $this->pdfClass = $pdfClass;
        $this->data = $data;
    }

و در process برای صدا زدن تابع یک شرط گذاشتم ولی فکر میکنم برای process بهترین روش نیست

if ($format == "Pdf") {
    $export = new $className(new \Mpdf\Mpdf(), ['title' => $title, 'content' => $content]);
} else {
    $export = new $className(['title' => $title, 'content' => $content]);
}
محمد گازری ۱۳ فروردین ۱۴۰۰، ۰۹:۳۲

سلام و احترام

نکته اول اینکه اگه قرار باشه آرگومانی null باشه اونو همیشه به عنوان آرگومان آخر در نظر بگیرید، به این شکل

   public function __construct(array $data, $pdfClass = null)
    {
        $this->pdfClass = $pdfClass;
        $this->data = $data;
    }

 

$exporterClass = ($format == "Pdf") ? (new \Mpdf\Mpdf()) : null;
$export = new $className(['title' => $title, 'content' => $content], $exporterClass);

اما خب نکات زیادی وجود داره، اینکه اگه null بود چه اتفاقی بیوفته، یا اینکه این کلاس قرار از همه‌ی exporter‌های مختلف پشتیبانی کنه یا ن، منظورم اینکه هم pdf بگیره هم excel و .. اگه میخواید کاری کنید تمامی خروجی‌های مختلف رو با کوچیک‌ترین تغییر  export بگیره بهم بگید تا بهتون توضیح بدم’

 

 

امیر صالحی ۱۴ فروردین ۱۴۰۰، ۱۶:۳۰