2017-03-31 140 views
0

我正在處理一個涉及通過JSON將數據「配置文件」傳遞到Web應用程序的項目。我使用CakePHP 3.0並且對它很新穎。我存儲配置文件在MySQL數據庫中,並可以很容易地查詢數據,並把它變成一個基本的JSON格式,每行是在JSON一個單獨的值:複雜的JSON與Cakephp 3

Controller.php這樣:

.... 
public function getProfileData() 
    { 
     $uid = $this->Auth->user('id'); 
     $this->loadComponent('RequestHandler'); 
     $this->set('profile', $this->MapDisplay->find(
      'all', 
      ['conditions' => 
       ['MapDisplay.user_id =' => $uid] 
      ] 
     ) 
     ); 
     $this->set('_serialize', ['profile']); 
    } 
.... 

get_profile_data .ctp:

<?= json_encode($profile); ?> 

它返回是這樣的:

{ 
"profile": [ 
    { 
     "alert_id": 1, 
     "alert_name": "Test", 
     "user_id": 85, 
     "initialized_time": "2017-03-24T00:00:00", 
     "forecasted_time": "2017-03-24T00:10:00", 
     "minimum_dbz_forecast": 0, 
     "maximum_dbz_forecast": 10, 
     "average_dbz_forecast": 5, 
     "confidence_in_forecast": 0.99, 
     "alert_lat": 44.3876, 
     "alert_lon": -68.2039 
    }, 
    { 
     "alert_id": 1, 
     "alert_name": "Test", 
     "user_id": 85, 
     "initialized_time": "2017-03-24T00:00:00", 
     "forecasted_time": "2017-03-24T00:20:00", 
     "minimum_dbz_forecast": 5, 
     "maximum_dbz_forecast": 15, 
     "average_dbz_forecast": 10, 
     "confidence_in_forecast": 0.99, 
     "alert_lat": 44.3876, 
     "alert_lon": -68.2039 
    }, 
    { 
     "alert_id": 2, 
     "alert_name": "Test2", 
     "user_id": 85, 
     "initialized_time": "2017-03-24T00:00:00", 
     "forecasted_time": "2017-03-24T00:10:00", 
     "minimum_dbz_forecast": 10, 
     "maximum_dbz_forecast": 20, 
     "average_dbz_forecast": 15, 
     "confidence_in_forecast": 0.99, 
     "alert_lat": 44.5876, 
     "alert_lon": -68.1039 
    }, 
    { 
     "alert_id": 2, 
     "alert_name": "Test2", 
     "user_id": 85, 
     "initialized_time": "2017-03-24T00:00:00", 
     "forecasted_time": "2017-03-24T00:20:00", 
     "minimum_dbz_forecast": 15, 
     "maximum_dbz_forecast": 25, 
     "average_dbz_forecast": 35, 
     "confidence_in_forecast": 0.99, 
     "alert_lat": 44.5876, 
     "alert_lon": -68.1039 
] 
} 

我^ h選擇A)輕鬆調用單個配置文件,而不是搜索唯一的配置文件ID和B)只需加載一個JSON文件即可獲取所有配置文件內容。這樣的輸出會更理想:

{ 
"profile": [ 
    { 
     "alert_id": 1, 
     "alert_name": "Test", 
     "initialized_time":"2017-03-24T00:00:00", 
     "alert_lat": 44.3876, 
     "alert_lon": -68.2039, 
     "profile_data": [ 
      { 
       "forecasted_time": "2017-03-24T00:10:00", 
       "minimum_dbz_forecast": 0, 
       "maximum_dbz_forecast": 10, 
       "average_dbz_forecast": 5, 
       "confidence_in_forecast": 0.99 
      }, 
      { 
       "forecasted_time": "2017-03-24T00:20:00", 
       "minimum_dbz_forecast": 5, 
       "maximum_dbz_forecast": 15, 
       "average_dbz_forecast": 10, 
       "confidence_in_forecast": 0.99 
      } 
     ] 
    }, 
    { 
     "alert_id": 2, 
     "alert_name": "Test2", 
     "initialized_time": "2017-03-24T00:00:00", 
     "alert_lat": 44.5876, 
     "alert_lon": -68.1039, 
     "profile_data": [ 
      { 
       "forecasted_time": "2017-03-24T00:10:00", 
       "minimum_dbz_forecast": 10, 
       "maximum_dbz_forecast": 20, 
       "average_dbz_forecast": 15, 
       "confidence_in_forecast": 0.99 
      }, 
      { 
       "forecasted_time": "2017-03-24T00:20:00", 
       "minimum_dbz_forecast": 15, 
       "maximum_dbz_forecast": 25, 
       "average_dbz_forecast": 35, 
       "confidence_in_forecast": 0.99 
      } 
     ] 
    } 
] 
} 

