【问题标题】:Complicated JSON with Cakephp 3Cakephp 3 的复杂 JSON
【发布时间】:2017-03-31 15:33:23
【问题描述】:

我正在开展一个项目,该项目涉及通过 JSON 将数据“配置文件”传递到 Web 应用程序。我正在使用 Cakephp 3.0 并且对它很陌生。我将配置文件存储在 mysql 数据库中,并且可以轻松地查询数据并将其放入基本的 JSON 格式,每一行都是 JSON 中的单独值:

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
]
}

我希望 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 重构为这种结构似乎有意义吗?

提前致谢!

【问题讨论】:

  • 看起来您的数据库中有很多重复数据,即您的架构没有达到应有的规范化程度!?
  • 这是真的 - 我打算先让它只处理一个表(看起来会更容易),然后将数据拆分为两个表,分别是 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 放在一起会更容易吗?
  • 很可能,是的。您只需正确设置associations,并在您的查找中设置contain 关联表,如果关联的属性名称为profile_data,您甚至不必修改结果完全没有。
  • 感谢您指点我正确的方式!我让它工作了。对于我为将来可能遇到此问题的人所做的事情,我会写一篇详尽的回复。

标签: php mysql json cakephp cakephp-3.0


【解决方案1】:

感谢用户 ndm,我意识到我的方法存在一些问题。我认为将所有数据放在一个表中会简化事情,但实际上它会使事情变得更加复杂并需要冗余数据存储(例如,为每个配置文件条目存储纬度和经度值,而不是只在单独的表中存储一次)。

ndm 也提到了

您只需要正确设置 associationscontain 在您的查找中关联的 > 表,如果关联的属性名称是 >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']
        ]
    );     

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多