【问题标题】:Laravel convert an array to a modelLaravel 将数组转换为模型
【发布时间】:2014-07-02 22:09:21
【问题描述】:

我有一个数组如下

      'topic' => 
  array (
    'id' => 13,
    'title' => 'Macros',
    'content' => '<p>Macros. This is the updated content.</p>
',
    'created_at' => '2014-02-28 18:36:55',
    'updated_at' => '2014-05-14 16:42:14',
    'category_id' => '5',
    'tags' => 'tags',
    'referUrl' => '',
    'user_id' => 3,
    'videoUrl' => '',
    'useDefaultVideoOverlay' => 'true',
    'positive' => 0,
    'negative' => 1,
    'context' => 'macros',
    'viewcount' => 60,
    'deleted_at' => NULL,
  )

我想使用此数组并将其转换/转换为主题模型。有没有办法做到这一点。

谢谢

【问题讨论】:

    标签: laravel laravel-4


    【解决方案1】:

    我在寻找其他东西时遇到了这个问题。注意到它有点过时了,我有另一种方法来处理 OPs 问题。这可能是处理从具有更新版本的 Laravel 的数组创建模型的已知方法。

    我向我的类/模型添加了一个通用构造函数

    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
    }
    

    然后,当我想从数组中创建模型的新实例时,我会进行这样的调用

    $topic = new Topic($attrs);
    // Then save it if applicable
    $topic->save(); // or $topic->saveOrFail();
    

    我希望有人觉得这很有帮助。

    【讨论】:

      【解决方案2】:

      看看L5中这两个可用的方法newInstancenewFromBuilder

      例如with(new static)-&gt;newInstance( $attributes , true ) ;

      【讨论】:

        【解决方案3】:

        用于从单个项目数组创建模型:

        $Topic = new Topic();
        $Topic->fill($array);
        

        用于从项目数组创建集合:

        $Topic::hydrate($result);
        

        【讨论】:

        • 在从数据库更新记录时也很有用,例如:$model = \App\Models\TblTask::find(1);$model-&gt;fill($updatedTaskFields);$model-&gt;save();
        • 是否有一个-&gt;fill(array $attributes) 更适合更新现有模型?顺便说一句,您可能想使用-&gt;findOrFail(int $id),如果找不到 ID,它将引发异常。不过,这取决于您的用例。
        • 啊,有-&gt;update(array $attributes = [], array $options = []),就是$this-&gt;fill($attributes)-&gt;save($options);
        【解决方案4】:

        我可能会创建对象的新实例,然后以这种方式构建它,然后您实际上可以将一些有用的可重用事物或默认值拆分到模型中,否则将数组推送到模型中并且什么都不做的意义何在- 除了标准化之外,几乎没有。

        我的意思是:

        $topic = new Topic();
        $topic->id = 3489;
        $topic->name = 'Test';
        

        模型只是一个带有public $id; 的类。您还可以设置默认值,因此如果您有 resync_topic 或任何属性,您可以在模型中将其设置为 0,而不是在数组中设置 0。

        【讨论】:

          【解决方案5】:

          您那里似乎有现有模型的数据,所以:

          1. 首先,您可以使用该数组仅填充模型上的fillable(或不填充guarded)属性。请注意,如果 Topic 模型上没有 fillableguarded 数组,您将收到 MassAssignmentException。
          2. 然后根据需要手动分配其余属性。
          3. 最后使用 newInstance 将第二个参数设置为 true 让 Eloquent 知道它是现有模型,而不是实例化一个新对象,因为它会再次在保存时抛出异常(由于唯一索引限制,主键为开始)。

          .

          $topic = with(new Topic)->newInstance($yourArray, true);
          $topic->someProperty = $array['someProperty']; // do that for each attribute that is not fillable (or guarded)
          ...
          $topic->save();
          

          总而言之,这很麻烦,可能您根本不应该这样做,所以问题是:您为什么还是要这样做?

          【讨论】:

          • @deczo.. 我正在处理队列。理想情况下,我想将模型传递给队列,但是当我将模型传递给队列时,它不起作用。当我将它作为数组传递时,一切正常
          • 我认为序列化是解决这个问题的方法。 Model 使用魔术方法 __wakeup 进行反序列化,什么可以为您完成这项工作。不确定序列化对象如何与队列一起工作。请注意,new Topic($array) 不会像我的回答中所说的那样按预期工作。
          • 好吧,我一尝试代码就知道你的意思。你是对的,id 正在被填充,但是 isdirty 是 false,这意味着更新将失败。但是我将不得不遵循您的第二种方法..手动填充属性,这将是一个巨大的痛苦,因为在实施较新的属性时可能会丢失某些属性。
          • 是的,在这个众所周知的地方会很痛苦;)我强烈建议检查是否可以将其序列化。
          • 请给我一些关于这个 __wakeup 的更多信息。似乎我找不到与此相关的任何内容。一定是我无法阅读 laravel 文档。谢谢
          【解决方案6】:

          这是一种通用的方法,不确定是否有特定于 Laravel 的方法——但这很容易实现。

          您的Topic 类及其属性,以及一个构造函数,该构造函数将创建一个新的Topic 对象并根据作为参数传递的$data 数组为其属性分配值。

          class Topic
          {
          
              public $id;
              public $title;
          
              public function __construct(array $data = array())
              {
                  foreach($data as $key => $value) {
                      $this->$key = $value;
                  }
              }
          
          }
          

          像这样使用它:

          $Topic = new Topic(array(
              'id' => 13,
              'title' => 'Marcos',
          ));
          

          输出:

          object(Topic)#1 (2) {
            ["id"]=>
            int(13)
            ["title"]=>
            string(6) "Marcos"
          }
          

          【讨论】:

          • 刚刚查了文档,只要你的类扩展Eloquent,就可以使用@TheShiftExchange的答案。我的例子很好地展示了他的回答。
          【解决方案7】:

          尝试创建一个新对象并将数组传递给构造函数

          $topic = new Topic($array['topic']);
          

          【讨论】:

          • 多少天来第二次了,你帮了我。再次感谢 ! :)
          猜你喜欢
          • 1970-01-01
          • 2014-02-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多