iOS開(kāi)發(fā)實(shí)戰(zhàn)-時(shí)光記賬Demo 網(wǎng)絡(luò)版

寫在前面
弄了下個(gè)人站...防止內(nèi)容再次被鎖定...所有東西都在這里面
welcome~
個(gè)人博客

之前寫了一個(gè)本地?cái)?shù)據(jù)庫(kù)版本 戳這里
現(xiàn)在這個(gè)就是增加了后臺(tái) 登錄注冊(cè)頁(yè)面以及web的上傳記錄展示頁(yè)面
含有少量php有興趣可以看下
另外demo中包括數(shù)據(jù)庫(kù)操作鼓寺、json乍丈、網(wǎng)絡(luò)請(qǐng)求等都沒(méi)有用到第三方庫(kù)抹缕,所以網(wǎng)絡(luò)方面的邏輯可能有所欠缺,大神請(qǐng)輕拍。

效果

效果.gif

分析

很簡(jiǎn)單的分析把大致需要編寫的模塊列出

服務(wù)器交互.png

客戶端部分

分析

  • 與本地版的demo相比主要是多了服務(wù)器請(qǐng)求操作

新增數(shù)據(jù)庫(kù)內(nèi)容:

  • Users表
    與Tally表關(guān)系:一對(duì)多


    user表

    相反Tally與Users的關(guān)系就是:一對(duì)多


    tally表
  • flag字段 決定是否上傳

  • 需要發(fā)送請(qǐng)求的位置

  • 登錄
  • 注冊(cè)
  • 登錄成功后第一次加載
  • 新增賬單
  • 修改賬單
  • 刪除賬單

代碼

登錄

登錄時(shí)向服務(wù)器發(fā)送用戶名和密碼渠驼,當(dāng)然只有兩個(gè)結(jié)果:未注冊(cè) 和 密碼錯(cuò)誤

#import "LoginViewController.h"

@interface LoginViewController ()<ServerOperationsDelegate>
@property (weak, nonatomic) IBOutlet UITextField *userNameField;
@property (weak, nonatomic) IBOutlet UITextField *userPswField;

@end

@implementation LoginViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"登錄";
    [[CoreDataOperations sharedInstance] loadTallyTypeToSqlite];
    // Do any additional setup after loading the view.
}

- (void)viewWillAppear:(BOOL)animated{
    self.userNameField.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"userName"];
    self.userPswField.text = nil;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
//去注冊(cè)
- (IBAction)clickRegister:(id)sender {
    [self.userPswField resignFirstResponder];
    [self.userPswField resignFirstResponder];
}

//輸入檢查 6-20為正常字符
- (BOOL)inputCheck:(NSString*)passWord{
    NSString *passWordRegex = @"^[a-zA-Z0-9]{6,20}+$";
    NSPredicate *passWordPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",passWordRegex];
    return [passWordPredicate evaluateWithObject:passWord];
    
}

//去登錄
- (IBAction)clickLogin:(id)sender {
    
    //輸入檢查
    BOOL userNameCheck = [self inputCheck:self.userNameField.text];
    BOOL userPswCheck = [self inputCheck:self.userPswField.text];
    if (!userNameCheck | !userPswCheck) {
        [self showAlertInfoWithTag:999 andMessage:@"用戶名或密碼出錯(cuò)\n請(qǐng)輸入6-20位合法字符"];
        return;
    }
    //鍵盤收起
    [self.userPswField resignFirstResponder];
    [self.userNameField resignFirstResponder];
    
    ServerOperations *op = [ServerOperations sharedInstance];
    op.delegate = self;
    [op loginWithUser:self.userNameField.text andPsw:self.userPswField.text];
}

//登錄結(jié)果
- (void)didLoginBackWithTag:(int)tag{
    [self loginAlertWithReslut:tag];
}

