2016-08-02 6 views
6

मुझे वाईआई 2 में अजीब समस्या का सामना करना पड़ रहा है। मेरे पास एक प्रश्न है जिसमें एक एजेंट तालिका के साथ शामिल है और एक (कई से कई) कार्य के साथ नौकरियों के संबंध में यह ठीक काम करता है लेकिन मुद्दा यह रिटर्न है स्ट्रिंग में सब कुछ।वाईआई 2 सक्रिय रिकॉर्ड जेएसओएन प्रतिक्रिया, प्रकार कास्टिंग समस्या

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

और JSON इनकोडिंग परिणाम:

{ 
    "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", 

    }, 
    ] 
} 

यदि आप आईडी, CUSTOMER_ID जैसे क्षेत्रों नोटिस और इन सभी पूर्णांक हैं job_id लेकिन यह स्ट्रिंग के रूप में वापसी नीचे क्वेरी है। लेकिन अगर मैं उपरोक्त क्वेरी से -> asArray() को हटा देता हूं तो यह वैध प्रकार कास्टिंग लौटाता है लेकिन समस्या यह है कि यह रिलेशनल और बाएं जॉइन एजेंट टेबल फ़ील्ड को छोड़ देती है, यह केवल जॉब टेबल फ़ील्ड्स लौटाती है - उपर्युक्त क्वेरी से -> asArray() को हटाने के बाद प्रतिक्रिया होती है।

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

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

यदि आप प्रतिक्रिया यह एजेंट टेबल FIRST_NAME, LAST_NAME और संबंधपरक डेटा कार्य नहीं है इसके बाद के संस्करण में नोटिस पूरी तरह से छोड़ दिया है, लेकिन आईडी और CUSTOMER_ID पूर्णांक में है।

क्या किसी को भी एक ही समस्या का सामना करना पड़ा है? आपकी मदद की अत्यधिक सराहना की जाएगी। अग्रिम धन्यवाद।

उत्तर

12

मैं यह सुनिश्चित करना चाहता था कि वास्तव में यह मामला है। मैं इस अपने आप को काफी समान क्वेरी के साथ परीक्षण किया है और मेरे परिणाम काफी समान हैं:

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

मेरे मामले में मैं भी सभी प्रकार के तारों के रूप में मिलता है। इसलिए, यदि आप if ($data[0]['id'] === 1) के साथ इनपुट और उसके प्रकार की जांच करने जा रहे हैं, तो आपको false परिणाम मिलेगा क्योंकि यह string है।

लेकिन आपको क्या करना है, इसे (int) जोड़ने से पहले इसे विभिन्न टाइपकास्ट में परिवर्तित करने के लिए है। यह होगा: (int) $data[0]['id']

फिर var_dump((int) $data[0]['id']); (मेरे मामले में) int(1) बजाय string(1) "1" दे देंगे।

तुम भी सशर्त में देख सकते हैं:

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

उपसर्ग के रूप में (int) लेखन Not integer परिणाम दे, जबकि उपसर्ग के साथ Integer निकलेगा जाएगा बिना।

आप प्रत्येक कार्य में इन उपसर्गों लेखन रखने के लिए नहीं करना चाहते हैं, तो आप की तरह कुछ लिख सकते हैं:

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

और अब $data[0]['id'] भविष्य का उपयोग करता है में integer हो जाएगा।


नए समाधान:

इस नए समाधान सिर्फ सरणियों के बजाय सरणियों के साथ एक वस्तु वापस आ जाएगी।

// 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; 
} 

नियंत्रक आप में (हमेशा की तरह) इस वस्तु पारित:

$data = User::getData(); 

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

और फिर व्यूअर में आप मानों तक पहुंच सकता है (सही समान किरदार में) इस तरह:

$data->query['columnName']; 

तो, आईडी चेक के लिए:

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

आपको प्रतिक्रिया मिलेगी ok (टाइपकास्ट: पूर्णांक, मान: 10)।

+3

होनी चाहिए ऑटो प्रकार कास्टिंग के बजाय इसे मैन्युअल रूप से कर रही है , क्या इसका कोई कामकाज है? –

+0

दुर्भाग्यवश, मुझे इसे बदलने का कोई तरीका नहीं दिख रहा है (या कम से कम मुझे इसके बारे में पता नहीं है) क्योंकि यह [डिफ़ॉल्ट व्यवहार] है (https://github.com/yiisoft/yii2/issues/9329#issuecomment- 128343292), डेवलपर के अनुसार। लेकिन यह एक बग या कुछ हो सकता है। मैंने उपसर्गों के साथ भी काम किया, इसका उपयोग करना मुश्किल नहीं है। –

+1

लेकिन यदि आप केवल ऐरे() -> सभी() के बजाय केवल सभी() का उपयोग करते हैं, तो यह वैध डेटाटाइप देता है लेकिन समस्या यह है कि यह केवल एकल तालिका डेटा देता है जो संबंधों को छोड़ देता है और जुड़ता है। –

7

यह अपेक्षित व्यवहार है और यह भी documented:

नोट: हालांकि यह विधि स्मृति बचाता है और प्रदर्शन को बेहतर बनाता है, यह कम डीबी अमूर्त परत के करीब है और आप सक्रिय रिकॉर्ड सुविधाओं का अधिकाधिक खो देंगे । कॉलम मानों के डेटा प्रकार में एक बहुत ही महत्वपूर्ण भेद है। जब आप सक्रिय रिकॉर्ड उदाहरणों में डेटा वापस करते हैं, तो कॉलम मान स्वचालित कॉलम प्रकारों के अनुसार स्वचालित रूप से टाइपकास्ट हो जाएंगे; दूसरी तरफ जब आप सरणी में डेटा वापस करते हैं, कॉलम मान स्ट्रिंग होंगे (क्योंकि वे बिना किसी प्रोसेसिंग के पीडीओ का परिणाम हैं), उनके वास्तविक कॉलम प्रकारों पर ध्यान दिए बिना।

दूसरे अंक के लिए, सक्रिय रिकॉर्ड कक्षा में अतिरिक्त फ़ील्ड को पुनः प्राप्त करने के लिए आप उन्हें कक्षा में अतिरिक्त गुणों बनाने के लिए:

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

    // ... 
} 
संबंधित मुद्दे