Error[8]: Undefined offset: 322, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 114
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

案例总结

1 前言

这个案例是一个简单的后端接口实现,含有用户注册、用户登录、发布笔记、删除笔记、修改笔记、查询笔记的功能。


主要使用c++语言编写,应用于linux的CGI环境。


2 环境配置 2.1 开发环境

笔者使用的环境如下:

[+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++]
2.2 配置环境参考博客
  1. mysql
    参考作者:“風の住む街~” 的博客
    Ubuntu20.04安装Mysql
  2. apache
    参考作者:“JstuCheng” 的博客
    Ubuntu安装使用apache2
  3. jsoncpp
    参考作者:“Acuity.” 的博客
    jsoncpp应用(Linux环境)
    参考作者:“肥叔菌” 的博客
    JsonCpp入门一:在linux下编译使用JsonCpp
  4. libmysqlclient-dev
    参考作者:“Devin_white” 的博客
    LINUX下C/C++ *** 作MySql
3 案例介绍 3.1 案例需求
  1. 需要建立两张表,用于存储用户信息和笔记信息,分别是users和notes表

  2. 接口需求
    1. user

        [+++]
      [+++][+++]{yours ip[+++][+++]cgi[+++]bin[+++]notes[+++]bin[+++]main[+++]user[+++]register
      request method:[+++]
      request body[+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      [+++][+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      
        [+++]
      [+++][+++]{yours ip[+++][+++]cgi[+++]bin[+++]notes[+++]bin[+++]main[+++]user[+++]login
      request method:[+++]
      request body[+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      [+++][+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      
    2. note

        [+++]
      [+++][+++]{yours ip[+++][+++]cgi[+++]bin[+++]notes[+++]bin[+++]main[+++]note[+++]add_note
      request method:[+++]
      request body[+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      [+++][+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      
        [+++]
      [+++][+++]{yours ip[+++][+++]cgi[+++]bin[+++]notes[+++]bin[+++]main[+++]note[+++]delete_note
      request method:[+++]
      request body[+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++][+++][+++] [+++][+++] [+++][+++]
      [+++]
      [+++][+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      
        [+++]
      [+++][+++]{yours ip[+++][+++]cgi[+++]bin[+++]notes[+++]bin[+++]main[+++]note[+++]update_note
      request method:[+++]
      request body[+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++][+++]
      	[+++][+++][+++][+++]
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      [+++][+++]
      type [+++] [+++][+++] update content[+++] 
      type [+++] [+++][+++] update tag[+++] 
      type [+++] [+++][+++] update content and tag
      [+++][+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      
        [+++]
      [+++][+++]{yours ip[+++][+++]cgi[+++]bin[+++]notes[+++]bin[+++]main[+++]note[+++]select_note
      request method:[+++]
      request body[+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++][+++]
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      [+++]
      [+++][+++]
      order [+++] [+++][+++] preorder
      order [+++] [+++][+++] postorder
      [+++][+++]
      {
      	[+++][+++][+++][+++]
      	[+++][+++][+++][+++]
      	[+++][+++][+++]
      		{
      			[+++][+++][+++][+++]
      			[+++][+++][+++][+++]
      			[+++][+++][+++][+++]
      			[+++][+++][+++][+++]
      			[+++][+++][+++]
      		[+++]
      	[+++]
      [+++]
      
3.2 案例实现 3.2.1 文件结构


3.2.2 代码实现 3.2.2.1 Main类
// Main.h
#include 
#include "Start.h"

int main(int argc, char **argv);
[+++]
3.2.2.2 Start类
// Start.h
#include 
#include 
#include 
#include 
#include 
#include 
#include "MyDB.h"
#include "json/json.h"
#include "Tools.h"
#include "Note.h"
#include "User.h"
using namespace std;

class Start
{
        private:
                MyDB* db;
                Tools* tools;
                Note* note;
                User* user;

        public:
                Start();
                ~Start();
                void run();
};
// Start.cpp
#include "../include/Start.h"

Start::Start()
{
        this->db = new MyDB();
        this->db->initDB((char *)"localhost", (char *)"root", (char *)"fast1111", (char *)"test");
        this->tools = new Tools();
        this->note = new Note(db, tools);
        this->user = new User(db, tools);
}

Start::~Start()
{

}

void Start::run()
{
        Json::Value root;
        Json::Value postData;
        Json::Value getData;
        map allowMethod;
        allowMethod["GET"] = 1;
        allowMethod["POST"] = 2;
        allowMethod["PUT"] = 3;
        allowMethod["DELETE"] = 4;
        map allowResource;
        allowResource["user"] = 1;
        allowResource["note"] = 2;

        // judeg method
        char *requestMethod = getenv("REQUEST_METHOD");
        if (!requestMethod || !allowMethod[requestMethod])
        {
                root["errCode"] = Json::Value(40100);
                root["errInfo"] = Json::Value("The request method is not allowed");
                this->tools->printHeader(2);
                this->tools->printJson(root, 2);
                exit(0);
        }

        switch (allowMethod[requestMethod])
        {
                case 1:
                        {
                                getData = this->tools->getGetData();                                break;
                        }
                case 2:
                        {
                                postData = this->tools->getPostData();
                                break;
                        }
                default:
                        {
                                break;
                        }
        }

        // judge resource
        char *requestResource = getenv("PATH_INFO");
        if (!requestResource)
        {
                root["errCode"] = Json::Value(40101);
                root["errInfo"] = Json::Value("The request resource is missing");
                this->tools->printHeaderAndJson(root, 2, 2);
                exit(0);
        }
        else if (requestResource)
        {
                vector resource;
                char *res = strtok(requestResource, "/");
                while (res)
                {
                        resource.push_back(res);
                        res = strtok(NULL, "/");
                }
                // match resource and choose execute path
                if (resource.size() < 2)
                {
                        root = this->tools->jsonEncode(40102, (char *)"The request resource is missing");
                        this->tools->printHeaderAndJson(root, 2, 2);                        exit(0);
                }
                else 
                {
                        // request user
                        if (!strcmp("user", resource[0].c_str()))
                        {
                                if (!strcmp("register", resource[1].c_str()))
                                {
                                        root = this->user->_register(postData);
                                }
                                else if (!strcmp("login", resource[1].c_str()))
                                {
                                        root = this->user->login(postData);
                                }
                                else
                                {
                                        root = this->tools->jsonEncode(40103, (char*)"Request resource is not allowed");
                                }
                        }
                        // request note
                        else if (!strcmp("note", resource[0].c_str()))
                        {
                                // add note
                                if (!strcmp("add_note", resource[1].c_str()))
                                {
                                        root = this->note->addNote(postData);
                                }
                                // delete note
                                else if (!strcmp("delete_note", resource[1].c_str()))
                                {
                                        root = this->note->deleteNote(postData);
                                }
                                // update note
                                else if (!strcmp("update_note", resource[1].c_str()))
                                {
                                        root = this->note->updateNote(postData);
                                }
                                // select note
                                else if (!strcmp("select_note", resource[1].c_str()))
                                {
                                        root = this->note->selectNote(postData);
                                }
                                // other
                                else
                                {
                                        root = this->tools->jsonEncode(40104, (char *)"Request resource is not allowed");
                                }
                        }
                }
        }

        this->tools->printHeaderAndJson(root, 2, 2);
}
3.2.2.3 MyDB类
// MyDB.h
#ifndef _MYDB_H
#define _MYDB_H

#include 
#include 
#include 
#include "json/json.h"
using namespace std;

class MyDB
{
        private:
                MYSQL* mysql;           // connect mysql pointer
                MYSQL_RES* result;      // query result pointer
                MYSQL_ROW row;          // result row

        public:
                MyDB();
                ~MyDB();
                bool initDB(char* host, char* user, char* pwd, char* db_name);
                Json::Value execSQL(char* sql);
};

#endif
[+++]
3.2.2.4 Tools类
// Tools.h
#ifndef _TOOLS_H
#define _TOOLS_H

#include 
#include 
#include 
#include 
#include "json/json.h"
using namespace std;

class Tools
{
        public:
                Tools();
                ~Tools();
                int getDatetime(char *timeStr);
                void printHeader(int type);
                void printJson(Json::Value root, int type);
                Json::Value jsonEncode(int errCode, char* errInfo);                void printHeaderAndJson(Json::Value root, int headerType, int jsonType);
                Json::Value getPostData();
                Json::Value getGetData();
};

#endif
// Tools.cpp
#include "../include/Tools.h"

Tools::Tools()
{

}

Tools::~Tools()
{

}

int Tools::getDatetime(char *timeStr)
{
        time_t seconds = time(NULL);
        struct tm *curTime = localtime(&seconds);
        int timeStrLen = sprintf(timeStr, "%04d-%02d-%02d %02d:%02d:%02d", curTime->tm_year + 1900, curTime->tm_mon + 1, curTime->tm_mday, curTime->tm_hour, curTime->tm_min, curTime->tm_sec);
        return timeStrLen;
}

void Tools::printHeader(int type = 1)
{
        if (type == 1)
        {
                cout << "Content-type: text/html\r\n\r\n";
        }
        else if (type == 2)
        {
                cout << "Content-type: application/json\r\n\r\n";
        }
}

void Tools::printJson(Json::Value root, int type = 1)
{
        if (type == 1)  // FastWriter
        {
                Json::FastWriter fastWriter;
                cout << fastWriter.write(root);
        }
        else if (type == 2)     // StyledWriter
        {
                Json::StyledWriter styledWriter;
                cout << styledWriter.write(root);
        }
}

// make errCode and errInfo
Json::Value Tools::jsonEncode(int errCode, char* errInfo)
{
        Json::Value root;
        root["errCode"] = Json::Value(errCode);
        root["errInfo"] = Json::Value(errInfo);
        return root;
}

void Tools::printHeaderAndJson(Json::Value root, int headerType = 1, int jsonType = 1)
{
        this->printHeader(headerType);
        this->printJson(root, jsonType);
}

Json::Value Tools::getPostData()
{
        char *postStr;
        // check data size
        if (getenv("CONTENT_LENGTH"))
        {
                int len;
                sscanf(getenv("CONTENT_LENGTH"), "%d", &len);
                postStr = new char[len * 2];
                int tot = 0;
                char c;
                // format post data
                for (int i = 0; i < len; i++)
                {
                        c = getchar();
                        if (c == '\n' || c == '\r' || c == '\t')
                        {
                                continue;
                        }
                        postStr[tot++] = c;
                }
                postStr[tot] = '';
        }
        Json::Value root;
        Json::Reader reader;
        if (!reader.parse(postStr, root))
        {
                this->printHeaderAndJson(this->jsonEncode(40200, (char*)"Json format error"), 2, 2);
                exit(1);
        }

        return root;
}

Json::Value Tools::getGetData()
{
        Json::Value root;
        return root;
}
 
3.2.2.5 User类 
// User.h
#include 
#include 
#include 
#include "MyDB.h"
#include "Tools.h"
#include "json/json.h"
using namespace std;

class User
{
        private:
                MyDB *db;
                Tools *tools;
                char* sql;
                Json::Value root;

        public:
                User();
                User(MyDB* db, Tools* tools);
                ~User();
                Json::Value insert(const char* username, const char* pwd);
                Json::Value _delete(int id);
                Json::Value update(int id, const char* username,const char* pwd, int type);
                Json::Value select(int id);
                Json::Value _register(Json::Value postData);
                Json::Value login(Json::Value postData);
};
 
// User.cpp
#include "../include/User.h"

User::User()
{

}

User::User(MyDB* db, Tools* tools)
{
        this->db = db;
        this->tools = tools;
        this->sql = new char[300];
}

User::~User()
{

}

Json::Value User::insert(const char* username, const char* pwd)
{
        char curTime[30];
        this->tools->getDatetime(curTime);

        sprintf(sql, "insert into users(username, password, createTime) values(\"%s\", \"%s\", \"%s\");", username, pwd, curTime);
        root = this->db->execSQL(sql);

        return root;
}

Json::Value User::_delete(int id)
{
        sprintf(sql, "delete from users where id = %d;", id);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value User::update(int id, const char* username, const char* pwd, int type)
{
        if (type == 1)  // update username
        {
                sprintf(sql, "update users set username = \"%s\" where id = %d;", username, id);
        }
        else if (type == 2)     // update password
        {
                sprintf(sql, "update users set password = \"%s\" where id = %d;", pwd, id);
        }
        root = this->db->execSQL(sql);
        return root;
}

Json::Value User::select(int id)
{
        sprintf(sql, "select * from users where id = %d;", id);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value User::_register(Json::Value postData)
{
        Json::Value root;
        if (postData.isMember("username") && postData.isMember("password"))
        {
                sprintf(sql, "select count(1) from users where username = \"%s\";", postData["username"].asString().c_str());
                Json::Value result = this->db->execSQL(sql);
                int flag;
                sscanf(result["data"][0u]["0"].asString().c_str(), "%d", &flag);
                if (flag >= 1)
                {
                        root = this->tools->jsonEncode(40303, (char*)"Username is exists");
                }
                else
                {
                        result = this->insert(postData["username"].asString().c_str(), postData["password"].asString().c_str());
                        root["errCode"] = result["errCode"];
                        root["errInfo"] = result["errInfo"];
                }
        }
        else
        {
                root = this->tools->jsonEncode(40300, (char*)"Params is missing");
        }
        return root;
}

Json::Value User::login(Json::Value postData)
{
        Json::Value root;
        if (postData.isMember("username") && postData.isMember("password"))
        {
                sprintf(sql, "select count(1) from users where username = \"%s\" and password = \"%s\";", postData["username"].asString().c_str(), postData["password"].asString().c_str());
                Json::Value result = this->db->execSQL(sql);
                int flag;
                sscanf(result["data"][0u]["0"].asString().c_str(), "%d", &flag);
                if (!flag)
                {
                        root = this->tools->jsonEncode(40301, (char*)"Username or password is wrong");
                }
                else
                {
                        root = this->tools->jsonEncode(0, (char *)"Ok");
                }

                // root["0"] = Json::Value(result["data"][0u]["0"].asInt());
        }
        else
        {
                root = this->tools->jsonEncode(40302, (char*)"Params is missing");
        }
        return root;
}
 
3.2.2.6 Note类 
// Note.h
#ifndef _NOTE_H
#define _NOTE_H

#include 
#include 
#include 
#include "MyDB.h"
#include "Tools.h"
#include "json/json.h"
using namespace std;

class Note
{
        private:
                MyDB *db;
                Tools *tools;
                char *sql;
                Json::Value root;

        public:
                Note();
                Note(MyDB *db, Tools *tools);
                ~Note();
                Json::Value insert(int userId, const char* content, int tag);
                Json::Value _delete(int id);
                Json::Value update(int id, const char* content);
                Json::Value select(int id, int type);
                Json::Value addNote(Json::Value postData);
                Json::Value deleteNote(Json::Value postData);
                Json::Value updateNote(Json::Value postData);
                Json::Value selectNote(Json::Value postDate);
};

#endif
 
< postData["noteIds"].size(); i++)
        {
                sprintf(sql, "delete from notes where id = %d and userId = %d;", postData["noteIds"][i].asInt(), postData["userId"].asInt());
                result = this->// Note.cpp
#include "../include/Note.h"

Note::Note()
{
        this->db = new MyDB();
        this->db->initDB((char *)"localhost", (char *)"root", (char *)"fast1111", (char *)"test");
        this->sql = new char[300];
}

Note::Note(MyDB *db, Tools *tools)
{
        this->db = db;
        this->tools = tools;
        this->sql = new char[300];
}

Note::~Note()
{

}

Json::Value Note::insert(int userId, const char* content, int tag = 1)
{
        char curTime[40];

        // format values
        tools->getDatetime(curTime);

        sprintf(sql, "insert into notes(userId, content, tag, createTime) values(%d, \"%s\", %d, \"%s\");",userId, content, tag, curTime);

        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::_delete(int id)
{
        sprintf(sql, "delete from notes where id = %d;", id);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::update(int id, const char* content)
{
        sprintf(sql, "update notes set content = \"%s\" where id = %d;", content, id);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::select(int id, int type = 0)
{
        if (type == 1)  // use note id to select
        {
                sprintf(sql, "select * from notes where id = %d;", id);
        }
        else if (type == 2)     // use user id to select
        {
                sprintf(sql, "select * from notes where userId = %d;", id);
        }
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::addNote(Json::Value postData)
{
        Json::Value root;
        char curTime[40];
        this->tools->getDatetime(curTime);
        sprintf(sql, "insert into notes(userId, content, createTime) values(%d, \"%s\", \"%s\");", postData["userId"].asInt(), postData["content"].asString().c_str(), curTime);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::deleteNote(Json::Value postData)
{
        Json::Value root;
        Json::Value result;

        // use transaction to aviod some error
        memset(sql, 0x00, sizeof(sql));
        memcpy(sql, "set autocommit = 0;", 20);
        root = this->db->execSQL(sql);
        if (root["errCode"].asInt())
        {
                return root;
        }
        memcpy(sql, "start transaction;", 20);
        root = this->db->execSQL(sql);
        if (root["errCode"].asInt())
        {
                return root;
        }
        // delete note in the order it was received
        for (int i = 0; i db->execSQL(sql);
                if (result["errCode"].asInt())
                {
                        break;
                }
        }
        // hava error, need to rollback
        if (result["errCode"].asInt())
        {
                memcpy(sql, "rollback;", 10);
                result = this->db->execSQL(sql);
                root = this->tools->jsonEncode(40401, (char *)"Delete notes wrong");
        }
        // no error, delete all, return Ok
        else
        {
                memcpy(sql, "commit;", 10);
                result = this->db->execSQL(sql);
                root = this->tools->jsonEncode(0, (char*)"Ok");
        }

        return root;
}

Json::Value Note::updateNote(Json::Value postData)
{
        Json::Value root;
        // check necessary params, type and noteId
        if (!postData.isMember("type") || !postData.isMember("noteId") || !postData.isMember("userId"))
        {
                return this->tools->jsonEncode(40402, (char *)"Params is missing");
        }
        switch (postData["type"].asInt())
        {
                case 1:         // update content
                {
                        if (!postData.isMember("content"))
                        {
                                return this->tools->jsonEncode(40402, (char *)"Params is missing");
                        }
                        sprintf(sql, "update notes set content = \"%s\" where id = %d and userId = %d;", postData["content"].asString().c_str(), postData["noteId"].asInt(), postData["userId"].asInt());                        break;
                }
                case 2:         // update tag
                {
                        if (!postData.isMember("tag"))
                        {
                                return this->tools->jsonEncode(40402, (char*)"Params is missing");
                        }
                        sprintf(sql, "update notes set tag = %d where id = %d and userId = %d;", postData["tag"].asInt(), postData["noteId"].asInt(), postData["userId"].asInt());
                        break;
                }
                case 3:         // update content and tag
                {
                        if (!postData.isMember("content") || !postData.isMember("tag"))
                        {
                                return this->tools->jsonEncode(40402, (char*)"Params is missing");
                        }
                        sprintf(sql, "update notes set content = \"%s\", tag = %d where id = %d and userId = %d;", postData["content"].asString().c_str(), postData["tag"].asInt(), postData["noteId"].asInt(), postData["userId"].asInt());
                        break;
                }
                default:
                {
                        return this->tools->jsonEncode(40403, (char*)"Type error");
                        break;
                }
        }
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::selectNote(Json::Value postData)
{
        Json::Value root;
        if (!postData.isMember("userId"))
        {
                return this->tools->jsonEncode(40404, (char*)"Params is missing");
        }
        int offset = 0, limit = 10, type = 1;
        char* orderStr = (char*)"asc";
        if (postData.isMember("offset"))
        {
                offset = postData["offset"].asInt();
        }
        if (postData.isMember("limit"))
        {
                limit = postData["limit"].asInt();
        }
        if (postData.isMember("type"))
        {
                type = postData["type"].asInt();
        }
        if (postData.isMember("order") && postData["order"].asInt() == 2)
        {
                orderStr = (char*)"desc";
        }

        switch (type)
        {
                case 1:         // select all fields
                {
                        sprintf(sql, "select * from notes where userId = %d order by createTime %s limit %d, %d;", postData["userId"].asInt(), orderStr, offset, limit);
                        break;
                }
                default:
                {
                        return this->tools->jsonEncode(40404, (char*)"Type error");
                }
        }
        root = this->db->execSQL(sql);
        return root;
}
 
3.2.2.7 Makefile 
objects [+++] temp/Main.o [+++]
          temp/Start.o [+++]
          temp/MyDB.o [+++]
          temp/Tools.o [+++]
          temp/Note.o [+++]
          temp/User.o

bin/main: [+++]objects[+++]
        g++ -g -o [+++] $^ -Llibs -ljson_linux-gcc-9_libmt -lmysqlclient
temp/%.o: source/%.cpp include/%.h
        g++ -o [+++] -c $[+++] -g

clean:
        [+++] -rf [+++]objects[+++]

3.3 案例结果 3.3.1 用户注册

3.3.2 用户登录

3.3.3 发布笔记

ps: 此时还未加入“userId”检查功能

3.3.4 删除笔记

3.3.5 修改笔记

3.3.6 查询笔记

ps: 返回集中没有记录的字段名,暂时没找到mysql的哪个函数会提供字段名,就先用列号代替了
    4 问题总结
[+++][+++][+++][+++]
    5 参考博客
[+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++]

6 其他
这篇博客作为学习过程的一个记录,方便以后查看。



目前还有很多内容没有完善,实现的比较粗糙,只是按着自己的想法做的,后面有机会也会再完善完善。



期间遇到了很多问题,参考了很多前辈的博客,远不止上面所列举的博客,学习了不少新知识。



我这边测试的基本功能都可以实现,如发现错误,请不吝赐教。


<===>)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
使用c++开发linux CGI环境下后端接口案例总结_C_内存溢出

使用c++开发linux CGI环境下后端接口案例总结

使用c++开发linux CGI环境下后端接口案例总结,第1张

案例总结
    • 1 前言
    • 2 环境配置
      • 2.1 开发环境
      • 2.2 配置环境参考博客
    • 3 案例介绍
      • 3.1 案例需求
      • 3.2 案例实现
        • 3.2.1 文件结构
        • 3.2.2 代码实现
          • 3.2.2.1 Main类
          • 3.2.2.2 Start类
          • 3.2.2.3 MyDB类
          • 3.2.2.4 Tools类
          • 3.2.2.5 User类
          • 3.2.2.6 Note类
          • 3.2.2.7 Makefile
      • 3.3 案例结果
        • 3.3.1 用户注册
        • 3.3.2 用户登录
        • 3.3.3 发布笔记
        • 3.3.4 删除笔记
        • 3.3.5 修改笔记
        • 3.3.6 查询笔记
    • 4 问题总结
    • 5 参考博客
    • 6 其他

1 前言

这个案例是一个简单的后端接口实现,含有用户注册、用户登录、发布笔记、删除笔记、修改笔记、查询笔记的功能。


主要使用c++语言编写,应用于linux的CGI环境。


2 环境配置 2.1 开发环境

笔者使用的环境如下:

工具版本备注
Ubantu20.04
mysql5.7.37
apache2.4.41
vim8.1.3741编辑源文件
jsoncpp0.5.0解析json数据
libmysqlclient-devlibmysqlclient.so.21.2.28 *** 作mysql数据库
postman9.15.10测试接口
2.2 配置环境参考博客
  1. mysql
    参考作者:“風の住む街~” 的博客
    Ubuntu20.04安装Mysql
  2. apache
    参考作者:“JstuCheng” 的博客
    Ubuntu安装使用apache2
  3. jsoncpp
    参考作者:“Acuity.” 的博客
    jsoncpp应用(Linux环境)
    参考作者:“肥叔菌” 的博客
    JsonCpp入门一:在linux下编译使用JsonCpp
  4. libmysqlclient-dev
    参考作者:“Devin_white” 的博客
    LINUX下C/C++ *** 作MySql
3 案例介绍 3.1 案例需求
  1. 需要建立两张表,用于存储用户信息和笔记信息,分别是users和notes表

  2. 接口需求
    1. user

      1. 用户注册(register)
      url:{yours ip}/cgi-bin/notes/bin/main/user/register
      request method:POST
      request body:
      {
      	"username":"zhangsan",
      	"password":"123456"
      }
      response:
      {
      	"errCode":0,
      	"errInfo":"ok"
      }
      
      1. 用户登录(login)
      url:{yours ip}/cgi-bin/notes/bin/main/user/login
      request method:POST
      request body:
      {
      	"username":"zhangsan",
      	"password":"123456"
      }
      response:
      {
      	"errCode":0,
      	"errInfo":"ok"
      }
      
    2. note

      1. 发布笔记(add_note)
      url:{yours ip}/cgi-bin/notes/bin/main/note/add_note
      request method:POST
      request body:
      {
      	"userId":1,
      	"content":"this is a test",
      	"tag":1
      }
      response:
      {
      	"errCode":0,
      	"errInfo":"ok"
      }
      
      1. 删除笔记(delete_note)
      url:{yours ip}/cgi-bin/notes/bin/main/note/delete_note
      request method:POST
      request body:
      {
      	"userId":1,
      	"noteIds":[1, 2, 3]
      }
      response:
      {
      	"errCode":0,
      	"errInfo":"ok"
      }
      
      1. 修改笔记(update_note)
      url:{yours ip}/cgi-bin/notes/bin/main/note/update_note
      request method:POST
      request body:
      {
      	"userId":1,
      	"noteId":1,
      	"content":"this is a text",
      	"tag":2,
      	"type":1
      }
      ps:
      type = 1, update content; 
      type = 2, update tag; 
      type = 3, update content and tag
      response:
      {
      	"errCode":0,
      	"errInfo":"ok"
      }
      
      1. 查询笔记(select_note)
      url:{yours ip}/cgi-bin/notes/bin/main/note/select_note
      request method:POST
      request body:
      {
      	"userId":1,
      	"offset":0,
      	"limit":10,
      	"order":1
      }
      ps:
      order = 1, preorder
      order = 2, postorder
      response:
      {
      	"errCode":0,
      	"errInfo":"ok",
      	"data":[
      		{
      			"noteId":1,
      			"userId":1,
      			"content":"this is a test",
      			"tag":1,
      			"createTime":"2022-03-27 12:00:00"
      		}
      	]
      }
      
3.2 案例实现 3.2.1 文件结构


3.2.2 代码实现 3.2.2.1 Main类
// Main.h
#include 
#include "Start.h"

int main(int argc, char **argv);
// Main.cpp
#include "../include/Main.h"
  
int main(int argc, char **argv)
{
        Start start;
        start.run();
        return 0;
}
3.2.2.2 Start类
// Start.h
#include 
#include 
#include 
#include 
#include 
#include 
#include "MyDB.h"
#include "json/json.h"
#include "Tools.h"
#include "Note.h"
#include "User.h"
using namespace std;

class Start
{
        private:
                MyDB* db;
                Tools* tools;
                Note* note;
                User* user;

        public:
                Start();
                ~Start();
                void run();
};
// Start.cpp
#include "../include/Start.h"

Start::Start()
{
        this->db = new MyDB();
        this->db->initDB((char *)"localhost", (char *)"root", (char *)"fast1111", (char *)"test");
        this->tools = new Tools();
        this->note = new Note(db, tools);
        this->user = new User(db, tools);
}

Start::~Start()
{

}

void Start::run()
{
        Json::Value root;
        Json::Value postData;
        Json::Value getData;
        map allowMethod;
        allowMethod["GET"] = 1;
        allowMethod["POST"] = 2;
        allowMethod["PUT"] = 3;
        allowMethod["DELETE"] = 4;
        map allowResource;
        allowResource["user"] = 1;
        allowResource["note"] = 2;

        // judeg method
        char *requestMethod = getenv("REQUEST_METHOD");
        if (!requestMethod || !allowMethod[requestMethod])
        {
                root["errCode"] = Json::Value(40100);
                root["errInfo"] = Json::Value("The request method is not allowed");
                this->tools->printHeader(2);
                this->tools->printJson(root, 2);
                exit(0);
        }

        switch (allowMethod[requestMethod])
        {
                case 1:
                        {
                                getData = this->tools->getGetData();                                break;
                        }
                case 2:
                        {
                                postData = this->tools->getPostData();
                                break;
                        }
                default:
                        {
                                break;
                        }
        }

        // judge resource
        char *requestResource = getenv("PATH_INFO");
        if (!requestResource)
        {
                root["errCode"] = Json::Value(40101);
                root["errInfo"] = Json::Value("The request resource is missing");
                this->tools->printHeaderAndJson(root, 2, 2);
                exit(0);
        }
        else if (requestResource)
        {
                vector resource;
                char *res = strtok(requestResource, "/");
                while (res)
                {
                        resource.push_back(res);
                        res = strtok(NULL, "/");
                }
                // match resource and choose execute path
                if (resource.size() < 2)
                {
                        root = this->tools->jsonEncode(40102, (char *)"The request resource is missing");
                        this->tools->printHeaderAndJson(root, 2, 2);                        exit(0);
                }
                else 
                {
                        // request user
                        if (!strcmp("user", resource[0].c_str()))
                        {
                                if (!strcmp("register", resource[1].c_str()))
                                {
                                        root = this->user->_register(postData);
                                }
                                else if (!strcmp("login", resource[1].c_str()))
                                {
                                        root = this->user->login(postData);
                                }
                                else
                                {
                                        root = this->tools->jsonEncode(40103, (char*)"Request resource is not allowed");
                                }
                        }
                        // request note
                        else if (!strcmp("note", resource[0].c_str()))
                        {
                                // add note
                                if (!strcmp("add_note", resource[1].c_str()))
                                {
                                        root = this->note->addNote(postData);
                                }
                                // delete note
                                else if (!strcmp("delete_note", resource[1].c_str()))
                                {
                                        root = this->note->deleteNote(postData);
                                }
                                // update note
                                else if (!strcmp("update_note", resource[1].c_str()))
                                {
                                        root = this->note->updateNote(postData);
                                }
                                // select note
                                else if (!strcmp("select_note", resource[1].c_str()))
                                {
                                        root = this->note->selectNote(postData);
                                }
                                // other
                                else
                                {
                                        root = this->tools->jsonEncode(40104, (char *)"Request resource is not allowed");
                                }
                        }
                }
        }

        this->tools->printHeaderAndJson(root, 2, 2);
}
3.2.2.3 MyDB类
// MyDB.h
#ifndef _MYDB_H
#define _MYDB_H

#include 
#include 
#include 
#include "json/json.h"
using namespace std;

class MyDB
{
        private:
                MYSQL* mysql;           // connect mysql pointer
                MYSQL_RES* result;      // query result pointer
                MYSQL_ROW row;          // result row

        public:
                MyDB();
                ~MyDB();
                bool initDB(char* host, char* user, char* pwd, char* db_name);
                Json::Value execSQL(char* sql);
};

#endif
// MyDB.cpp
#include "../include/MyDB.h"

MyDB::MyDB()
{
        mysql = mysql_init(NULL);               // initial connect param
        if (mysql == NULL)
        {
                cout << "Error:" << mysql_error(mysql);
                exit(1);
        }
}

MyDB::~MyDB()
{
        if (mysql != NULL)
        {
                mysql_close(mysql);
        }
}

bool MyDB::initDB(char* host, char* user, char* pwd, char* db_name){
        mysql = mysql_real_connect(mysql, (const char*)host, (const char*)user, (const char*)pwd, (const char*)db_name, 0, NULL, 0);
        if (mysql == NULL)
        {
                cout << "Error:" << mysql_error(mysql);
                exit(1);
        }
        return true;
}

Json::Value MyDB::execSQL(char* sql)
{
        Json::Value root;
        // mysql_query() success will return 0
        if (mysql_query(mysql, (const char*)sql))
        {
                root["errCode"] = Json::Value(40000);
                root["errInfo"] = Json::Value(mysql_error(mysql));
                return root;
        }
        else    // success
        {
                result = mysql_store_result(mysql);
                if (result)     // return result set
                {
                        root["errCode"] = Json::Value(0);
                        root["errInfo"] = Json::Value("ok");
                        int num_fields = mysql_num_fields(result);
                        int num_rows = mysql_num_rows(result);
                        for (int i = 0; i < num_rows; i++)
                        {
                                // get next line data
                                row = mysql_fetch_row(result);
                                if (row < 0) break;

                                Json::Value rowData;
                                char key[10];
                                for (int j = 0; j < num_fields; j++)
                                {
                                        sprintf(key, "%d", j);
                                        rowData[key] = Json::Value(row[j]);
                                }
                                root["data"].append(rowData);
                        }
                }
                else    // result == NULL
                {
                        // execute update, insert, delete
                        if (mysql_field_count(mysql) == 0)
                        {
                                root["errCode"] = Json::Value(0);
                                root["errInfo"] = Json::Value("ok");
                                int numRows = mysql_affected_rows(mysql);
                             // root["numRows"] = Json::Value(numRows);
                        }
                        else    // error
                        {
                                root["errCode"] = Json::Value(40001);
                                root["errInfo"] = Json::Value(mysql_error(mysql));
                        }
                }
        }
        return root;
}
3.2.2.4 Tools类
// Tools.h
#ifndef _TOOLS_H
#define _TOOLS_H

#include 
#include 
#include 
#include 
#include "json/json.h"
using namespace std;

class Tools
{
        public:
                Tools();
                ~Tools();
                int getDatetime(char *timeStr);
                void printHeader(int type);
                void printJson(Json::Value root, int type);
                Json::Value jsonEncode(int errCode, char* errInfo);                void printHeaderAndJson(Json::Value root, int headerType, int jsonType);
                Json::Value getPostData();
                Json::Value getGetData();
};

#endif
// Tools.cpp
#include "../include/Tools.h"

Tools::Tools()
{

}

Tools::~Tools()
{

}

int Tools::getDatetime(char *timeStr)
{
        time_t seconds = time(NULL);
        struct tm *curTime = localtime(&seconds);
        int timeStrLen = sprintf(timeStr, "%04d-%02d-%02d %02d:%02d:%02d", curTime->tm_year + 1900, curTime->tm_mon + 1, curTime->tm_mday, curTime->tm_hour, curTime->tm_min, curTime->tm_sec);
        return timeStrLen;
}

void Tools::printHeader(int type = 1)
{
        if (type == 1)
        {
                cout << "Content-type: text/html\r\n\r\n";
        }
        else if (type == 2)
        {
                cout << "Content-type: application/json\r\n\r\n";
        }
}

void Tools::printJson(Json::Value root, int type = 1)
{
        if (type == 1)  // FastWriter
        {
                Json::FastWriter fastWriter;
                cout << fastWriter.write(root);
        }
        else if (type == 2)     // StyledWriter
        {
                Json::StyledWriter styledWriter;
                cout << styledWriter.write(root);
        }
}

// make errCode and errInfo
Json::Value Tools::jsonEncode(int errCode, char* errInfo)
{
        Json::Value root;
        root["errCode"] = Json::Value(errCode);
        root["errInfo"] = Json::Value(errInfo);
        return root;
}

void Tools::printHeaderAndJson(Json::Value root, int headerType = 1, int jsonType = 1)
{
        this->printHeader(headerType);
        this->printJson(root, jsonType);
}

Json::Value Tools::getPostData()
{
        char *postStr;
        // check data size
        if (getenv("CONTENT_LENGTH"))
        {
                int len;
                sscanf(getenv("CONTENT_LENGTH"), "%d", &len);
                postStr = new char[len * 2];
                int tot = 0;
                char c;
                // format post data
                for (int i = 0; i < len; i++)
                {
                        c = getchar();
                        if (c == '\n' || c == '\r' || c == '\t')
                        {
                                continue;
                        }
                        postStr[tot++] = c;
                }
                postStr[tot] = '';
        }
        Json::Value root;
        Json::Reader reader;
        if (!reader.parse(postStr, root))
        {
                this->printHeaderAndJson(this->jsonEncode(40200, (char*)"Json format error"), 2, 2);
                exit(1);
        }

        return root;
}

Json::Value Tools::getGetData()
{
        Json::Value root;
        return root;
}
 
3.2.2.5 User类 
// User.h
#include 
#include 
#include 
#include "MyDB.h"
#include "Tools.h"
#include "json/json.h"
using namespace std;

class User
{
        private:
                MyDB *db;
                Tools *tools;
                char* sql;
                Json::Value root;

        public:
                User();
                User(MyDB* db, Tools* tools);
                ~User();
                Json::Value insert(const char* username, const char* pwd);
                Json::Value _delete(int id);
                Json::Value update(int id, const char* username,const char* pwd, int type);
                Json::Value select(int id);
                Json::Value _register(Json::Value postData);
                Json::Value login(Json::Value postData);
};
 
// User.cpp
#include "../include/User.h"

User::User()
{

}

User::User(MyDB* db, Tools* tools)
{
        this->db = db;
        this->tools = tools;
        this->sql = new char[300];
}

User::~User()
{

}

Json::Value User::insert(const char* username, const char* pwd)
{
        char curTime[30];
        this->tools->getDatetime(curTime);

        sprintf(sql, "insert into users(username, password, createTime) values(\"%s\", \"%s\", \"%s\");", username, pwd, curTime);
        root = this->db->execSQL(sql);

        return root;
}

Json::Value User::_delete(int id)
{
        sprintf(sql, "delete from users where id = %d;", id);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value User::update(int id, const char* username, const char* pwd, int type)
{
        if (type == 1)  // update username
        {
                sprintf(sql, "update users set username = \"%s\" where id = %d;", username, id);
        }
        else if (type == 2)     // update password
        {
                sprintf(sql, "update users set password = \"%s\" where id = %d;", pwd, id);
        }
        root = this->db->execSQL(sql);
        return root;
}

Json::Value User::select(int id)
{
        sprintf(sql, "select * from users where id = %d;", id);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value User::_register(Json::Value postData)
{
        Json::Value root;
        if (postData.isMember("username") && postData.isMember("password"))
        {
                sprintf(sql, "select count(1) from users where username = \"%s\";", postData["username"].asString().c_str());
                Json::Value result = this->db->execSQL(sql);
                int flag;
                sscanf(result["data"][0u]["0"].asString().c_str(), "%d", &flag);
                if (flag >= 1)
                {
                        root = this->tools->jsonEncode(40303, (char*)"Username is exists");
                }
                else
                {
                        result = this->insert(postData["username"].asString().c_str(), postData["password"].asString().c_str());
                        root["errCode"] = result["errCode"];
                        root["errInfo"] = result["errInfo"];
                }
        }
        else
        {
                root = this->tools->jsonEncode(40300, (char*)"Params is missing");
        }
        return root;
}

Json::Value User::login(Json::Value postData)
{
        Json::Value root;
        if (postData.isMember("username") && postData.isMember("password"))
        {
                sprintf(sql, "select count(1) from users where username = \"%s\" and password = \"%s\";", postData["username"].asString().c_str(), postData["password"].asString().c_str());
                Json::Value result = this->db->execSQL(sql);
                int flag;
                sscanf(result["data"][0u]["0"].asString().c_str(), "%d", &flag);
                if (!flag)
                {
                        root = this->tools->jsonEncode(40301, (char*)"Username or password is wrong");
                }
                else
                {
                        root = this->tools->jsonEncode(0, (char *)"Ok");
                }

                // root["0"] = Json::Value(result["data"][0u]["0"].asInt());
        }
        else
        {
                root = this->tools->jsonEncode(40302, (char*)"Params is missing");
        }
        return root;
}
 
3.2.2.6 Note类 
// Note.h
#ifndef _NOTE_H
#define _NOTE_H

#include 
#include 
#include 
#include "MyDB.h"
#include "Tools.h"
#include "json/json.h"
using namespace std;

class Note
{
        private:
                MyDB *db;
                Tools *tools;
                char *sql;
                Json::Value root;

        public:
                Note();
                Note(MyDB *db, Tools *tools);
                ~Note();
                Json::Value insert(int userId, const char* content, int tag);
                Json::Value _delete(int id);
                Json::Value update(int id, const char* content);
                Json::Value select(int id, int type);
                Json::Value addNote(Json::Value postData);
                Json::Value deleteNote(Json::Value postData);
                Json::Value updateNote(Json::Value postData);
                Json::Value selectNote(Json::Value postDate);
};

#endif
 
< postData["noteIds"].size(); i++)
        {
                sprintf(sql, "delete from notes where id = %d and userId = %d;", postData["noteIds"][i].asInt(), postData["userId"].asInt());
                result = this->// Note.cpp
#include "../include/Note.h"

Note::Note()
{
        this->db = new MyDB();
        this->db->initDB((char *)"localhost", (char *)"root", (char *)"fast1111", (char *)"test");
        this->sql = new char[300];
}

Note::Note(MyDB *db, Tools *tools)
{
        this->db = db;
        this->tools = tools;
        this->sql = new char[300];
}

Note::~Note()
{

}

Json::Value Note::insert(int userId, const char* content, int tag = 1)
{
        char curTime[40];

        // format values
        tools->getDatetime(curTime);

        sprintf(sql, "insert into notes(userId, content, tag, createTime) values(%d, \"%s\", %d, \"%s\");",userId, content, tag, curTime);

        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::_delete(int id)
{
        sprintf(sql, "delete from notes where id = %d;", id);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::update(int id, const char* content)
{
        sprintf(sql, "update notes set content = \"%s\" where id = %d;", content, id);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::select(int id, int type = 0)
{
        if (type == 1)  // use note id to select
        {
                sprintf(sql, "select * from notes where id = %d;", id);
        }
        else if (type == 2)     // use user id to select
        {
                sprintf(sql, "select * from notes where userId = %d;", id);
        }
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::addNote(Json::Value postData)
{
        Json::Value root;
        char curTime[40];
        this->tools->getDatetime(curTime);
        sprintf(sql, "insert into notes(userId, content, createTime) values(%d, \"%s\", \"%s\");", postData["userId"].asInt(), postData["content"].asString().c_str(), curTime);
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::deleteNote(Json::Value postData)
{
        Json::Value root;
        Json::Value result;

        // use transaction to aviod some error
        memset(sql, 0x00, sizeof(sql));
        memcpy(sql, "set autocommit = 0;", 20);
        root = this->db->execSQL(sql);
        if (root["errCode"].asInt())
        {
                return root;
        }
        memcpy(sql, "start transaction;", 20);
        root = this->db->execSQL(sql);
        if (root["errCode"].asInt())
        {
                return root;
        }
        // delete note in the order it was received
        for (int i = 0; i db->execSQL(sql);
                if (result["errCode"].asInt())
                {
                        break;
                }
        }
        // hava error, need to rollback
        if (result["errCode"].asInt())
        {
                memcpy(sql, "rollback;", 10);
                result = this->db->execSQL(sql);
                root = this->tools->jsonEncode(40401, (char *)"Delete notes wrong");
        }
        // no error, delete all, return Ok
        else
        {
                memcpy(sql, "commit;", 10);
                result = this->db->execSQL(sql);
                root = this->tools->jsonEncode(0, (char*)"Ok");
        }

        return root;
}

Json::Value Note::updateNote(Json::Value postData)
{
        Json::Value root;
        // check necessary params, type and noteId
        if (!postData.isMember("type") || !postData.isMember("noteId") || !postData.isMember("userId"))
        {
                return this->tools->jsonEncode(40402, (char *)"Params is missing");
        }
        switch (postData["type"].asInt())
        {
                case 1:         // update content
                {
                        if (!postData.isMember("content"))
                        {
                                return this->tools->jsonEncode(40402, (char *)"Params is missing");
                        }
                        sprintf(sql, "update notes set content = \"%s\" where id = %d and userId = %d;", postData["content"].asString().c_str(), postData["noteId"].asInt(), postData["userId"].asInt());                        break;
                }
                case 2:         // update tag
                {
                        if (!postData.isMember("tag"))
                        {
                                return this->tools->jsonEncode(40402, (char*)"Params is missing");
                        }
                        sprintf(sql, "update notes set tag = %d where id = %d and userId = %d;", postData["tag"].asInt(), postData["noteId"].asInt(), postData["userId"].asInt());
                        break;
                }
                case 3:         // update content and tag
                {
                        if (!postData.isMember("content") || !postData.isMember("tag"))
                        {
                                return this->tools->jsonEncode(40402, (char*)"Params is missing");
                        }
                        sprintf(sql, "update notes set content = \"%s\", tag = %d where id = %d and userId = %d;", postData["content"].asString().c_str(), postData["tag"].asInt(), postData["noteId"].asInt(), postData["userId"].asInt());
                        break;
                }
                default:
                {
                        return this->tools->jsonEncode(40403, (char*)"Type error");
                        break;
                }
        }
        root = this->db->execSQL(sql);
        return root;
}

Json::Value Note::selectNote(Json::Value postData)
{
        Json::Value root;
        if (!postData.isMember("userId"))
        {
                return this->tools->jsonEncode(40404, (char*)"Params is missing");
        }
        int offset = 0, limit = 10, type = 1;
        char* orderStr = (char*)"asc";
        if (postData.isMember("offset"))
        {
                offset = postData["offset"].asInt();
        }
        if (postData.isMember("limit"))
        {
                limit = postData["limit"].asInt();
        }
        if (postData.isMember("type"))
        {
                type = postData["type"].asInt();
        }
        if (postData.isMember("order") && postData["order"].asInt() == 2)
        {
                orderStr = (char*)"desc";
        }

        switch (type)
        {
                case 1:         // select all fields
                {
                        sprintf(sql, "select * from notes where userId = %d order by createTime %s limit %d, %d;", postData["userId"].asInt(), orderStr, offset, limit);
                        break;
                }
                default:
                {
                        return this->tools->jsonEncode(40404, (char*)"Type error");
                }
        }
        root = this->db->execSQL(sql);
        return root;
}
 
3.2.2.7 Makefile 
objects = temp/Main.o \
          temp/Start.o \
          temp/MyDB.o \
          temp/Tools.o \
          temp/Note.o \
          temp/User.o

bin/main: $(objects)
        g++ -g -o $@ $^ -Llibs -ljson_linux-gcc-9_libmt -lmysqlclient
temp/%.o: source/%.cpp include/%.h
        g++ -o $@ -c $< -g

clean:
        rm -rf $(objects)

3.3 案例结果 3.3.1 用户注册

3.3.2 用户登录

3.3.3 发布笔记

ps: 此时还未加入“userId”检查功能

3.3.4 删除笔记

3.3.5 修改笔记

3.3.6 查询笔记

ps: 返回集中没有记录的字段名,暂时没找到mysql的哪个函数会提供字段名,就先用列号代替了
    4 问题总结
  • mysql, apache建议使用apt命令安装
  • 需要学习静态库的编译
  • 需要学习makefile文件的编写
  • jsoncpp的数组使用时会出问题,比如data[“note”][0], 编译到[0]时会报错,好像是因为jsoncpp内部重载了[(char *)]和[int],例子中无法判断,可以使用[0u]通过编译
    1. 5 参考博客
  • 風の住む街~: Ubuntu20.04安装Mysql
  • JstuCheng: Ubuntu安装使用apache2
  • Acuity.: jsoncpp应用(Linux环境)
  • 肥叔菌: JsonCpp入门一:在linux下编译使用JsonCpp
  • Devin_white: jsoncpp应用(Linux环境)
  • 果冻虾仁: C++后台实践:古老的CGI与Web开发
  • ShiningStarPxx: Apache下c语言的cgi如何获得Get,Post参数
  • smilejiasmile: gcc编译以及Makefile与GDB调试
  • tp_16b: Linux——makefile编写
  • IT8343: jsoncpp判断key是否存在以及类型
  • php中文网: c语言mysql数据库事务开始、提交、回滚范例_MySQL
  • 深海的小鱼儿: CGI 环境变量
  • 6 其他
    这篇博客作为学习过程的一个记录,方便以后查看。



    目前还有很多内容没有完善,实现的比较粗糙,只是按着自己的想法做的,后面有机会也会再完善完善。



    期间遇到了很多问题,参考了很多前辈的博客,远不止上面所列举的博客,学习了不少新知识。



    我这边测试的基本功能都可以实现,如发现错误,请不吝赐教。


    欢迎分享,转载请注明来源:内存溢出

    原文地址: https://outofmemory.cn/langs/562995.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-04-02
    下一篇 2022-04-02

    发表评论

    登录后才能评论

    评论列表(0条)

    保存