//驗(yàn)證登錄
- (void)loginAlertWithReslut:(int)result{
    switch (result) {
        case 0:
            //連接遠(yuǎn)程數(shù)據(jù)庫(kù)失敗
            [self showAlertInfoWithTag:result andMessage:@"連接遠(yuǎn)程數(shù)據(jù)庫(kù)失敗"];
            break;
        case 1:
            //驗(yàn)證成功
            [self performSegueWithIdentifier:@"toHome" sender:nil];
            break;
        case 2:
            //密碼錯(cuò)誤
            [self showAlertInfoWithTag:result andMessage:@"密碼錯(cuò)誤"];
            break;
        case 3:
            //用戶不存在
            [self showAlertInfoWithTag:result andMessage:@"用戶名不存在\n請(qǐng)注冊(cè)"];
            break;
        default:
            break;
    }
}

//彈出提示框
- (void)showAlertInfoWithTag:(int)tag andMessage:(NSString*)message {
    UIAlertController *alertVC =[UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    [alertVC addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:nil]];
    if (tag == 3) {
        [alertVC addAction:[UIAlertAction actionWithTitle:@"注冊(cè)" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [self performSegueWithIdentifier:@"toRegister" sender:nil];
        }]];
    }
    [self presentViewController:alertVC animated:YES completion:nil];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    NSLog(@"準(zhǔn)備push");
    //本地保存用戶名
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"isLoaded"];
    [[NSUserDefaults standardUserDefaults] setObject:self.userNameField.text forKey:@"userName"];
    
}
@end

注冊(cè)

注冊(cè)也很簡(jiǎn)單,發(fā)送注冊(cè)信息給服務(wù)器,服務(wù)器判斷下用戶名是否存在就行儡陨。

#import "RegisterViewController.h"

@interface RegisterViewController ()<ServerOperationsDelegate>
@property (weak, nonatomic) IBOutlet UITextField *userNameField;
@property (weak, nonatomic) IBOutlet UITextField *userPswField;

@end

@implementation RegisterViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"注冊(cè)";
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

//輸入檢查 6-20為正常字符
- (BOOL)inputCheck:(NSString*)passWord{
    NSString *passWordRegex = @"^[a-zA-Z0-9]{6,20}+$";
    NSPredicate *passWordPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",passWordRegex];
    return [passWordPredicate evaluateWithObject:passWord];
    
}

- (void)didRegisterBackWithTag:(int)tag{
    [self loginAlertWithReslut:tag];
}

//提交注冊(cè)
- (IBAction)clickRegister:(id)sender {
    
    //輸入檢查
    BOOL userNameCheck = [self inputCheck:self.userNameField.text];
    BOOL userPswCheck = [self inputCheck:self.userPswField.text];
    if (!userNameCheck | !userPswCheck) {
        [self showAlertInfoWithTag:0 andMessage:@"用戶名或密碼出錯(cuò)\n請(qǐng)輸入6-20位合法字符"];
        return;
    }
    
    //取消鍵盤響應(yīng)
    [self.userNameField resignFirstResponder];
    [self.userPswField resignFirstResponder];

    ServerOperations *ops = [ServerOperations sharedInstance];
    ops.delegate = self;
    [ops registerWithUser:self.userNameField.text andPsw:self.userPswField.text];
}

//登錄提示
- (void)loginAlertWithReslut:(int)result{
    switch (result) {
        case 0:
            //連接遠(yuǎn)程數(shù)據(jù)庫(kù)失敗
            [self showAlertInfoWithTag:0 andMessage:@"連接遠(yuǎn)程數(shù)據(jù)庫(kù)失敗"];
            break;
        case 1:
            //注冊(cè)成功
            [self showAlertInfoWithTag:1 andMessage:@"注冊(cè)成功"];
            break;
        case 2:
            //注冊(cè)失敗 用戶已經(jīng)存在
            [self showAlertInfoWithTag:2 andMessage:@"注冊(cè)失敗\n用戶已經(jīng)存在"];
            break;
        default:
            break;
    }
}

//彈出提示框
- (void)showAlertInfoWithTag:(int)tag andMessage:(NSString*)message {
    UIAlertController *alertVC =[UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    if (tag == 1) {
        [alertVC addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [[NSUserDefaults standardUserDefaults] setObject:self.userNameField.text forKey:@"userName"];
            [self.navigationController popViewControllerAnimated:YES];
        }]];

    }else{
        [alertVC addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:nil]];

    }
    [self presentViewController:alertVC animated:YES completion:nil];
}

@end

向服務(wù)器發(fā)送的請(qǐng)求操作

整個(gè)操作寫成一個(gè)單例

