【问题标题】:Laravel toArray() still returning an object in DB::rawLaravel toArray() 仍然在 DB::raw 中返回一个对象
【发布时间】:2017-05-17 18:25:10
【问题描述】:

我有这个代码:

 $response['data'] = DB::table('customers')
                ->select(DB::raw('name,email,address1,address2,postalcode,state_region,country_code,phone,created_at'))
                ->where('user_id',"=",Auth::user()->id)
                ->where('name','like',"%$search_value%")
                ->orWhere('address1',"%$search_value%")
                ->orWhere('email','like',"%$search_value%")
                ->orWhere('address2','like',"%$search_value%")
                ->orWhere('city','like',"%$search_value%")
                ->orWhere('postalcode','like',"%$search_value%")
                ->orWhere('state_region','like',"%$search_value%")
                ->orWhere('country_code','like',"%$search_value%")
                ->orWhere('phone','like',"%$search_value%")
                ->orderBy('name', $order)
                ->limit($length)
                ->offset($start)
                ->get()->toArray();

这个结果是这样的:

'data' => 
    array (size=10)
      0 => 
        object(stdClass)[194]
          public 'name' => string '|Barbara User' (length=13)
          public 'email' => string 'email@email.com' (length=16)
          public 'address1' => string 'address aaddress' (length=17)
          public 'address2' => null
          public 'postalcode' => string '00000000' (length=10)
          public 'state_region' => string 'GA' (length=2)
          public 'country_code' => string 'US' (length=2)
          public 'phone' => string '12312312312' (length=10)
          public 'created_at' => string '2017-01-02 15:20:20' (length=19)
      1 => 
        object(stdClass)[201]
            public 'name' => string '|Barbara User' (length=13)
          public 'email' => string 'email@email.com' (length=16)
          public 'address1' => string 'address aaddress' (length=17)
          public 'address2' => null
          public 'postalcode' => string '00000000' (length=10)
          public 'state_region' => string 'GA' (length=2)
          public 'country_code' => string 'US' (length=2)
          public 'phone' => string '12312312312' (length=10)
          public 'created_at' => string '2017-01-02 15:20:20' (length=19)
    ....

如您所见,即使我已经做了toArray(),结果中仍然有一个对象。

这里似乎有什么问题?

您的帮助将不胜感激!谢谢!

【问题讨论】:

    标签: php arrays laravel


    【解决方案1】:

    toArray 正在将对象集合更改为对象数组,就像它应该做的那样。如果希望集合内的对象也是数组,则需要先对每个对象进行转换:

    $users = DB::table('users')->where([...])->take(1)->get();
    
    $array = $users->map(function($obj){
        return (array) $obj;
    })->toArray();
    

    【讨论】:

      【解决方案2】:

      当您在Collection 上调用toArray() 时,如果底层项目实现Illuminate\Contracts\Support\Arrayable 接口,则集合将尝试在每个项目上调用toArray()。但是,当您使用查询生成器时,结果将是stdClass 对象中的Collection,而stdClass 对象是没有实现该接口且没有toArray() 方法的普通对象。因此,当您在 CollectionstdClass 对象上调用 toArray() 时,您只会得到 stdClass 对象的普通数组。

      如果您改用 Eloquent,定义 Customer 模型,并使用该模型执行查询,您的结果将是 Customer 模型中的 Collection,并且这些模型确实实现了 Arrayable 接口。因此,当您在此 Collection 上调用 toArray() 时,它将在 Collection 中的每个项目上调用 toArray(),您的结果将是一个数组数组。

      如果出于某种原因不想使用 Eloquent,则需要手动将项目从对象转换为数组。您可以使用Collection 上的maptransform 方法轻松完成此操作。如果您想返回一个新的Collection 并保留原来的map,请使用map,如果您只想修改原来的Collection,请使用transform

      $response['data'] = DB::table('customers')  
          // query conditions, etc
          ->get()
          ->map(function ($item, $key) {
              return (array) $item;
          })
          ->all();
      

      【讨论】:

      • 这是最好的答案。我不知道集合尝试在每个项目上调用 toArray()。
      【解决方案3】:

      您正在将集合转换为数组,而不是具体的每个模型。

      你可以使用 Laravel 的集合 ->transform() 方法来做这样的事情:

          $response['data'] = DB::table('customers')
                  ->select(DB::raw('name,email,address1,address2,postalcode,state_region,country_code,phone,created_at'))
                  ->where('user_id',"=",Auth::user()->id)
                  ->where('name','like',"%$search_value%")
                  ->orWhere('address1',"%$search_value%")
                  ->orWhere('email','like',"%$search_value%")
                  ->orWhere('address2','like',"%$search_value%")
                  ->orWhere('city','like',"%$search_value%")
                  ->orWhere('postalcode','like',"%$search_value%")
                  ->orWhere('state_region','like',"%$search_value%")
                  ->orWhere('country_code','like',"%$search_value%")
                  ->orWhere('phone','like',"%$search_value%")
                  ->orderBy('name', $order)
                  ->limit($length)
                  ->offset($start)
                  ->get();
      
          $response['data']->transform(function ($item) {
              // return $item->toArray(); // You could do this if you called the query with model
              return (array)$item; // This should work in your case 
          });
      

      这样 $response['data'] 将是数组的集合(不是数组)。您还可以这样做:

      $response['data']->toArray();
      

      将集合也转换为数组。

      【讨论】:

      • 我在您的$item->toArray(); 中收到了Call to undefined method stdClass::toArray()
      • 这很有趣。我测试了类似的代码(用 Model 而不是 \DB::table() 调用)并且它有效。然后我认为 Amit Gupta 的回答应该有效。
      • 如果查询是使用 Eloquent Model 执行的,则不需要这样做。模型实现了Arrayable 接口,因此在Collection 上调用toArray() 将自动在各个项目上调用toArray()
      【解决方案4】:

      您可以将集合中的每个对象类型转换为数组:

      $response['data']->transform(function($x) {
         return (array) $x; 
      })->toArray();
      

      toArray 将您从集合中带回数组。

      【讨论】:

        猜你喜欢
        • 2020-05-22
        • 2018-07-06
        • 2018-10-24
        • 2020-03-11
        • 1970-01-01
        • 2014-12-05
        • 2016-09-27
        • 1970-01-01
        • 2019-01-10
        相关资源
        最近更新 更多