JSON数据在cocos中的解包和在php文件中的打包

本文介绍了如何在PHP文件中将数据库查询结果打包成JSON数据,以及在Cocos中如何解包这些数据。在PHP中,通过查询数据库并封装成JSON,然后返回给客户端。在Cocos端,解析JSON获取特定信息。注意在处理JSON时的数据类型匹配和字符串处理问题。

注:本文为作者原创,其中知识内容出自闪电终结者的视频课程

在php文件中我们可以通过

mysql_query() // 参数为SQL语句,得到一大个表
mysql_fetch_array() // 得到表中的第一行,在写一个则得到第二行,依次下去,每一行都是一个数组
mysql_num_fields() // 得到表的列数
mysql_num_rows() // 行数

但是无论如何,取到的最小单位都是一个数组,只能手动把需要的数直接echo给客户端。这个时候,就用到json数据。

具体的顺序是:

  1. 客户端连接服务器,并发送表单数据(也可以不发送)
  2. php文件连接数据库,并在数据库中读取相关数据,
  3. 把数据打包成JSON数据
  4. 服务器把php脚本解码,变成文本数据,返回给需要请求的客户端

在php文件中的打包

目标是:打包如下的JSON数据:

[{"id":"3", "name":"小刚", "sex":"male", "length":"1.75"}]

制作数据库test1里的表student:

 id | name   | sex    | length |
+----+--------+--------+--------+
|  1 | 小明   | male   |    1.8 |
|  2 | 小花   | female |    1.5 |
|  3 | 小敏   | female |   1.67 |
|  4 | 小刚   | male   |   1.75 

主要代码如下:

<?php
    // 获取表单信息
     $id = $_POST['id'];

    // 连接数据库
    $sql = mysql_connect("127.0.0.1", "root", "");

    // 获取到id = $id 条件下的一大个表
    $result = mysql_query("SELECT * FROM test1.student WHERE id = $id");

    // 获取到这个表的列数(字段数)
    $number = mysql_num_fields($result);

    $result_1 = mysql_query("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = \"test1\" AND TABLE_NAME = \"student\"");

    $js_for_return = "[{";

    $isFirst = true;
    $data_array = mysql_fetch_array($result);

    for ($index = 0; $index < $number; $index++) {
        // 如果不是第一个,则不需要加,
        if ($isFirst) {
            $isFirst = false;
        } else {
            $js_for_return = $js_for_return.",";
        }
        $js_for_return = $js_for_return."\"".mysql_fetch_array($result_1)[0]."\":\"";
        $js_for_return = $js_for_return.$data_array[$index];
        $js_for_return = $js_for_return.'"';
    }
    $js_for_return = $js_for_return."}]";

    echo $js_for_return;

重点在这句:

    $result_1 = mysql_query("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = \"test1\" AND TABLE_NAME = \"student\"");

做如下解释:

mysql> SHOW SCHEMAS;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| login_test         |
| mysql              |
| order_test         |
| performance_schema |
| sys                |
| test1              |

这是我们电脑中所有的数据库,其中除了login_test,order_test ,test1是自己创的以外,其余都是系统自带的

mysql> SHOW TABLES in information_schema;
+---------------------------------------+
| Tables_in_information_schema          |
+---------------------------------------+
| CHARACTER_SETS                        |
| COLLATIONS                            |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                               |
| COLUMN_PRIVILEGES                     |
| ENGINES                               |
| EVENTS                                |
| FILES                                 |
| GLOBAL_STATUS                         |
| GLOBAL_VARIABLES                      |
....

看到information_schema这个数据库中,有一个表叫COLUMNS(字段)