#import <Foundation/Foundation.h>
#import "CoreDataOperations.h"

//服務(wù)器地址
//static NSString* const kServerUrl = @"http://localhost/timetally/";
static NSString* const kServerUrl = @"http://timetallydemo.duapp.com/";

@protocol ServerOperationsDelegate <NSObject>

@optional

//登錄結(jié)果回調(diào)
- (void)didLoginBackWithTag:(int)tag;
//注冊(cè)結(jié)果回調(diào)
- (void)didRegisterBackWithTag:(int)tag;
//成功上傳
- (void)didUploadTallySuccessed;
//上傳失敗
- (void)didUploadTallyFaild;

@end

@interface ServerOperations : NSObject

@property(nonatomic,strong)id<ServerOperationsDelegate> delegate;

+ (instancetype)sharedInstance;
//發(fā)送服務(wù)器請(qǐng)求加載數(shù)據(jù)
- (void)loadDataFormServer;
//上傳賬單至服務(wù)器
- (void)uploadTallyToServer;
//服務(wù)器刪除指定賬單
- (void)deleteTallyInServerWithIdentity:(NSString*)identity;

//登錄到服務(wù)器
- (void)loginWithUser:(NSString*)username andPsw:(NSString*)psw;
//注冊(cè)到服務(wù)器
- (void)registerWithUser:(NSString*)username andPsw:(NSString*)psw;
@end
#import "ServerOperations.h"

@implementation ServerOperations
static ServerOperations *instance = nil;

+ (instancetype)sharedInstance
{
    return [[ServerOperations alloc] init];
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });
    return instance;
}

- (instancetype)init
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super init];
    });
    return instance;
}

//發(fā)送服務(wù)器請(qǐng)求加載數(shù)據(jù)
- (void)loadDataFormServer{
    
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"showusertally.php"]]];
    [quest setHTTPMethod:@"POST"];
    //POST 用戶名
    NSString *userName = [[NSUserDefaults standardUserDefaults] objectForKey:@"userName"];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:userName,@"username", nil];
    NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //json解碼
        NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"server下載結(jié)果-----%@",dataStr);
        if ([dataStr isEqualToString:@"0"]) {
            return ;
        }
        NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
        if (jsonArray.count != 0) {
            [[CoreDataOperations sharedInstance] loadFromServerWithDataArray:jsonArray];
        }
    }];
    
    [task resume];

}

//上傳賬單至服務(wù)器
- (void)uploadTallyToServer{
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"uploadtally.php"]]];
    [quest setHTTPMethod:@"POST"];
    //POST 信息
    NSArray *postArray = [[CoreDataOperations sharedInstance] getAllTallyWithArray];
    NSData *postData = [NSJSONSerialization dataWithJSONObject:postArray options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        int flag = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] intValue];
        NSLog(@"server上傳結(jié)果 %d",flag);
        if (flag==1 || flag == 9) {
            //寫入成功
            for (NSDictionary *dict in postArray) {
                [[CoreDataOperations sharedInstance] uploadServerSucceedWithIdentity:dict[@"identity"]];
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(didUploadTallySuccessed)]) {
                    [self.delegate didUploadTallySuccessed];
                }
            });
           
        }else{
            dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(didUploadTallyFaild)]) {
                    [self.delegate didUploadTallyFaild];
                }
            });

        }
        
    }];
    
    [task resume];

}

//登錄到服務(wù)器
- (void)loginWithUser:(NSString*)username andPsw:(NSString*)psw {
    //創(chuàng)建URL請(qǐng)求
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"login.php"]]];
    //post請(qǐng)求
    [quest setHTTPMethod:@"POST"];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:username,@"username",psw,@"userpsw", nil];
    //字典轉(zhuǎn)json
    NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    
    //建立連接
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        int result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] intValue];
        NSLog(@"server登錄結(jié)果 %d ",result);

        dispatch_async(dispatch_get_main_queue(), ^{
            if ([self.delegate respondsToSelector:@selector(didLoginBackWithTag:)]) {
                [self.delegate didLoginBackWithTag:result];
            }
            
        });
        
    }];
    
    [task resume];

}