我該如何去查詢我的數據庫並填充此JSON結構?有沒有任何CakePHP工具可以幫助你做到這一點?將JSON重構爲這種結構似乎有意義嗎?

在此先感謝!

+0

看起來你有大量的重複數據你的數據庫,也就是說你的模式不像標準化那樣!! – ndm

+0

這是真的 - 我試圖讓它只使用一張表(看起來好像更容易),然後將數據分成兩個表,並在一個表中使用alert_id,alert_name,initialized_time,alert_lat和alert_lon兩個表和另一個表中的alert_id,forecasted_time,minimum_dbz_forecast,maximum_dbz_forecast,average_dbz_forecast和confidence_in_forecast(兩個「alert_id」彼此對應)。在後一種情況下將這個JSON放在一起會更容易嗎? – WXMan

+2

最有可能的是,是的。您只需要正確設置[**關聯**](https://book.cakephp.org/3.0/en/orm/associations.html),並且[**包含**](https: //book.cakephp.org/3.0/en/orm/query-builder.html#loading-associations)查找中的關聯表,如果關聯的屬性名稱爲'profile_data',則不會甚至不得不修改結果。 – ndm

回答

0

感謝用戶ndm,我意識到我的方法存在一些問題。我認爲將一張表中的所有數據都簡化了,但事實上它會使事情變得更加複雜並且需要冗餘數據存儲(例如,爲每個配置文件條目存儲經度和緯度值,而不是在單獨的表中存儲一次)。

NDM也在你找到提到

你只需要建立associations正常,並contain關聯>表格,並在情況下的關聯屬性的名稱將是> profile_data,你根本不需要修改結果。

改變表型號文件後,我有這個新的 「ProfileDataTable.php」 文件:

class ProfileDataTable extends Table 
{ 

/** 
* Initialize method 
* 
* @param array $config The configuration for the Table. 
* @return void 
*/ 
public function initialize(array $config) 
{ 
    parent::initialize($config);   

    $this->setTable('profile_data'); 

    $this->setDisplayField('title'); 
    $this->setPrimaryKey('alert_id'); 
    $this->addBehavior('Timestamp'); 

    $this->belongsTo('AlertData', [ 
     'foreignKey' => 'alert_id' 
    ]); 
} 

} 

而這個新的 「AlertDataTable.php」 文件:

class AlertDataTable extends Table 
{ 

/** 
* Initialize method 
* 
* @param array $config The configuration for the Table. 
* @return void 
*/ 
public function initialize(array $config) 
{ 
    parent::initialize($config); 

    $this->setTable('alert_data'); 

    $this->setDisplayField('title'); 
    $this->setPrimaryKey('alert_id'); 
    $this->addBehavior('Timestamp'); 

    $this->hasMany('ProfileData', [ 
     'foreignKey' => 'alert_id' 
    ]); 
} 

} 

這裏的重要行是「belongsTo」和「hasMany」。

然後我能夠改變我的查詢,並使用「包含」可以輕鬆地在兩個表連接在一起,並得到JSON格式的正是我想要的東西:

$this->AlertData->find(
     'all', 
     ['conditions' => 
      ['AlertData.user_id =' => $uid], 
     'contain' => 
      ['ProfileData'] 
     ] 
    );