如何修复 laravel 5.3 中的字符串调用成员函数 diffForHumans()

How to fix it Call to a member function diffForHumans() on string in laravel 5.3

为什么我改用query builder函数diffForHumans()会报错,而用ELoquent ROM却没有报错,有办法解决吗? (我该如何解决)谢谢

diffForHumans()

这是ArticlesController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Article;
use Carbon\Carbon;
use Auth;
use DB;

class ArticlesController extends Controller
{

    public function index()
    {
        $articles =DB::table('articles')->get();
        $articles = ['articles'=>$articles];
        return view('articles.index',$articles);
    }
}

这是型号Article.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\SoftDeletes;

class Article extends Model
{
    //
    use SoftDeletes ;

    protected $fillable = [
        'user_id','content','live','post_on',
    ];

    protected $dates =[
        'post_on','deleted_at','created_at','updated_at',
    ];

    public function setLiveAttribute($value)
    {
        $this->attributes['live'] = (boolean)($value);
    }

    public function getShortContentAttribute()
    {
        return substr($this->content,0,random_int(60,150))."...";
    }

    public function setPostOnAttribute($value)
    {
        $this->attributes['post_on'] = Carbon::parse($value);
    }

    public function setCreatedAtAttribute($value)
    {
        $this->attributes['post_on'] = Carbon::parse($value);
    }



}

这是我的代码,我该如何修复它? 谢谢

我注意到你的代码中有几点,

  • 不需要将 created_atupdated_at 转换为日期,它们已经被转换并且是 Carbon
  • 的实例
  • 您可以使用 属性 $casts 来转换简单的属性,例如 live
  • 无需为 post_on 日期添加突变器,因为您将其添加到 $dates
  • 你还在 created_at 而不是 post_on 上设置了一个突变器,你使用 SetCreatedAttribute 而不是 setPostOnAttribute
  • 您可以使用 Laravel 的 str_limit 辅助函数代替 substr($this->content,0,random_int(60,150))."...",同时将 random_int 更改为 rand => int rand ( int $min , int $max )

查询生成器 return dates 作为字符串,你需要在使用它们之前进行解析,否则你会得到像这样的错误 PHP error: Call to a member function on string,就这样做吧:

\Carbon\Carbon::parse(\DB::table('articles')->first()->post_on)->diffForHumans()

您可以像这样简化您的模型:

<?php

namespace App;

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

class Article extends Model
{
    use SoftDeletes ;

    protected $fillable = [
        'user_id','content','live','post_on',
    ];

    protected $dates = [
        'post_on','deleted_at'
    ];

    protected $casts = [
        'live'  => 'boolean'
    ];

    public function getShortContentAttribute()
    {
        return str_limit($this->content, rand(60,150));
    }
}

您也可以像这样简化 index 方法:

public function index()
{
    $articles = DB::table('articles')->get();

    return view('articles.index', compact('articles'));
}

默认情况下 eloquent returns date/time 字段作为 Carbon 实例,而查询构建器则不需要。因此,如果您想在查询构建器返回的 属性 上使用 Carbon,则必须使用 Carbon::parse() 方法包装 属性。

例如,我可以在 eloquent 结果上使用 Carbon 的方法之一 toCookieString(),例如

echo App\User::find(1)->created_at->toCookieString();

这将给出这样的响应 Thursday, 10-Aug-2017 17:59:53 UTC。但是,如果我改用查询生成器,例如

echo DB::table('users')->find(1)->created_at->toCookieString();

然后会报错

Call to a member function toCookieString() on string

为了在这里使用 Carbon,我用 Carbonparse() 方法包装了 属性。

echo Carbon\Carbon::parse(DB::table('users')->find(1)->created_at)->toCookieString();

这将给出所需的结果 eloquent。