//注冊(cè)到服務(wù)器
- (void)registerWithUser:(NSString*)username andPsw:(NSString*)psw{
    //創(chuàng)建URL請(qǐng)求
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"register.php"]]];
    //post請(qǐng)求
    [quest setHTTPMethod:@"POST"];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:username,@"username",psw,@"userpsw", nil];
    //字典轉(zhuǎn)json
    NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    
    //建立連接
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        int result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] intValue];
        NSLog(@"server注冊(cè)結(jié)果 %d ",result);
        //回到主線程
        dispatch_async(dispatch_get_main_queue(), ^{
            if ([self.delegate respondsToSelector:@selector(didRegisterBackWithTag:)]) {
                [self.delegate didRegisterBackWithTag:result];
            }
        });
    }];
    
    [task resume];
}

//從服務(wù)器刪除賬單
- (void)deleteTallyInServerWithIdentity:(NSString*)identity{
    //創(chuàng)建URL請(qǐng)求
    NSMutableURLRequest *quest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[kServerUrl stringByAppendingString:@"deletetally.php"]]];
    //post請(qǐng)求
    [quest setHTTPMethod:@"POST"];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:identity,@"identity", nil];
    //字典轉(zhuǎn)json
    NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    [quest setHTTPBody:postData];
    //建立連接
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:quest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        int result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] intValue];
        if (result == 0) {
            NSLog(@"%d server鏈接數(shù)據(jù)庫(kù)失敗",result);
        }else if (result == 1){
            NSLog(@"%d server刪除賬單成功",result);
        }else if (result == 2){
            NSLog(@"%d server刪除賬單失敗",result);
        }
    }];
    
    [task resume];
}
@end

服務(wù)端部分

php新手 高手勿噴
文件結(jié)構(gòu)


文件結(jié)構(gòu)

其中index.php 和 useruploadrecords.php是web斷的登錄展示頁(yè)面

數(shù)據(jù)庫(kù)部分字段和表基本與客戶端相同可以看CREATE的代碼

代碼

配置文件

<?php
define('MYSQL_HOST','localhost');
define('MYSQL_USER','root');
define('MYSQL_PSW','');
define('MYSQL_DBNAME','TimeTally');

所有數(shù)據(jù)庫(kù)操作

<?php
require_once 'config.php';

/**鏈接并選擇數(shù)據(jù)表
 * @param $table 鏈接表
 * @return mysqli 鏈接link
 */
function connectDBandSelectTable($table) {
    $con = mysqli_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PSW);
    mysqli_set_charset($con,'utf8');
    if ($con){
        mysqli_select_db($con,MYSQL_DBNAME);
        if(mysqli_num_rows(mysqli_query($con,"SHOW TABLES LIKE '".$table."'"))==0) {
            if ($table == 'Tally'){
                $sql = "CREATE TABLE $table 
                        ( id INT NOT NULL AUTO_INCREMENT , 
                        username VARCHAR(50) NOT NULL ,
                        date VARCHAR(50) NOT NULL , 
                        identity VARCHAR(1024) NOT NULL , 
                        typename VARCHAR(50) NOT NULL , 
                        income DOUBLE NOT NULL , 
                        expenses DOUBLE NOT NULL , 
                        timestamp DOUBLE NOT NULL ,
                        uploadtime TIMESTAMP NOT NULL,
                        PRIMARY KEY (id))";
                mysqli_query($con,$sql);

            }elseif ($table == 'Users'){
                $sql = "CREATE TABLE $table 
                        (id INT  NOT  NULL AUTO_INCREMENT, 
                        username VARCHAR (100) NOT  NULL ,
                        userpsw VARCHAR (100) NOT  NULL , 
                        session INT  NOT  NULL  DEFAULT  0,
                        PRIMARY KEY (id))";
                mysqli_query($con,$sql);
            }
        }
    }
    return $con;
}

/**注冊(cè)
 * @param $table 表
 * @param $username 用戶名
 * @param $userpsw 用戶密碼
 * @return int 0:連接失敗 1:注冊(cè)成功 2:用戶已存在
 */
