为什么我要在Laravel Eloquent中尝试获取非对象的属性

时间:2017-05-09 13:05:47

标签: php laravel eloquent

我有以下功能:

public function show($id){

    $product = Product::findOrFail($id);
    $product_image = $product->image->file_name.".".$product->image->file_extension;
    return json_encode(array_merge($product->toArray(), ["image" => $product_image]));

}

鉴于id,它将返回以下JSON:

{
  "id": 1,
  "parent_id": 0,
  "category_id": 0,
  "image": "1.png"
}

我有以下功能:

public function index() {

    return json_encode(Product::all());

}

将返回以下JSON:

[
  {
    "id": 1,
    "parent_id": 0,
    "category_id": 0
  },
  {
    "id": 2,
    "parent_id": 0,
    "category_id": 0
  },
  {
    "id": 3,
    "parent_id": 0,
    "category_id": 0
  },
  {
    "id": 4,
    "parent_id": 0,
    "category_id": 0
  }
]

我的函数在Laravel项目中的API的Controller类中。

ProductsController extends Controller

ProductEloquent模型。

我想要实现的是使索引函数返回具有image属性的数组。这是我的尝试:

public function index() {

    $products = Product::all();

    $productsWithImages = [];

    for($i = 0; $i < count($products); $i++) { 
        $product = $products[$i];

        $product_image = $product->image->file_name.".".$product->image->file_extension;

        $productsWithImages[] = array_merge($product->toArray(), ["image" => $product_image]);
    }

    return json_encode(productsWithImages);

}

但是,当我测试我的API时,我收到以下错误:

Trying to get property of non-object

它指向以下行:

$productsWithImages[] = array_merge($product->toArray(), ["image" => $product_image]);

Product模特课:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\File;

class Product extends Model
{

    use SoftDeletes;

    protected $fillable = ['parent_id', 'category_id'];


    // this is for voyager
    public function categoryId() {
        return $this->belongsTo(ProductCategory::class);
    }

    // this is for voyager
    public function parentId() {
        return $this->belongsTo(self::class);
    }

    public function category() {

        return $this->belongsTo(ProductCategory::class);

    }

    public function parent() {

        return $this->belongsTo(Product::class);

    }


    public function files(){

        return $this->hasOne(File::class, 'file_name');

    }


    public function image() {

        return $this->files()->where('table_name', '=', 'products');

    }

}

注意:在此行之上,为清晰起见,我删除了一些产品属性的输出。

print_r($product)的输出:

App\Product Object
(
    [dates:protected] => Array
        (
            [0] => deleted_at
        )

    [fillable:protected] => Array
        (
            [0] => name
            [1] => parent_id
            [2] => category_id
            [3] => alternative_name
            [4] => critical_quantity
            [5] => allowed_increase
            [6] => maximum_purchase_quantity
            [7] => status
            [8] => sort
        )

    [connection:protected] => mysql
    [table:protected] => 
    [primaryKey:protected] => id
    [keyType:protected] => int
    [incrementing] => 1
    [with:protected] => Array
        (
        )

    [perPage:protected] => 15
    [exists] => 1
    [wasRecentlyCreated] => 
    [attributes:protected] => Array
        (
            [id] => 1
            [parent_id] => 0
            [category_id] => 0
            [name] => Apple
            [alternative_name] => 
            [critical_quantity] => 
            [allowed_increase] => 
            [maximum_purchase_quantity] => 
            [status] => 
            [sort] => 
            [created_at] => 
            [updated_at] => 2017-04-23 00:23:46
            [deleted_at] => 
        )

    [original:protected] => Array
        (
            [id] => 1
            [parent_id] => 0
            [category_id] => 0
            [name] => Apple
            [alternative_name] => 
            [critical_quantity] => 
            [allowed_increase] => 
            [maximum_purchase_quantity] => 
            [status] => 
            [sort] => 
            [created_at] => 
            [updated_at] => 2017-04-23 00:23:46
            [deleted_at] => 
        )

    [casts:protected] => Array
        (
        )

    [dateFormat:protected] => 
    [appends:protected] => Array
        (
        )

    [events:protected] => Array
        (
        )

    [observables:protected] => Array
        (
        )

    [relations:protected] => Array
        (
        )

    [touches:protected] => Array
        (
        )

    [timestamps] => 1
    [hidden:protected] => Array
        (
        )

    [visible:protected] => Array
        (
        )

    [guarded:protected] => Array
        (
            [0] => *
        )

    [forceDeleting:protected] => 
)

3 个答案:

答案 0 :(得分:1)

您的某些产品似乎没有附加图像。

public function index()
{
    return Product::all()->map(function ($product) {
        if ($image = $product->image) {
            $image = $image->file_name.'.'.$image->file_extension;
        }

        return $product->toArray() + compact('image');
    });
}

P.S。你不必转换为JSON。 Laravel自动处理这个问题。

答案 1 :(得分:1)

使用Mutators和$appends属性的组合。

将此添加到您的模型:

class Product extends Model
{
    // ...

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = ['image_path'];

    // ...

    /**
     * Get the full path for the product image.
     *
     * @return bool
     */
    public function getImagePath()
    {
        if ($this->image) {
            return $this->image->file_name . "." . $this->image->file_extension;
        }
        return ""; // or any other sensible default
    }

    // ...
}

您可以在此处的文档中了解有关它的更多信息:Eloquent: Serialization - Appending Values To JSON

答案 2 :(得分:1)

更改后尝试:

public function index() {

    $products = Product::all();
    $productsWithImages = [];

    foreach($products as $product) {
        $product_image = !(empty($product->image)) ? $product->image->file_name.".".$product->image->file_extension : '';
        $productsWithImages[] = array_merge($product->toArray(), ["image" => $product_image]);
    }

    return json_encode(productsWithImages);
}