Laravel-避免模型中的代码重复

时间:2018-12-11 19:56:19

标签: laravel laravel-5 php-7

我有一种方法可以在模型中保存一些文件,并且我不想再复制它,这是避免在Laravel中重复此代码的最佳方法?

您可以在下面看到一些重复的示例,其中有Product和Articles模型,都具有saveFile方法。

如何隔离此代码并重复使用?

// App/Article.php
class Product extends Model {
    protected static $storageFolders = "public/products";

    public static function saveFile($file, Array $options = []) {
        $filename = "";
        if (isset($options["name"])) {
            $filename .= $options["name"];
        }
        if ($options["unique"]) {
            $filename .= "-" . time();
        }
        $picture_path = "";
        if ($filename) {
            $extension = $file->getClientOriginalExtension();
            $filename .= ".$extension";
            $picture_path = $file->storeAs(SELF::$storageFolders, $filename);
        } else {
            $picture_path = $file->store(SELF::$storageFolders);
        }
        $storage_url = Storage::url($picture_path);
        return $storage_url;
    }
}

// App/Article.php
class Article extends Model {
    protected static $storageFolders = "public/articles";

    public static function saveFile($file, Array $options = []) {
        $filename = "";
        if (isset($options["name"])) {
            $filename .= $options["name"];
        }
        if ($options["unique"]) {
            $filename .= "-" . time();
        }
        $picture_path = "";
        if ($filename) {
            $extension = $file->getClientOriginalExtension();
            $filename .= ".$extension";
            $picture_path = $file->storeAs(SELF::$storageFolders, $filename);
        } else {
            $picture_path = $file->store(SELF::$storageFolders);
        }
        $storage_url = Storage::url($picture_path);
        return $storage_url;
    }

}

2 个答案:

答案 0 :(得分:3)

Traits允许您在不同的类之间共享方法。如果您将该方法放在特征中,并且两个类都使用它,那应该可以实现您想要的。

例如:

trait SavesFiles
{
    public static function saveFile($file, Array $options = []) {
        $filename = "";
        if (isset($options["name"])) {
            $filename .= $options["name"];
        }
        if ($options["unique"]) {
            $filename .= "-" . time();
        }
        $picture_path = "";
        if ($filename) {
            $extension = $file->getClientOriginalExtension();
            $filename .= ".$extension";
            $picture_path = $file->storeAs(SELF::$storageFolders, $filename);
        } else {
            $picture_path = $file->store(SELF::$storageFolders);
        }
        $storage_url = Storage::url($picture_path);
        return $storage_url;
    }
}

然后,您的模型可以按以下方式使用它:

class Product extends Model
{
    use SavesFiles;
    ...
}

可以在类(例如public $folder = 'products';)上定义不同模型(例如文件夹)之间的所有内容,然后在特征(例如$this->folder)中使用。

或者,您可以使用该方法创建一个抽象模型类,并使两个模型都继承自该方法。但是特质是我的首选。

答案 1 :(得分:1)

您可以使用服务或特质。 (您永远不会从一个控制器调用方法到另一个控制器)。

    <?php


    namespace App\Services;

    class FileService
    {

        public function saveFile($file, Array $options = []) {
            $filename = "";
            if (isset($options["name"])) {
                $filename .= $options["name"];
            }
            if ($options["unique"]) {
                $filename .= "-" . time();
            }

            $picture_path = "";    

            if ($filename) {
                $extension = $file->getClientOriginalExtension();
                $filename .= ".$extension";
                $picture_path = $file->storeAs(SELF::$storageFolders, $filename);
            } else {
                $picture_path = $file->store(SELF::$storageFolders);
            }
            $storage_url = Storage::url($picture_path);

        return $storage_url;
       }
}

然后,在每个其他类中,只需在构造函数中对其进行初始化并使用。

// App/Article.php
class Product extends Model {
    protected static $storageFolders = "public/products";  
    protected $fileService;

    public function __construct(FileService $fileService) 
    {
         $this->fileService = $fileService;
    }

    public function saveFile ($file, Array $options = [] ) {
        this->fileService->saveFile($file,$options);
    }