function register($table,$username,$userpsw){
    $con = connectDBandSelectTable($table);
    if ($con){
        $isExist = existQuery($table,"username",$username);
        if ($isExist == 2){
            $sql = "INSERT INTO $table (username, userpsw) VALUES ('$username',MD5('$userpsw'))";
            $result = mysqli_query($con,$sql);
            if ($result){
                //成功
                return 1;
            }
        }else if ($isExist == 1){
            //已存在
            return 2;
        }
        //關(guān)閉數(shù)據(jù)庫(kù)
        mysqli_close($con);
    }
    //連接數(shù)據(jù)庫(kù)失敗
    return 0;
}

/**查詢字段是否存在
 * @param $table 表名
 * @param $field 查詢字段名
 * @param $obj 查詢對(duì)象
 * @return 0:連接失敗 1:存在 2:不存在
 */
function existQuery($table,$field,$obj){
    $con = connectDBandSelectTable($table);
    if ($con){
        $sql = "SELECT * FROM $table WHERE $field = '$obj'";
        $result = mysqli_query($con,$sql);
        if (mysqli_num_rows($result) > 0){
            return 1;
        }else{
            return 2;
        }
    }
    return 0;
}

/**獲取該用戶下所有賬單
 * @param $table 表名
 * @param $user 用戶名
 * @return int|string 0:連接失敗或無(wú)法查詢  string:json數(shù)組;
 */
function getUserTally($table,$user){
    $con = connectDBandSelectTable($table);
    if ($con){
        $sql = "SELECT * FROM $table WHERE username = '$user'";
        $arr = mysqli_query($con,$sql);
        $num = mysqli_num_rows($arr);
        if ($num > 0){
            for ($i=0;$i<$num;$i++){
                $results[] = mysqli_fetch_assoc($arr);
            }
            mysqli_close($con);
            return json_encode($results);
        }
    }
    //連接失敗或無(wú)法查詢
    return 0;
}

/**登錄驗(yàn)證
 * @param $username 用戶名
 * @param $userpsw  用戶密碼
 * @return int  0:連接失敗 1:驗(yàn)證成功 2:密碼錯(cuò)誤 3:用戶不存在
 */
function verifyLogin($username,$userpsw){
    //查詢用戶名是否存在
    $table = 'Users';
    $con = connectDBandSelectTable($table);
    if ($con){
        $sql = "SELECT * FROM $table WHERE username = '$username'";
        $isExist = mysqli_query($con,$sql);
        if (mysqli_num_rows($isExist) > 0) {
            //存在并繼續(xù)驗(yàn)證 密碼
            $result = mysqli_fetch_array($isExist);
            $psw = $result['userpsw'];
            if (md5($userpsw) == $psw){
                //密碼正確
                return 1;
            }else {
                //密碼錯(cuò)誤
                return 2;
            }

        }else {
            //用戶不存在
            return 3;
        }
        mysqli_close($con);
    }

    //數(shù)據(jù)庫(kù)連接失敗
    return 0;

}

/**上傳更新或新增賬單數(shù)據(jù)
 * @param $table  寫入表名
 * @param $tallyJson 傳入解析后的json
 * @return int -1:數(shù)據(jù)庫(kù)連接失敗 0:沒(méi)有寫入 1:寫入成功 2:寫入失敗 9:更新數(shù)據(jù)
 */
function uploadTally($table,$tallyJson){
    $con = connectDBandSelectTable($table);
    $r = 0;
    if ($con){
        //根據(jù)json解析出來(lái)的數(shù)組的長(zhǎng)度 更新對(duì)應(yīng)identity數(shù)值
        for ($i=0;$i<count($tallyJson);$i++){
            $identity = $tallyJson[$i]->identity;
            $isExistSql = "SELECT * FROM $table WHERE identity LIKE '$identity'";
            $isExisResult = mysqli_query($con,$isExistSql);
            if (mysqli_num_rows($isExisResult) > 0){
                $typename = $tallyJson[$i]->typename;
                $income = $tallyJson[$i]->income;
                $expenses = $tallyJson[$i]->expenses;
                $timestamp = $tallyJson[$i]->timestamp;
                $updateSql = "UPDATE $table 
                          SET typename = '$typename',
                          income='$income' ,
                          expenses = '$expenses',
                          uploadtime = CURRENT_TIMESTAMP,
                          timestamp = '$timestamp'
                          WHERE identity = '$identity'";
                mysqli_query($con,$updateSql);
                $r = 9;
            } else{
                //沒(méi)有查詢到identity則進(jìn)入新增
                $typename = $tallyJson[$i]->typename;
                $income = $tallyJson[$i]->income;
                $expenses = $tallyJson[$i]->expenses;
                $username = $tallyJson[$i]->username;
                $date = $tallyJson[$i]->date;
                $timestamp = $tallyJson[$i]->timestamp;
                //mysql插入
                $intoSql = "INSERT INTO $table
                          (id,username,date,identity,typename,income,expenses,timestamp,uploadtime)
                          VALUES (NULL, '$username', '$date','$identity','$typename','$income','$expenses','$timestamp',CURRENT_TIMESTAMP)";
                $insertResult = mysqli_query($con,$intoSql);
                if ($insertResult){
                    //新增成功
                   $r = 1;
                }else{
                    //新增失敗
                    $r = 2;
                }
            }
        }
    mysqli_close($con);
    }else{
        //連接失敗
        $r = -1;
    }
    return $r;
}

