【问题标题】:How do I fix the "Call to a member function update() on null" error?如何修复“在 null 上调用成员函数 update()”错误?
【发布时间】:2020-09-13 05:11:39
【问题描述】:

我正在尝试将输入数据从表单中提取到数据库中以运行更新操作。但是,它们是直接指向“$obj->update(request()->all());”行的错误。错误是“在 null 上调用成员函数 update()”。我不太清楚这个错误是什么意思,但我认为这意味着 request()->all() 为空。我想要的输出是在将用户输入更新到数据库后,用户将被重定向到 pageManagement.blade.php,通过 return redirect('/p');然而,当前的输出只是一条错误消息,说明“在 null 上调用成员函数 update()”。

public function update($URI)
{
    $data = request()->validate([
        'title' => 'required',
        'URI' => 'required|min:5|max:10',
        'pageContent' => 'required'
    ]);
    $obj = \App\Page::find($URI);
    $obj->update(request()->all());
    return redirect('/p');
}

这是我的模型 Page.php。

class Page extends Model
{
    protected $fillable = ['title', 'URI', 'pageContent'];
}

这是我在 web.php 中的路由。

Route::patch('/page/{URI}','PageController@update');

这是我供用户输入数据的表单。

<form action="/page/{{ $pageContent->URI }}" method="post">
@csrf
@method('PATCH')
  <label for="title">Title:</label><br>
  <input type="text" id="title" name="title" autocomplete="off" value="{{ $pageContent -> title 
}}"><br>
  @error('title') <p style="color: red">{{ $message }}</p> @enderror
  <label for="URI">URI:</label><br>
  <input type="text" id="URI" name="URI" autocomplete="off" value="{{ $pageContent -> URI }}"> 

@error('URI') {{ $message }} @enderror 页面内容:
页面内容 }}"> @error('pageContent') {{ $message }} @enderror tinymce.init({ 选择器:'#pageContent' })

我的 GitHub 存储库附在下面,因为表单的问题格式看起来有点搞砸了...

https://github.com/xiaoheixi/wfams

感谢您阅读我的问题! :D

【问题讨论】:

  • 错误是“在 null 上调用成员函数 update()”意味着 $obj 为 null。似乎 $obj = \App\Page::find($URI);没有返回您期望的结果
  • 你在调用request(),但是在这个函数中你没有使用Request,public function update($URI)所以改成public function update(Request $request, $URI)
  • 当然,我现在要改变它。
  • 我改了,还是不行。
  • 更改后会出现哪个错误?

标签: php laravel


【解决方案1】:

你正在使用Request,所以你需要在你的函数中调用Request,对于update()方法你可以使用where()来代替:

public function update(Request $request)
{
    $data = $request->validate([
        'title' => 'required',
        'URI' => 'required|min:5|max:10',
        'pageContent' => 'required'
    ]);

    $obj = \App\Page::where('URI', $request->URI)
        ->update([
            'title' => $request->title, 
            'pageContent' => $request->pageContent
        ]);

    return redirect('/p');
}

查看官方文档here

【讨论】:

  • 他可能会改变'URI' @sta,你可以使用路由模型绑定
  • 我尝试观看有关 Route Model Binding 的 YouTube 视频,我不太明白,并且尝试了大约 5 个小时的有关路由模型绑定的所有内容,但不起作用。
  • @DwarfChampion 添加了一个答案以用作练习代码
  • @lagbox 有两个原因。他们调用请求,但没有将其定义到函数中。而 find() 方法通过默认搜索表上的id,对吗?他们正在调用字段URI 这是一个字符串,所以find() 在这里不能做任何事情。
  • find() 方法中没有 update() 方法,直接使用 find() 中的 fill() 方法可以实现 update()。无论如何,我更新了我的答案。
【解决方案2】:

我建议您使用验证规则“exists”验证 URI 是否存在:

  $data = request()->validate([
        'title' => 'required',
        'URI' => 'required|min:5|max:10|exists:pages,URI',
        'pageContent' => 'required'
    ]);

现在,如果 URI 在您的 pages 表中不存在,laravel 将返回一个验证错误,并显示类似“指定的 URI 在表页面中不存在”的消息

【讨论】:

  • 我有一个问题,它说现在的错误是“未定义的变量:URI”。
  • php artisan route:list ,找到你的路由'page/'并确保参数名发送到更新方法
  • @OMR 我猜他没有将 getRouteKeyName() 设置为 'URI'
【解决方案3】:

我看到了你的 github https://github.com/xiaoheixi/myFirstWebsite

在控制器中使用模型绑定示例:

Route::patch('/page/{URI}','PageController@update');
Route::get('{URI}', 'PageController@getPage');
public function update($URI)
{
    $data = request()->validate([
        'title' => 'required',
        'URI' => 'required|min:5|max:10',
        'pageContent' => 'required'
    ]);
    $obj = \App\Page::find($URI);
    $obj->update(request()->all());
    return redirect('/p');
}

将控制器更改为:

use App\Page;

public function getPage(Page $URI)
{
    return view('page_view', compact('URI'));
}

public function update(Request $request, Page $URI)//match $URI to {URI}
{
    $data = $request->validate([
        'title' => 'required',
        'URI' => 'required|min:5|max:10|unique:pages,URI,'.$URI->id, //you dont want a duplicate URI when you search a page by URI
        'pageContent' => 'required'
    ]);
    
    $URI->update($request->all());
    return redirect('/p');
}

在刀片中:

<form action="/page/{{ $pageContent }}" method="post">

在模型中:

use Illuminate\Database\Eloquent\Model;

class Page extends Model
{
    protected $fillable = ['title', 'URI', 'pageContent'];
    public function getRouteKeyName()
    {
        return 'URI';
    }
}

【讨论】:

    【解决方案4】:

    错误意味着find 返回了null。这是有道理的,因为 find 将尝试搜索主键字段而不是 URI 字段。

    我不会使用URI 作为该记录的标识符。我会使用它的id

    <form action="/page/{{ $pageContent->id }}" method="post">
    
    Route::patch('/page/{page}','PageController@update');
    

    这会大大简化事情。现在您可以轻松地使用路由模型绑定来为您获取此Page

    use App\Page;
    ...
    
    public function update(Page $page)
    {
        $data = request()->validate([
            'title' => 'required',
            'URI' => 'required|min:5|max:10',
            'pageContent' => 'required'
        ]);
    
        $page->update(request()->all());
    
        return redirect('/p');
    }
    

    这将确保$page 是现有模型实例。既然是这种情况,您可以致电update。只需确保 titleURIpageContent 是“可填充的”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      • 2021-11-27
      相关资源
      最近更新 更多