2017-03-31 136 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'] 
     ] 
    );