mysql> DESC  information_schema.COLUMNS;
+--------------------------+---------------------+------+-----+---------+-------+
| Field                    | Type                | Null | Key | Default | Extra |
+--------------------------+---------------------+------+-----+---------+-------+
| TABLE_CATALOG            | varchar(512)        | NO   |     |         |       |
| TABLE_SCHEMA             | varchar(64)         | NO   |     |         |       |
| TABLE_NAME               | varchar(64)         | NO   |     |         |       |
| COLUMN_NAME              | varchar(64)         | NO   |     |         |       |
| ORDINAL_POSITION         | bigint(21) unsigned | NO   |     | 0       |       |
| COLUMN_DEFAULT           | longtext            | YES  |     | NULL    |       |
| IS_NULLABLE              | varchar(3)          | NO   |     |         |       |

看向这个表里,其他有TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME这三个字段

COLUMN_NAME:存储了其他表(比如表student中的id, name,…)的字段值,
TABLE_SCHEMA:表示其他表所处的数据库名称,(比如student表处于test1数据库中,此时TABLE_SCHEMA=”test1”)
TABLE_NAME :表示表的名称(比如此时TABLE_NAME = “student”)

因此我们就可以使用TABLE_SCHEMA和TABLE_NAME这2个关键字来找到student中所有的字段

mysql> SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = "test1" AND TABLE_NAME = "student";
+-------------+
| COLUMN_NAME |
+-------------+
| id          |
| name        |
| sex         |
| length      |
+-------------+

调试过程中遇到的bug:

    $result = mysql_query("SELECT * FROM test1.student WHERE id = $id");

这里一开始写的是id = \”$id\”
在创建表的时候id是int类型所有不需要加双引号

在cocos中的解包

把这个解包写在一个类中,对不同项目需要进行不同的封装,还是以上的实例,实现输入一个id可以获取学生的其他信息

// DecodeByJson.hpp
#ifndef DecodeByJson_hpp
#define DecodeByJson_hpp

#include <cocos2d.h>
#include <iostream>
#include <network/httpClient.h>
#include <spine/Json.h>
#include <vector>

struct Student {
    int id;
    std::string name;
    std::string sex;
    std::string length;
};

// 只能针对该项目的封装
class DecodeByJson {
private:
    std::string jsonData;

    std::vector<Student> stuVector;

public:
    DecodeByJson(const std::string &jsonData);

    // 能通过id得到student
    Student getStuById(const int id);
};

#endif /* DecodeByJson_hpp */
// cpp
#include "DecodeByJson.hpp"

DecodeByJson::DecodeByJson(const std::string &jsonData): jsonData(jsonData) {
    auto js = Json_create(jsonData.c_str());
    // 得到第一行json数据
    auto node = js -> child;
    while (node) {
        Student stuTemp;
        stuTemp.id = Json_getItem(node, "id") -> valueInt;
        stuTemp.name = Json_getItem(node, "name") -> valueString;
        stuTemp.sex = Json_getItem(node, "sex") -> valueString;
        stuTemp.length = Json_getItem(node, "length") -> valueString;
        stuVector.push_back(stuTemp);
        node = node -> next;
    }
    // 通过id寻找:1遍历整个数组
    // 2在创建好数组时,对数组进行从小到大的排序,那么id以后就是Index
    std::sort(stuVector.begin(), stuVector.end(), [](const Student &left, const Student &right) {
        return left.id > right.id; // 大于则返回一,那么久是一个升序排列
    });
}

// 能通过id得到student
Student DecodeByJson::getStuById(const int id) {
    return stuVector.at(id - 1);
}

PS:

        stuTemp.id = Json_getItem(node, "id") -> valueInt;
        stuTemp.name = Json_getItem(node, "name") -> valueString;
        stuTemp.sex = Json_getItem(node, "sex") -> valueString;
        stuTemp.length = Json_getItem(node, "length") -> valueString;
        stuVector.push_back(st

在处理返回的json数据时候,我吧length也设置成了string类型其实是不合适的,他应该是float。
而在php文件中,因为是用循环语句来打包Json数据导致给每个数据项都加了双引号,因此我们可以用2个函数来解决此问题

#include <cstdlib> // 包含头文件

std::atoi(const char * ); // 字符串到Int
std::atof(const chat * ); // 字符串到float
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值