【问题标题】:Get enum options in laravels eloquent在 laravel eloquent 中获取枚举选项
【发布时间】:2014-11-18 10:03:59
【问题描述】:

在我的迁移文件中,我为表 pages 提供了一个带有 2 个可能值的 enum 字段(如下所示)。我的问题是,是否可以使用 Laravel Eloquent 选择这些值?

$table->enum('status', array('draft','published'));

我找到了几种解决方法,但必须有一些“雄辩的原生”方法来处理这个问题。我的预期输出是这样的(那将是完美的!):

array('draft','published')

提前谢谢你!

【问题讨论】:

    标签: php laravel enums eloquent


    【解决方案1】:

    很遗憾,Laravel 没有为此提供解决方案。你必须自己做。我做了一些挖掘,发现this answer

    您可以使用该函数并将其转换为模型类中的方法...

    class Page extends Eloquent {
    
        public static function getPossibleStatuses(){
            $type = DB::select(DB::raw('SHOW COLUMNS FROM pages WHERE Field = "type"'))[0]->Type;
            preg_match('/^enum\((.*)\)$/', $type, $matches);
            $values = array();
            foreach(explode(',', $matches[1]) as $value){
                $values[] = trim($value, "'");
            }
            return $values;
        }
    }
    

    然后你就这样使用它

    $options = Page::getPossibleStatuses();
    

    如果您愿意,您还可以使其更普遍可访问和通用。

    首先,创建一个BaseModel。然后所有模型都应该从这个类扩展

    class BaseModel extends Eloquent {}
    

    然后,把这个函数放在那里

    public static function getPossibleEnumValues($name){
        $instance = new static; // create an instance of the model to be able to get the table name
        $type = DB::select( DB::raw('SHOW COLUMNS FROM '.$instance->getTable().' WHERE Field = "'.$name.'"') )[0]->Type;
        preg_match('/^enum\((.*)\)$/', $type, $matches);
        $enum = array();
        foreach(explode(',', $matches[1]) as $value){
            $v = trim( $value, "'" );
            $enum[] = $v;
        }
        return $enum;
    }
    

    你这样称呼这个

    $options = Page::getPossibleEnumValues('status');
    

    【讨论】:

    • 为什么不为此使用专用特征?
    • 当然,如果你愿意,你可以使用特征
    • Laravel 应该将其添加到每个 Eloquent 类中,可能作为 Trait
    • 我试过这个解决方案,是的,它可以工作,但我怎样才能保存索引而不是状态本身。 “草稿”示例 1,“已发布”示例 2
    【解决方案2】:

    对 lukasgeiter 的功能进行了小幅改进。他的答案中的 foreach 循环正在解析字符串。您可以更新正则表达式来为您执行此操作。

    /**
     * Retrieves the acceptable enum fields for a column
     *
     * @param string $column Column name
     *
     * @return array
     */
    public static function getPossibleEnumValues ($column) {
        // Create an instance of the model to be able to get the table name
        $instance = new static;
    
        // Pulls column string from DB
        $enumStr = DB::select(DB::raw('SHOW COLUMNS FROM '.$instance->getTable().' WHERE Field = "'.$column.'"'))[0]->Type;
    
        // Parse string
        preg_match_all("/'([^']+)'/", $enumStr, $matches);
    
        // Return matches
        return isset($matches[1]) ? $matches[1] : [];
    }
    

    【讨论】:

    • 如果列没有枚举值,则会引发错误。所以我在代码中加了一个小检查 `public static function getPossibleEnumValues($column) { // 创建模型的一个实例就可以得到表名 $instance = new static; // 从 DB 中提取列字符串 $enumStr = $arr[0]->Type; // 解析字符串 preg_match_all("/'([^']+)'/", $enumStr, $matches); // 返回匹配项 return isset($matches[1]) ? $matches[1] : []; } `
    【解决方案3】:

    如果该列不存在,则会引发错误。所以我在代码中添加了一个小检查

    public static function getPossibleEnumValues ($column) {
    // Create an instance of the model to be able to get the table name
        $instance = new static;
    
        $arr = DB::select(DB::raw('SHOW COLUMNS FROM '.$instance->getTable().' WHERE Field = "'.$column.'"'));
        if (count($arr) == 0){
            return array();
        }
        // Pulls column string from DB
        $enumStr = $arr[0]->Type;
    
        // Parse string
        preg_match_all("/'([^']+)'/", $enumStr, $matches);
    
        // Return matches
        return isset($matches[1]) ? $matches[1] : [];
    }
    

    【讨论】:

      【解决方案4】:

      从 L5.17 开始,Eloquent 不包含此功能,您需要退回到原生 QL。这是一个使用 SQL 的示例,并且在一行中 - 返回一个数组,如您所要求的。

      本着单线复杂性的精神 ;)

      我把它扔给了我的一个视图作曲家——它从表中获取列,分解它并将值组合到一个数组中。

      我使用 foreach 在我的视图中对其进行迭代。

      explode (
          "','",
          substr (
            DB::select("  SHOW COLUMNS 
                          FROM ".(new \Namespace\Model)->getTable()." 
                          LIKE 'colName'"
            )[0]->Type,
            6,
            -2
          )
      );
      

      【讨论】:

        猜你喜欢
        • 2020-08-04
        • 2021-10-10
        • 2017-01-14
        • 2014-10-04
        • 1970-01-01
        • 1970-01-01
        • 2018-12-14
        • 1970-01-01
        • 2011-02-16
        相关资源
        最近更新 更多