尝试从数据库laravel获取数据时未定义的变量

时间:2017-10-16 03:39:34

标签: php laravel laravel-5

我在控制器中添加新功能后,无法从数据库中获取数据。任何人都可以向我解释这个错误,我该怎么办?

背景信息:我有3种不同类型的表,personal_infos,user_infos和user_info1s表,其中personal_infos有很多user_infos和user_info1s。我使用user_id作为外键与personal_infos表链接

我使用this video作为参考,并希望做一些像他的最终结果(见视频的17.17),但我收到此错误:

Error: Undefined variable: data

我想做什么:enter image description here Route.php

Route::get('/home/{id}', 'HomeController@getData')->name('home');

的HomeController

public function getData($id) {
    $data['data'] = DB::table('personal_infos')->get()->sortByDesc('upload_time');

    if (count($data) > 0) {
        return view('home',$data)
            ->with('test', personal_info::find($id)); // --> after adding this got error
    } else {
        return view('home');
    }
}

Home.blade.php

<table class="table table-bordered">
  <tr>
    <th><strong><big>Name: </big></strong></th>
  </tr>
  <td>
  <tr>
    @foreach($data as $value)
  <tr>    
  <th>{{HTML::link_to_route('home',$value->Name, array($value->id)) }}</th>              
  </tr>
    @endforeach
  </tr>
  </tr>
</table>

我在更改后的代码:

HomeController中:

   public function getData($id = null){

        $data['data'] = DB::table('personal_infos')->orderBy('created_at', 'desc')->get();
        return view('home') 
    ->with('personalInfos', $personalInfos) 
    ->with('test', personal_info::find($id));

} }

home.blade.php

<ul>
    @foreach ($personalInfos as $info) 
        <li>{{ HTML::link_to_route('home', $info->Name, [ $info->id ]) }}</li>
    @endforeach 
</ul>

路线

Route::get('/home/{id?}', 'HomeController@getData')->name('home');

personal_info模型:(如果需要,不知道,以防万一)

class personal_info extends Eloquent
{
    protected $fillable = array('Email', 'Name', 'Mobile_No');
    protected $table = 'personal_infos';
    protected $primaryKey = 'id';
    public function user_infos() {
        return $this->hasMany('App\user_info','user_id');
    }
        public function user_info1s() {
        return $this->hasMany('App\user_info1','user_id');
    }
}

user_info1和user_info(它们相似,所以我只放1个)

class user_info1 extends Eloquent
{
            protected $fillable = array('hobby','sport','user_id');
    public function personal_infos() {
        return $this->belongsTo('App\personal_info', 'user_id', 'id');
    }
}

2 个答案:

答案 0 :(得分:1)

我可以告诉你正在学习Laravel。您的问题中发布的代码存在多个问题。让我们逐步了解每一个,看看我们是否可以提高您的理解力。

首先,让我们看一下控制器方法签名:

public function getData($id) 

此方法需要在相应路由中定义$id参数。但是,如果我们看看路线:

Route::get('/home/(:any)', 'HomeController@getData')->name('home'); 

...它没有正确地声明URL包含一个参数(您正在观看的视频是关于Laravel的一个非常旧的版本)。如the docs中所述,我们需要更改路由签名以包含$id的参数:

Route::get('/home/{id}', 'HomeController@getData')->name('home');

接下来,让我们看看控制器方法如何获取其数据:

$data['data'] = DB::table('personal_infos')->get()->sortByDesc('upload_time');

此查询将personal_infos中的所有记录提取到Collection,然后按upload_time对其进行排序。这很好,但数据库引擎通常可以比我们的PHP应用程序更快地对数据进行排序,因此我们可以指示数据库为我们排序数据:

$data['data'] = DB::table('personal_infos')->orderBy('upload_time', 'desc')->get();

注意我们如何将对集合的sortByDesc()的调用更改为orderBy()以进行数据库查询。现在,数据库为我们排序结果,因此集合不需要。

最后,让我们尝试修复将数据传递给视图时遇到的错误。以下是您的控制器方法目前的工作方式:

if (count($data) > 0) {
    return view('home', $data)
        ->with('test', personal_info::find($id)); // --> after adding this got error
} else {
    return view('home');
}

上面的代码存在一些问题:

  1. count($data) 始终大于零,因为我们每次调用方法时都会设置$data['data'],因此else块将永远不会执行。这可能很好,因为......
  2. ...当count($data)等于零时,控制器不会传递视图任何数据,因此视图中的$data将为undefined
  3. 有问题的视图使用@foreach循环遍历每个结果,因此我们可以简化控制器方法中的代码,因为foreach不会迭代空集合:

    $personalInfos = DB::table('personal_infos')->orderBy('upload_time', 'desc')->get();
    
    return view('home') 
        ->with('personalInfos', $personalInfos) 
        ->with('test', personal_info::find($id));
    

    视图将从上述方法中收到两个变量:$personalInfos$test。我冒昧地将$data['data']重命名为更有意义的变量。随着项目的发展,这变得非常重要。以下是我们如何在视图中使用数据:

    <ul>
        @foreach ($personalInfos as $info) 
            <li>{{ HTML::link_to_route('home', $info->Name, [ $info->id ]) }}</li>
        @endforeach 
    </ul>
    

    上面的模板输出一个无序列表,如问题中的图像所示。原始表包含多个行/列嵌套错误,并且不会显示问题所描述的信息。我们可以看到,此模板循环遍历$personalInfos中的每个结果。如果$personalInfos为空,则列表不会显示任何项目。

    如果我们希望我们的控制器方法使用或不使用 ID来处理路径,我们需要告诉Laravel该ID是可选的。对于路线,参数后面的问号(?)使其成为可选:

    Route::get('/home/{id?}', 'HomeController@getData')->name('home');
    

    然后,我们可以为处理路径的控制器方法设置默认值。在这种情况下,我们将使用null

    public function getData($id = null) 
    

    当然,在我们更新之后,我们需要更改方法来处理null $id参数,我们使用该参数为视图{{{{1}获取personal_info 1}}变量。这个问题没有解释视图如何使用$test,因此我将此作为练习留给读者:)

答案 1 :(得分:0)

以下是将多个变量传递给view的两种方法:

//Passing variable to view using with Method
return view('home')->with(['test'=>personal_info::find($id),'data'=>$data['data']]);

//Passing variable to view using Associative Array
return view('home', ['test'=>personal_info::find($id),'data'=>$data['data']]);