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

Laravel - Avoiding code duplication in models

我有一个方法可以在我的模型中保存一些文件,我不想再复制它了,这是在 Laravel?

中避免代码重复的最佳方法

您可以在下面看到一些重复的示例,其中有 Product 和 Articles Models,它们都有 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;
    }

}

Traits 允许您在不同的 class 之间共享方法。如果你把那个方法放在一个特征中并且让两个 class 都使用它,那应该会实现你想要的。

例如:

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;
    ...
}

模型之间的任何差异,例如文件夹,都可以在 class 上定义,例如 public $folder = 'products';,然后在特征中使用,例如 $this->folder.

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

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

    <?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;
       }
}

然后,在其他每个 class 中,您只需在构造函数中初始化它,然后使用。

// 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);
    }