簡體   English   中英

Laravel 4 Eloquent返回錯誤的ID

[英]Laravel 4 Eloquent returns wrong ID

我的數據庫中有3個表:

  1. 廣告活動
  2. 用戶
  3. 公司

一家公司可能有一些用戶。 一個用戶可能有一些活動。 用戶(具有管理員權限)可以對屬於其公司的任何廣告系列執行某些操作。 所以,我想檢查他是否正在與他的競選活動一起做這些行動(在最后一種情況下,我返回的內容如“拒絕訪問”)。

我的病情

Campaign::join('users', 'users.id', '=', 'campaigns.user_id')
        ->where('users.company_id', '=', Auth::user()->company->id)
        ->where('campaigns.id', '=', Input::get('id'))
        ->first();

因此,如果我獲得了獨特的廣告系列 - 沒關系,如果我得到了空 - 出了點問題,我向用戶發送了“拒絕訪問權限”,因為他正在處理其他公司廣告系列。

此代碼生成下一個查詢:

array(3) {
  ["query"]=>
  string(148) "select * from `campaigns` inner join `users` on `users`.`id` = `campaigns`.`user_id` where `users`.`company_id` = ? and `campaigns`.`id` = ? limit 1"
  ["bindings"]=>
  array(2) {
    [0]=>
    string(1) "2"
    [1]=>
    string(2) "13"
  }
  ["time"]=>
  float(0.42)
}

使用phpmyadmin我嘗試了相同的查詢並獲得了ID = 13的廣告系列。但是當我調試我的應用程序時,我發現了這一點

dd($campaign->id);

而是返回8。 8也等於campaigns.user_id (該記錄同時包含campaigns.idcampaigns.user_id = 8 )。

我無法弄清楚為什么會這樣。 即使我的SQL查詢有問題(我懷疑是phpmyadmin返回正確的結果),我得到的條件為campaigns.id = Input::get('id') ,其中Input::get('id') = 13 為什么id正在改變?

當然,我可以通過兩個步驟進行安全檢查,比如先獲得廣告系列,然后檢查$campaign->user->company->id = Auth::user()->company->id但只是想知道......

如果您在phpMyAdmin中運行此查詢,您應該可以看到結果包含名稱為“ id ”的多個列。 當PHP將查詢結果解析為關聯數組或對象時,鍵必須是唯一的! 如果鍵發生碰撞,將使用最后一列!

例:

SQL結果:

id    user_id    name    id    name    company_id
1     2          Camp1   2     Pelle   1

PHP結果:

array (size=1)
  0 => 
    object(stdClass)[131]
      public 'id' => string '2' (length=1)
      public 'user_id' => string '2' (length=1)
      public 'name' => string 'Pelle' (length=5)
      public 'company_id' => string '1' (length=1)

要解決此問題,您可以添加一個select子句,僅選擇廣告系列列:

Campaign::select('campaigns.*')
    ->join('users', 'users.id', '=', 'campaigns.user_id')
    ->where('users.company_id', '=', Auth::user()->company->id)
    ->where('campaigns.id', '=', Input::get('id'))
    ->first();

這似乎是Eloquent庫中的限制。 它不應該使用最后一個“id”,而是應該更主動地搜索查詢主表的“id”。 或者在SQL語句中使用“as”。

另一種解決方案是唯一地命名每個表的id字段。 例如user.user_id,campaigns.campaign_id。 這將與其他表中的外鍵沖突,因此將外鍵命名為campaigns.user_fid。

如果要控制使用重復列的實際表,只需按特定順序將表添加到數組中。 最后一個是->id屬性。

        ->select([
            'table1.*',
            'table2.*',
            'tags.*',
            'companies.*',
            'users.*',
        ])

這樣,您可以保留使用join選擇的所有唯一列。 如果您想要特定表中的特定列,您可以使用AS

        ->select([
            'table1.*',
            'table2.*',
            'tags.*',
            'companies.*',
            'users.*',
            'table1.id AS table1_id',
            'tags.name AS tag_name',
            'companies.name AS company_name',
        ])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM