cocos2dx 实现简单的文件上传到php服务器的demo

来源:互联网 发布:知乎账号存在异常流量 编辑:程序博客网 时间:2024/05/17 23:23

最近刚写完一个cocos2dx,从客户端上传到php服务器的简单测试程序,代码可以复制直接运行


在阅读代码前最好可以先花点时间了解一点php 和libcurl的相关知识,并不会花费太长时间,由于我做的时候对php不是特别熟悉,所有使用libcurl拼凑表单的时候出现一个问题,花了我一阵时间去解决。下方代码只是简单的demo,代码有些粗糙,但对于大家的理解应该影响不大

我使用XAMMP中的Apache服务器,php脚本放在\xampp\htdocs\目录下,并在当前目录创建upload文件夹用来存放上传的文件

1:

ReceiveFile.php

<?php     /* 设定上传目录 */    $dest_dir='./upload';     /* 检测上传目录是否存在 */    if( !is_dir($dest_dir) || !is_writeable($dest_dir) )    {        die("上传目录 ".$dest_dir." 不存在或无法写入");    }     /* 设置允许上传文件的类型 */    $type=array("rar","zip","txt","c","JPG");     /* 获取上传文件信息 */   // $upfile=&$HTTP_POST_FILES['file'];    $upfile=$_FILES["file"];     echo "Upload: " . $_FILES["file"]["name"] . "<br />";    echo "Type: " . $_FILES["file"]["type"] . "<br />";    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";    echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";     /* 获取文件后缀名函数 */    function fileext($filename)    {        return substr(strrchr($filename, '.'), 1);    }     //echo "Temp file: " .  fileext($upfile['name']   . "<br />";    /* 判断上传文件类型 */    if( !in_array( strtolower( fileext($upfile['name'] ) ),$type) )     {        $text=implode(",",$type);        echo "对不起,您只能上传以下类型文件: ",$text,"<br>";     }     else     {        /* 设置文件名为"日期_文件名" */        $dest=$dest_dir.'/'.date("ymdHis")."_".$upfile['name'];         /* 移动上传文件到指定文件夹 */        $state=move_uploaded_file($upfile['tmp_name'],$dest);         if ($state)        {            print("文件上传成功!<br>");            print("文件名:".$dest."<br>");            print("上传的文件大小:".( round($upfile['size'] / 1024,2) )." KB<br>");        }        else        {            /* 处理错误信息 */            switch($upfile['error'])            {                case 1 : die("上传文件大小超出 php.ini:upload_max_filesize 限制<br>");                case 2 : die("上传文件大小超出 MAX_FILE_SIZE 限制<br>");                case 3 : die("文件仅被部分上传<br>");                case 4 : die("没有文件被上传<br>");                case 5 : die("找不到临时文件夹<br>");                case 6 : die("文件写入失败<br>");            }        }     } ?>

2:

upload.html 表单:

<form method="post" enctype="multipart/form-data"  action="ReceiveFile.php">   <input type="file" name="file" id="file" />     <input type="submit" name="submit" value="submit" /></form>

可以直接运行upload.html,如http://127.0.0.1/WD/upload.html

则会出现页面,选择相应的文件上传则会提示


注:php页面会有上传大小超过1M的限制


3:

接下来就要最重要的部分了,使用libcurl库来实现upload.html表单,实现上传功能

Httpupload.h

#ifndef COMMON_LINUX_HTTP_UPLOAD_H__#define COMMON_LINUX_HTTP_UPLOAD_H__#include <map>#include <string>using std::map;class HTTPUpload {<span style="white-space:pre"></span>public:static bool SendRequest(const string &url,const map<string, string> ¶meters,const string &upload_file,const string &file_part_name,const string &proxy,const string &proxy_user_pwd,const string &ca_certificate_file,string *response_body,long *response_code,string *error_description);static bool MySendRequest( const string &upload_file);private:// Checks that the given list of parameters has only printable// ASCII characters in the parameter name, and does not contain// any quote (") characters.  Returns true if so.static bool CheckParameters(const map<string, string> ¶meters);// No instances of this class should be created.// Disallow all constructors, destructors, and operator=.HTTPUpload();explicit HTTPUpload(const HTTPUpload &);void operator=(const HTTPUpload &);~HTTPUpload();};#endif  // COMMON_LINUX_HTTP_UPLOAD_H__

Httpupload.cpp