/**
 * @param $table 表名
 * @param $identity 需要?jiǎng)h除的標(biāo)識(shí)
 * @return int 0:鏈接數(shù)據(jù)庫(kù)失敗 1:刪除成功 2:刪除失敗
 */
function deleteTally($table,$identity){
    $con = connectDBandSelectTable($table);
    if ($con){
        $sql = "DELETE FROM $table WHERE identity = '$identity'";
        $result = mysqli_query($con,$sql);
        if ($result){
            return 1;
        }else{
            return 2;
        }
    }
    mysqli_close($con);
    return 0;
}

/**獲取post的json數(shù)據(jù) 并連接數(shù)據(jù)庫(kù)表
 * @param $table 表名
 * @return mixed json數(shù)據(jù)
 */
function getPostJsonValue($table){
//獲取post數(shù)據(jù)
    $postValue = file_get_contents("php://input");
//json解析
    $postJson = json_decode($postValue);
    $currentTable = $table;
//連接并選擇數(shù)據(jù)庫(kù)
    connectDBandSelectTable($currentTable);
    return $postJson;
}

各個(gè)調(diào)用頁(yè)面

登錄

<?php
require_once 'dboperations.php';
//獲取post數(shù)據(jù)
$table = 'Users';
$postValue = getPostJsonValue($table);
//登錄驗(yàn)證
$result = verifyLogin($postValue->username,$postValue->userpsw);
echo $result;

注冊(cè)

<?php
require_once 'dboperations.php';
//獲取post數(shù)據(jù)并連接數(shù)據(jù)庫(kù)表
$currentTable = 'Users';
$postJson = getPostJsonValue($currentTable);
//注冊(cè)
$result = register($currentTable,$postJson->username,$postJson->userpsw);
echo $result;

下載服務(wù)端數(shù)據(jù)

<?php
require_once 'dboperations.php';
$table = 'Tally';
$postValue = getPostJsonValue($table);
$reslut = getUserTally($table,$postValue->username);
echo $reslut;

上傳

<?php
require_once 'dboperations.php';
$table = 'Tally';
$postJson = getPostJsonValue($table);
$result = uploadTally($table,$postJson);
echo $result;

刪除

<?php
require_once 'dboperations.php';
$table = 'Tally';
$postValue = getPostJsonValue($table);
$reslut = deleteTally($table,$postValue->identity);
echo $reslut;

web端

首頁(yè)登錄

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    <title>Document</title>
</head>
<body>
<form id="slick-login" action="useruploadrecords.php" method="get" >
    <input type="text" name="username" placeholder="用戶名">
    <input type="password" name="userpsw" placeholder="密碼">
    <input type="submit" value="Log In"/>
</form>
</body>
</html>

內(nèi)容頁(yè)



<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" type="text/css" href="css/tablestyle.css" />
    <title>Document</title>
</head>
<body>
<?php
require_once 'dboperations.php';
if (isset($_GET["username"]) && isset($_GET["userpsw"])){
    $username = $_GET["username"];
    $userpsw = $_GET["userpsw"];
}

