2016-08-02 18 views
6

Tôi đang gặp vấn đề lạ trong Yii2 Tôi có một truy vấn có một tham gia với bảng agent và một (một đến nhiều) mối quan hệ của công việc với nhiệm vụ nó hoạt động tốt nhưng vấn đề là nó trả về mọi thứ trong chuỗi. Dưới đây là các truy vấn:Yii2 Active Record JSON response, gõ vấn đề casting

$query = self::find() 
     ->select("job.*, agent.first_name,agent.last_name") 
     ->leftJoin('agent', 'job.agent_id = agent.id') 
     ->with('tasks') 
     ->asArray() 
     ->all(); 

và kết quả JSON mã hóa:

{ 
    "success": true, 
    "data": [ 
    { 
    "id": "10", 
    "customer_id": "1", 
    "job_type": "normal", 
    "created": "2016-06-22 10:19:25", 
    "first_name": "Shayan", 
    "last_name": "", 
    "tasks": [ 
    { 
     "id": "10", 
     "job_id": "10", 
     "title": "bring food", 
     "instruction": null, 
     "created": "2016-06-22 10:19:25", 

    }, 
    { 
     "id": "10", 
     "job_id": "10", 
     "title": "bring pizza", 
     "instruction": null, 
     "created": "2016-06-22 10:19:25", 

    }, 
    ] 
} 

nếu bạn nhận thấy các lĩnh vực như id, customer_id và job_id những tất cả đều nguyên nhưng nó trở lại như chuỗi. Nhưng nếu tôi loại bỏ -> asArray() từ truy vấn trên, nó trả về kiểu nhập hợp lệ nhưng vấn đề là nó bỏ qua các trường bảng quan hệ và leftJoin, nó chỉ trả về các trường bảng công việc ở đây là đáp ứng sau khi xóa -> asArray() từ truy vấn trên.

{ 
"success": true, 
"data": [ 

{ 
    "id": 10, 
    "customer_id": 1, 
    "name": null, 
    "job_type": "normal", 
    "created": "2016-06-22 10:19:25", 
}, 

Nếu bạn nhận thấy ở trên phản ứng không có bảng tác nhân first_name, last_name và các dữ liệu quan hệ bị bỏ qua nhưng id và customer_id là số nguyên.

Có ai gặp phải vấn đề tương tự không? sự giúp đỡ của bạn sẽ được đánh giá cao. Cảm ơn trước.

Trả lời

12

Tôi muốn đảm bảo đó thực sự là trường hợp. Tôi đã tự thử nghiệm bản thân này với truy vấn tương tự và kết quả của tôi khá giống nhau:

array(2) { 
    [0]=> 
    array(5) { 
    ["id"]=> 
    string(1) "1" 
    ["name"]=> 
    string(5) "Admin" 
    // ... 
    } 
// ... 
} 

Trong trường hợp của tôi, tôi cũng nhận được tất cả các loại dưới dạng chuỗi. Vì vậy, nếu bạn định kiểm tra đầu vào và loại của nó với if ($data[0]['id'] === 1), bạn sẽ nhận được kết quả false vì nó là string.

Nhưng những gì bạn cần làm là thêm (int) trước biến để chuyển đổi nó thành kiểu chữ khác nhau. Điều này sẽ là: (int) $data[0]['id'].

Sau đó, var_dump((int) $data[0]['id']); (trong trường hợp của tôi) sẽ cung cấp int(1) thay vì string(1) "1".

Bạn cũng có thể kiểm tra trong điều kiện:

((int) $data[0]['id'] === 1) ? exit('Integer') : exit('Not integer'); 

Nếu không có văn bản (int) như tiền tố sẽ cho Not integer kết quả trong khi với tiền tố sẽ mang lại Integer.

Nếu bạn không muốn giữ lại viết những tiền tố trong mỗi chức năng, bạn có thể viết một cái gì đó như:

$data[0]['id'] = (int) $data[0]['id']; 

Và bây giờ $data[0]['id'] sẽ integer trong sử dụng trong tương lai.


giải pháp mới:

giải pháp mới này sẽ trả về một đối tượng với mảng thay vì chỉ mảng.

// Method that gives data back. In this case, user with ID == 10. 
public static function getData() 
{ 
    $dataProvider = new ActiveDataProvider([ 
     'query' => self::findOne(['id' => 10])->attributes 
    ]); 

    return $dataProvider; 
} 

Trong điều khiển bạn (như mọi khi) vượt qua đối tượng này:

$data = User::getData(); 

return $this->render('user', [ 
      //... 
      'data' => $data 
     ]); 

Và sau đó trong Viewer bạn có thể truy cập vào các giá trị (trong định kiểu đúng) như thế này:

$data->query['columnName']; 

Vì vậy, để kiểm tra ID:

($data->query['id'] === 10 ? exit('ok') : exit('nok')); 

Bạn sẽ nhận được phản hồi ok (typecast: số nguyên, giá trị: 10).

+3

Nên có auto loại đúc thay vì làm nó bằng tay , có cách nào khác không? –

+0

Thật không may, tôi không thấy bất kỳ cách nào để thay đổi điều đó (hoặc ít nhất là tôi không biết điều đó) vì đó là [hành vi mặc định] (https://github.com/yiisoft/yii2/issues/9329#issuecomment- 128343292), theo nhà phát triển. Nhưng nó có thể là một lỗi hoặc một cái gì đó. Tôi cũng đã làm việc với tiền tố, nó không phải là khó để có được sử dụng với nó. –

+1

Nhưng nếu bạn chỉ sử dụng tất cả() thay vì asArray() -> all() nó trả về kiểu dữ liệu hợp lệ nhưng vấn đề là nó chỉ trả về dữ liệu bảng đơn nó bỏ qua quan hệ và tham gia. –

7

này dự kiến ​​hành vi và cũng documented:

Lưu ý: Trong khi phương pháp này giúp tiết kiệm bộ nhớ và cải thiện hiệu suất, nó là gần gũi hơn với giá thấp hơn lớp trừu tượng DB và bạn sẽ mất hầu hết các tính năng Ghi kích hoạt . Một sự khác biệt rất quan trọng nằm trong kiểu dữ liệu của các giá trị cột. Khi bạn trả về dữ liệu trong các bản ghi Active Record, các giá trị cột sẽ được tự động định kiểu theo các kiểu cột thực tế; mặt khác khi bạn trả về dữ liệu trong mảng, giá trị cột sẽ là chuỗi (vì chúng là kết quả của PDO mà không xử lý bất kỳ), bất kể các kiểu cột thực tế của chúng.

Đối với vấn đề thứ hai, để lấy trường bổ sung trong lớp ghi lại hoạt động bạn phải tạo thuộc tính bổ sung trong lớp cho họ:

class MyRecord extends \yii\db\ActiveRecord 
{ 
    public $first_name; 
    public $last_name; 

    // ... 
} 
Các vấn đề liên quan