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

Laravel-避免模型中的代码重复,laravel,laravel-5,php-7,Laravel,Laravel 5,Php 7,我有一个在我的模型中保存一些文件的方法,我不想再复制它了,这是避免Laravel中代码重复的最好方法 您可以看到下面的一些复制示例,其中有产品和文章模型,它们都有saveFile方法 如何隔离此代码并重用它 // App/Article.php class Product extends Model { protected static $storageFolders = "public/products"; public static function saveFile($f

我有一个在我的模型中保存一些文件的方法,我不想再复制它了,这是避免Laravel中代码重复的最好方法

您可以看到下面的一些复制示例,其中有产品和文章模型,它们都有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;
    }

}
允许您在不同类之间共享方法。如果你把这个方法放在一个trait中,并且让两个类都使用它,那应该可以实现你想要的

例如:

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'
,然后用于trait,例如
$this->folder

或者,您可以使用该方法创建一个抽象模型类,并使两个模型都从中继承。但是traits将是我的第一选择。

允许您在不同的类之间共享方法。如果你把这个方法放在一个trait中,并且让两个类都使用它,那应该可以实现你想要的

例如:

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'
,然后用于trait,例如
$this->folder


或者,您可以使用该方法创建一个抽象模型类,并使两个模型都从中继承。但是Trait是我的第一选择。

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


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


在laravel中有一些使用特征的转换?例如:一些文件夹,一些名称模式,我在文档中找不到任何内容。@MateusKoppe您可以定义文件夹之类的东西作为类变量,并让trait从类中提取它们。我得到了以下错误:App\Product和App\Traits\StorageTrait在App\Product的组合中定义相同的属性($storageFolders)。但是,定义不同,被认为是不兼容的。类已组合我想在每个模型中配置$storageFolders变量,就像它是从另一个类扩展而来的一样。@MateusKoppe这意味着您不能在trait中定义它。trait中定义的任何内容都会被复制并粘贴到使用它的类中,因此如果您从trait中删除该变量的定义,应该可以解决这个问题?例如:一些文件夹,一些名称模式,我在文档中找不到任何内容。@MateusKoppe您可以定义文件夹之类的东西作为类变量,并让trait从类中提取它们。我得到了以下错误:App\Product和App\Traits\StorageTrait在App\Product的组合中定义相同的属性($storageFolders)。但是,定义不同,被认为是不兼容的。类已组合我想在每个模型中配置$storageFolders变量,就像它是从另一个类扩展而来的一样。@MateusKoppe这意味着您不能在trait中定义它。trait中定义的任何内容都会被复制并粘贴到使用它的类中,因此如果您从trait中删除该变量的定义,它应该可以解决问题。