$verifty = verifyLogin($username,$userpsw);
if ($verifty == 1){
    $table = 'Tally';
    $con = connectDBandSelectTable($table);
    $sql = "SELECT * FROM $table WHERE username = '$username' ORDER BY uploadtime DESC ";
    $res = mysqli_query($con,$sql);


echo "<table>
<tr><th>歡迎用戶:$username</th><th></th><th></th><th></th><th></th></tr>
<tr><th>操作記錄</th><th>上傳時(shí)間</th><th>賬單類型</th><th>支出</th><th>收入</th></tr>";
    for ($i=0;$i<mysqli_num_rows($res);$i++){
        $resarray = mysqli_fetch_assoc($res);
        $uploadtime = $resarray["uploadtime"];
        $typename = $resarray["typename"];
        $income= $resarray["income"];
        $expenses = $resarray["expenses"];
        ?>
        <tr>
            <td>
                <?php echo $i+1?>
            </td>
            <td>
                <?php echo $uploadtime?>
            </td>
            <td>
                <?php echo $typename?>
            </td>
            <td>
                <?php echo $expenses?>
            </td>
            <td>
                <?php echo $income?>
            </td>
        </tr>
<?php
    }
echo "</table>";
}elseif ($verifty == 2){

    echo "<script> alert('密碼錯(cuò)誤');parent.location.href='index.php'; </script>";

}elseif ($verifty == 3){
    echo "<script> alert('用戶不存在');parent.location.href='index.php'; </script>";
}
?>
</body>
</html>

Demo地址

https://github.com/gongxiaokai/TimeTallyOnlineDemo
其中包含server端的php代碼和客戶端的oc代碼

github

簡(jiǎn)書主頁(yè)

http://www.reibang.com/u/7897b0bd4a55

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市量淌,隨后出現(xiàn)的幾起案子骗村,更是在濱河造成了極大的恐慌,老刑警劉巖呀枢,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胚股,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡裙秋,警方通過(guò)查閱死者的電腦和手機(jī)琅拌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)摘刑,“玉大人进宝,你說(shuō)我怎么就攤上這事〖纤。” “怎么了党晋?”我有些...
    開(kāi)封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我未玻,道長(zhǎng)灾而,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任深胳,我火速辦了婚禮绰疤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舞终。我一直安慰自己轻庆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布敛劝。 她就那樣靜靜地躺著余爆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夸盟。 梳的紋絲不亂的頭發(fā)上蛾方,一...
    開(kāi)封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音上陕,去河邊找鬼桩砰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛释簿,可吹牛的內(nèi)容都是我干的亚隅。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼庶溶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼煮纵!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起偏螺,我...
    開(kāi)封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤行疏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后套像,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體酿联,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年夺巩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了货葬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡劲够,死狀恐怖震桶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情征绎,我是刑警寧澤蹲姐,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布磨取,位于F島的核電站,受9級(jí)特大地震影響柴墩,放射性物質(zhì)發(fā)生泄漏忙厌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一江咳、第九天 我趴在偏房一處隱蔽的房頂上張望逢净。 院中可真熱鬧,春花似錦歼指、人聲如沸爹土。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)胀茵。三九已至,卻和暖如春挟阻,著一層夾襖步出監(jiān)牢的瞬間琼娘,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工附鸽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脱拼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓坷备,卻偏偏與公主長(zhǎng)得像挪拟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子击你,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)谎柄,斷路器丁侄,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 轉(zhuǎn)載自cr180大神DiscuzX2.5完整目錄結(jié)構(gòu)【source程序文件庫(kù)】 /source/admincp后臺(tái)...
    cndaqiang閱讀 835評(píng)論 1 2
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,504評(píng)論 25 707
  • 人生 就是一場(chǎng)電影 你是主角 但卻不能主導(dǎo) 不能循環(huán),暫停朝巫,停止鸿摇。 但卻可以演繹得無(wú)比接近內(nèi)心 卻不能走進(jìn)心靈深處。
    展翅的魚閱讀 225評(píng)論 0 2
  • 正月剛過(guò)劈猿,天氣漸暖拙吉,相信很多人的內(nèi)心開(kāi)始蠢蠢欲動(dòng),思忖著要開(kāi)始減肥、健身。網(wǎng)上隨便一搜就可以搜到很多有關(guān)健身含滴、減肥...
    蠶豆小象閱讀 449評(píng)論 0 8