Laravel“尝试获取非对象的属性”使用数据库值设置数组

时间:2015-03-10 09:32:08

标签: php laravel

我正在尝试用PHP解决这个错误,我对语言并不完全熟悉,所以如果你能帮我解决这个问题会很好,我无法弄清楚这个错误。< / p>

我在这里有这个代码:

    public function index() {
    $counterino = ClientsJobs::all()->count();
    $MasterArray = array();
    /* Go Through All of the Records in the Client-Jobs Table and Resolve their columns to Desired Names */
    for ($i = 1; $i <= $counterino; $i++ ) {
        //Temporary Array for one Name-Resolved-Row of the Table.
        $tempArray = array(
            'id'          => ClientsJobs::find( $i )->id,              // id
            'client_name' => ClientsJobs::find( $i )->clients->fname , // get the first name ( based on fk )
            'job_name'    => ClientsJobs::find( $i )->jobs->name,      // get the name of the job ( based on fk )
            'wage'        => ClientsJobs::find( $i )->wage,            // wage for the job
            'productivity'=> ClientsJobs::find( $i )->producivity      // productivity level for the job
        );
        $MasterArray[] = $tempArray; //add the row
    }
    return $MasterArray;
}

此代码更改ClientsJobs Junction Table中列的名称。

public function up()
{
    Schema::create('clients-jobs', function(Blueprint $table)
    {
        $table->increments('id')->unsigned(); 
        $table->integer('client_id')->unsigned();
        $table->foreign('client_id')->references('id')->on('clients');
        $table->integer('job_id')->unsigned();
        $table->foreign('job_id')->references('id')->on('jobs');
        $table->decimal('wage', 4, 2);
        $table->decimal('productivity', 5, 2); // 0.00 - 100.00 (PERCENT)
        $table->timestamps();
    });
}

作业和客户表非常简单。

我在上面发布的index()函数中有错误,它说

'试图获取非对象的属性'

从线上开始

'client_name' => ClientsJobs::find( $i )->clients->fname,

对于设置阵列的其他部分,我也很生气。

我已经测试了我用来设置数组的各个函数,它们都工作,fname也应该返回一个字符串,我使用dd()来获取值。

我试过了:

- 使用FindorFail

- 在没有for循环的情况下设置数组并手动设置每个元素

- 抛出函数的多个部分以确保它的工作原理(counterino,数组的所有函数,......)

我的猜测是它与PHP的类型推导有关,我实际上只需要一个字符串数组,但仍然想使用名称映射,因为我将传递这个我正在使用的视图我的其他一些东西。该代码实际上工作得更早,但我以某种方式打破它(添加新记录或运行作曲家更新?)无论如何,还有一些严重的伏都教。

在预先感谢您的帮助下,我正在为非营利组织免费开展这个项目。

P.S。我正在使用Laravel 4.2和Platform 2.0

2 个答案:

答案 0 :(得分:1)

首先,这是一个可怕的做法:

    $tempArray = array(
        'id'          => ClientsJobs::find( $i )->id,              // id
        'client_name' => ClientsJobs::find( $i )->clients->fname , // get the first name ( based on fk )
        'job_name'    => ClientsJobs::find( $i )->jobs->name,      // get the name of the job ( based on fk )
        'wage'        => ClientsJobs::find( $i )->wage,            // wage for the job
        'productivity'=> ClientsJobs::find( $i )->producivity      // productivity level for the job
    );

通过多次调用ClientJobs::find($i),您可以多次执行相同的查找 - 无论是对您的数据库,还是对您的缓存层进行配置。

其次,您的问题的答案取决于您的ClientJobs模型。为了您的示例,它需要:

  • 有效的clients关系,定义如下:

     public function clients()
     {
         return $this->hasOne(...);
     }
    
  • clients也需要是有效的1:1 始终存在关系。即必须始终有一个客户。如果没有,你很容易受到你刚刚得到的错误的影响(因为`客户魔法最终会变为空)

同样适用于jobs

在每种情况下,最好确保先设置好所有内容。请使用以下方法检查:

$clientJob = ClientJobs::find($i);
if (!$clientJob->clients || $clientJob->jobs) throw new \RangeException("No client or job defined for ClientJob $i");

然后在您喜欢的任何级别捕获异常。

最佳方法

public function index() {
  $masterArray = array();
  ClientsJobs::with('clients', 'jobs')->chunk(200, function($records) use (&$masterArray) {
      foreach ($records as $record) {
        $masterArray[] = array(
          'id'          => $record->id,              // id
          'client_name' => !empty($record->clients) ? $record->clients->fname : null,
          'job_name'    => !empty($record->jobs) ? $record->jobs->name : null,
          'wage'        => $record->wage,
          'productivity'=> $record->productivity,
        );
      }
  });
  return $MasterArray;
}

答案 1 :(得分:1)

你的做法非常错误 如果你想返回一个数组,你可以这样做

$counterino = ClientsJobs::all()->toArray();

这将从表中获取所有行,并且toArray会将对象转换为数组