#include <assert.h>#include <curl/curl.h>#include <curl/easy.h>#include <stdio.h>#include <vector>#include "stdafx.h"#include "HttpUpload.h"using namespace cocos2d;using namespace std;// Callback to get the response data from server.static size_t WriteCallback(void *ptr, size_t size,                            size_t nmemb, void *userp) {  if (!userp)    return 0;  string *response = reinterpret_cast<string *>(userp);  size_t real_size = size * nmemb;  response->append(reinterpret_cast<char *>(ptr), real_size);  std::cout << response << endl;  return real_size;}static const char kUserAgent[] = "Breakpad/1.0 (Linux)";// staticbool HTTPUpload::SendRequest(const string &url,                             const map<string, string> ¶meters,                             const string &upload_file,//"E:\\install.res.1041.zip"                             const string &file_part_name,//"upload_file_minidump",                             const string &proxy,                             const string &proxy_user_pwd,                             const string &ca_certificate_file,                             string *response_body,                             long *response_code,                             string *error_description) {  if (response_code != NULL)    *response_code = 0;  if (!CheckParameters(parameters))    return false;curl_global_init(CURL_GLOBAL_ALL);  CURL *curl = curl_easy_init();  if (error_description != NULL)    *error_description = "No Error";  if (!curl) {    return false;  }  CURLcode err_code = CURLE_OK;  (curl_easy_setopt)(curl, CURLOPT_URL, url.c_str());  (curl_easy_setopt)(curl, CURLOPT_USERAGENT, kUserAgent);  // Set proxy information if necessary.  if (!proxy.empty())    (curl_easy_setopt)(curl, CURLOPT_PROXY, proxy.c_str());  if (!proxy_user_pwd.empty())    (curl_easy_setopt)(curl, CURLOPT_PROXYUSERPWD, proxy_user_pwd.c_str());  if (!ca_certificate_file.empty())    (curl_easy_setopt)(curl, CURLOPT_CAINFO, ca_certificate_file.c_str());  struct curl_httppost *formpost = NULL;  struct curl_httppost *lastptr = NULL;  // Add form file.  (curl_formadd)(&formpost, &lastptr,       CURLFORM_COPYNAME, "file",               CURLFORM_FILE, upload_file.c_str(),               CURLFORM_END);  (curl_easy_setopt)(curl, CURLOPT_HTTPPOST, formpost);  curl_formadd(&formpost,   &lastptr,   CURLFORM_COPYNAME, "submit",   CURLFORM_COPYCONTENTS, "send",   CURLFORM_END);  // Disable 100-continue header.  struct curl_slist *headerlist = NULL;  char buf[] = "Expect:"; // struct curl_slist* (curl_slist_append)(struct curl_slist *, const char *);  //*(void**) (&curl_slist_append) = dlsym(curl_lib, "curl_slist_append");  headerlist = (curl_slist_append)(headerlist, buf);  (curl_easy_setopt)(curl, CURLOPT_HTTPHEADER, headerlist);  if (response_body != NULL) {    (curl_easy_setopt)(curl, CURLOPT_WRITEFUNCTION, WriteCallback);    (curl_easy_setopt)(curl, CURLOPT_WRITEDATA,                     reinterpret_cast<void *>(response_body));  }  // Fail if 400+ is returned from the web server.  (curl_easy_setopt)(curl, CURLOPT_FAILONERROR, 1);  err_code = (curl_easy_perform)(curl);  if (response_code != NULL) {    (curl_easy_getinfo)(curl, CURLINFO_RESPONSE_CODE, response_code);  }  if (error_description != NULL)    *error_description = (curl_easy_strerror)(err_code);  (curl_easy_cleanup)(curl);  if (formpost != NULL) {    (curl_formfree)(formpost);  }  if (headerlist != NULL) {    (curl_slist_free_all)(headerlist);  } // dlclose(curl_lib);  return err_code == CURLE_OK;}// staticbool HTTPUpload::CheckParameters(const map<string, string> ¶meters) {  for (map<string, string>::const_iterator pos = parameters.begin();       pos != parameters.end(); ++pos) {    const string &str = pos->first;    if (str.size() == 0)      return false;  // disallow empty parameter names    for (unsigned int i = 0; i < str.size(); ++i) {      int c = str[i];      if (c < 32 || c == '"' || c > 127) {        return false;      }    }  }  return true;}//重写把数据读入上传数据流函数   size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) {FILE *fptr = (FILE*)userp;size_t m_size = fread(buffer, size, nmemb, fptr);return m_size;} 

在任意地方调用下方代码,则实现将 E:\\3.0.25.63.zip 文件上传到php服务器的upload目录下

CCLOG("################################################################################################ Begin send dump file");string strPath = "E:\\3.0.25.63.zip";std::map<string, string> parameters;string response, error;const char * url = "http://127.0.0.1/WD/ReceiveFile.php";bool success = HTTPUpload::SendRequest(url,parameters,strPath.c_str(),//"upload_file_minidump","","","","",&response,NULL,&error);




以上代码是个简单的demo,代码相当粗糙,但应该对大家的理解影响不打,代码还有很大的优化空间,大家可以进行优化和扩展空间,期望大家一起完善!

0 0