routes.php第113行中的FatalErrorException:在Laravel 5.2中调用null上的成员函数delete()

时间:2017-03-10 01:45:12

标签: php mysql laravel laravel-5

我正在尝试通过routes.php删除文件,但它产生了以下错误:

FatalErrorException in routes.php line 113: Call to a member function delete() on null

这是将功能放在删除按钮中的视图。

<div class="col-md-12 col-xs-12">
        <div class="row">
            @foreach($properties->files as $index=>$file)

                  <div class="col-sm-6 col-md-2">
                    <div class="thumbnail">
                      <img src="{{ URL::asset('uploads/products/' . $file->name) }}" alt="{{ $file->property_id }}" width="300" height="200">
                      <div class="caption">
                        <div class="caption" align="center">
                            <form action="{{ url('file/'.$file->id) }}" method="POST" enctype="multipart/form-data">
                                {{ csrf_field() }}
                                {{ method_field('DELETE') }}
                                <button onclick="return confirm('Está seguro eliminar esta imagen?')" class="button btn btn-danger btn-xs" data-toggle="tooltip" data-placement="top" title="Eliminar imagen"><i class="material-icons delete-white">delete</i></button>
                            </form>
                        </div>
                      </div>
                    </div>
                  </div>           

            @endforeach
        </div>
    </div>

这是我用来删除目录和数据库中文件的路径。

// Delete files
    Route::delete('/file/{id}', function ($id) {
        //File::findOrFail($id)->delete();
        $file = File::find(Input::get('id')->delete());

        $filename= Input::get('upload');
        $path = 'uploads/products/' . $file->filename;

        //return redirect('/');
        return redirect()->back()->with('success', 'Imagen eliminada satisfactoriamente!!!');

    });

3 个答案:

答案 0 :(得分:1)

处理请求输入时,有两种类型的参数:路由参数和查询参数。路由参数是URL的一部分,可用作路由处理程序(闭​​包或控制器方法)的参数,而查询参数来自查询字符串,并通过请求数据(您正在使用的输入外观)提供。 / p>

如上所述,您的代码有两个问题。首先,您的文件ID是路由参数,但您尝试访问它,就像它是一个查询参数一样。其次,您实际上是尝试在id本身上调用delete(),实际上是null,因为它不作为查询参数存在。

您注释掉的行应该可以正常工作:

File::findOrFail($id)->delete();

当您删除File记录时,您似乎也在尝试从文件系统中删除文件。我建议您在deleted()方法中添加File事件,以便每当删除File模型时,它都会从文件系统中删除关联文件。

class File extends Model
{
    public static function boot()
    {
        // make sure to call the parent boot
        parent::boot();

        // this function will be called whenever a File is deleted
        static::deleted(function ($model) {
            // delete the file when the model is deleted. very basic,
            // you'll want to add in more sanity checks, etc.

            // get the file path
            $path = 'uploads/products/' . $model->filename;

            // delete the file
            unlink($path);
        });
    }
}

您还可以使用deleting()事件,该事件将在从数据库中删除文件记录之前触发。如果您这样做,如果文件无法删除,您可以从事件返回false,这将阻止从数据库中删除该记录。

答案 1 :(得分:1)

生成错误是因为您尝试从不存在的输入字段中检索值。您应该阅读文档并查看输入和请求Requests & Input

之间的区别

由于表单中没有输入字段,而您只是在表单请求中传递和id,请更改此

 $file = File::find(Input::get('id'))->delete();

到这个

 $file = File::find(Request::segment(2))->delete();

它现在应该可以正常工作。

<强>更新 确保您的Web路线中有您的模型类。另外,请务必使用请求use Illuminate\Http\Request; 在您的网络路线中使用请求。请执行下列操作: 改变这个

// Delete files
Route::delete('/file/{id}', function ($id) {
    //File::findOrFail($id)->delete();
    $file = File::find(Input::get('id')->delete());

    $filename= Input::get('upload');
    $path = 'uploads/products/' . $file->filename;

    //return redirect('/');
    return redirect()->back()->with('success', 'Imagen eliminada satisfactoriamente!!!');

});

到这个

// Delete files
Route::delete('/file/{id}', use function (Request $request) {

    File::findOrFail($request->segment(2))->delete();

    $filename= Input::get('upload');
    $path = 'uploads/products/' . $file->filename;

    //return redirect('/');
    return redirect()->back()->with('success', 'Imagen eliminada satisfactoriamente!!!');

});

答案 2 :(得分:1)

感谢您的建议,但我决定更改方法来处理这些事件。

1 - 我创建了一个新的控制器(FilesController)并通过控制器我在BD和公共路径中传递了要消除的参数,对于这个控制器,我们使用了destroy方法。

2 - 我从同一个控制器创建一个Route资源。

这是文件模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

use Illuminate\Database\Eloquent\SoftDeletes;

class File extends Model
{
    protected $table = 'files';

    protected $fillable = ['name', 'property_id'];

    // Relation with Property
    public function property()
    {
        return $this->belongsTo('App\Property');
    }
}

这是FilesController方法:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Input;
use Illuminate\Http\Request;

use App\Http\Requests;
use App\File;
use Redirect;
use Storage;

class FilesController extends Controller
{
    public function destroy(Request $request, $id)
    {

        $file = File::find($id);

        $fileName = $file->name;

        //dd($fileName);

        $file_path = public_path() . "/uploads/products/" . $fileName;

        //dd($file_path);

        if(File::exists($file_path))
        { 
            unlink($file_path);
        }

        $file->delete();

        return redirect()->back()->with('success', 'Imagen eliminada satisfactoriamente!!!');

    }
}

路线:

Route::resource('properties','PropertyController');

这是视图中删除文件的部分:

<div class="col-md-12 col-xs-12">
        <div class="row">
            @foreach($properties->files as $index=>$file)

                  <div class="col-sm-4 col-md-2">
                    <div class="thumbnail">
                      <img src="{{ URL::asset('uploads/products/' . $file->name) }}" alt="{{ $file->property_id }}" width="300" height="200">
                      <div class="caption">
                        <div class="caption" align="center">
                            {!! Form::open(['method' => 'DELETE','route' => ['files.destroy', $file->id],'style'=>'display:inline']) !!}

                                {!! Form::hidden('_method', 'DELETE') !!}

                                {!! csrf_field() !!}

                                @permission('role-delete')
                                <button onclick="return confirm('Se eliminara la propiedad de la lista')" class="button btn btn-danger btn-xs" data-toggle="tooltip" data-placement="top" title="Eliminar imagen" data-id="{{$file->id}}"><i class="material-icons delete-white">delete</i></button>
                                @endpermission

                            {!! Form::close() !!}
                        </div>
                      </div>
                    </div>
                  </div>           

            @endforeach
        </div>
    </div>

使用这个简单的表格,我们可以删除数据库和公共路径的图像。

我希望与其他热情的人合作。