1. 将图片转换为Base64编码,POST上传。PHP将Base64解码为二进制,再写出文件。缺点:不能上传较大的图片
- // iOS(Swift)
- function upload(image: UIImage, url: String) {
- let imageData = UIImageJPEGRepresentation(image, 0.3) // 将图片转换成jpeg格式的NSData,压缩到0.3
- let imageStr = imageData?.base64EncodedStringWithOptions(.Encoding64CharacterLineLength) // 将图片转换为base64字符串
- let params: NSDictionary = ["file": imageStr!]
- let manager = AFHTTPRequestOperationManager()
- // 采用POST的方式上传,因为POST对长度没有限制
- manager.POST(url, parameters: params, success: { (_: AFHTTPRequestOperation!, response: AnyObject!) in
- // 成功
- }) { (_: AFHTTPRequestOperation!, _: NSError!) in
- // 失败
- }
- }
保存图片
- header('Content-type: text/json; charset=UTF-8');
- $base64 = $_POST["file"]; // 得到参数
- $img = base64_decode($base64); // 将格式为base64的字符串解码
- $path = "md5(uniqid(rand()))".".jpg"; // 产生随机唯一的名字作为文件名
- file_put_contents($path, $img); // 将图片保存到相应位置
2.AFNetworking上传,PHP端通过正常接收网页上传方法来接收图片
- static func uploadPortrait(image: UIImage, url: String) {
- let manager = AFHTTPRequestOperationManager()
- // fromData: AFN封装好的http header类,可以添加请求体
- manager.POST(url, parameters: [:], constructingBodyWithBlock: { (fromData: AFMultipartFormData!) in
- let pngData = UIImagePNGRepresentation(image)
- // name必须和后台PHP接收的参数名相同($_FILES["file"])
- // fileName为图片名
- fromData.appendPartWithFileData(pngData, name: "file", fileName: "image.png", mimeType: "image/png")
- // let jpegData = UIImageJPEGRepresentation(image, 0.3)
- // fromData.appendPartWithFileData(jpegData, name: "file", fileName: "image.jpg", mimeType: "image/jpeg")
- }, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) in
- // 成功
- }) { (operation: AFHTTPRequestOperation!, error: NSError!) in
- // 失败
- }
- }
- header('Content-type: text/json; charset=UTF-8' );
- /**
- * $_FILES 文件上传变量,是一个二维数组,第一维保存上传的文件的数组,第二维保存文件的属性,包括类型、大小等
- * 要实现上传文件,必须修改权限为加入可写 chmod -R 777 目标目录
- */
- // 文件类型限制
- // "file"名字必须和iOS客户端上传的name一致
- if (($_FILES["file"]["type"] == "image/gif")
- || ($_FILES["file"]["type"] == "image/jpeg")
- || ($_FILES["file"]["type"] == "image/png")
- || ($_FILES["file"]["type"] == "image/pjpeg"))
- // && ($_FILES["file"]["size"] < 20000)) // 小于20k
- {
- if ($_FILES["file"]["error"] > 0) {
- echo $_FILES["file"]["error"]; // 错误代码
- } else {
- $fillname = $_FILES['file']['name']; // 得到文件全名
- $dotArray = explode('.', $fillname); // 以.分割字符串,得到数组
- $type = end($dotArray); // 得到最后一个元素:文件后缀
- $path = "../portrait/".md5(uniqid(rand())).'.'.$type; // 产生随机唯一的名字
- move_uploaded_file( // 从临时目录复制到目标目录
- $_FILES["file"]["tmp_name"], // 存储在服务器的文件的临时副本的名称
- $path);
- echo "成功";
- }
- } else {
- echo "文件类型不正确";
- }
3.将图片封装在Http的请求报文中的请求体(body)中上传。也是AFN上传的原理
- // 使用OC封装
- #import
@interface RequestPostUploadHelper : NSObject + (NSMutableURLRequest *)uploadImage:(NSString*)url uploadImage:(UIImage *)uploadImage params:(NSMutableDictionary *)params; @end #import "RequestPostUploadHelper.h" @implementation RequestPostUploadHelper + (NSMutableURLRequest *)uploadImage:(NSString*)url uploadImage:(UIImage *)uploadImage params:(NSMutableDictionary *)params { [params setObject:uploadImage forKey:@"file"]; //分界线的标识符 NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x"; //根据url初始化request NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10]; //分界线 --AaB03x NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY]; //结束符 AaB03x-- NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary]; //要上传的图片 UIImage *image=[params objectForKey:@"file"]; //得到图片的data NSData* data = UIImagePNGRepresentation(image); //http body的字符串 NSMutableString *body=[[NSMutableString alloc]init]; //参数的集合的所有key的集合 NSArray *keys= [params allKeys]; //遍历keys for(int i = 0; i < [keys count]; i++) { //得到当前key NSString *key = [keys objectAtIndex:i]; //如果key不是file,说明value是字符类型,比如name:Boris if(![key isEqualToString:@"file"]) { //添加分界线,换行 [body appendFormat:@"%@\r\n",MPboundary]; //添加字段名称,换2行 [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key]; //添加字段的值 [body appendFormat:@"%@\r\n",[params objectForKey:key]]; } } ////添加分界线,换行 [body appendFormat:@"%@\r\n",MPboundary]; //声明file字段,文件名为image.png [body appendFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"image.png\"\r\n"]; //声明上传文件的格式 [body appendFormat:@"Content-Type: image/png\r\n\r\n"]; //声明结束符:--AaB03x-- NSString *end=[[NSString alloc] initWithFormat:@"\r\n%@",endMPboundary]; //声明myRequestData,用来放入http body NSMutableData *myRequestData = [NSMutableData data]; //将body字符串转化为UTF8格式的二进制 [myRequestData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]]; //将image的data加入 [myRequestData appendData:data]; //加入结束符--AaB03x-- [myRequestData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]]; //设置HTTPHeader中Content-Type的值 NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY]; //设置HTTPHeader [request setValue:content forHTTPHeaderField:@"Content-Type"]; //设置Content-Length [request setValue:[NSString stringWithFormat:@"%d", [myRequestData length]] forHTTPHeaderField:@"Content-Length"]; //设置http body [request setHTTPBody:myRequestData]; //http method [request setHTTPMethod:@"POST"]; return request; } @end
- // 使用
- // Swift
- static func uploadPortrait(image: UIImage, url:String) {
- // 使用
- let request = RequestPostUploadHelper.uploadImage(url, uploadImage: image, params: [:])
- // 异步网络请求
- NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) { (response: NSURLResponse?, data: NSData?, error: NSError?) in
- if error != nil {
- // 失败
- } else {
- // 成功
- }
- }
- }
- // PHP代码和上一步相同
4.iOS图片转换为NSData,通过POST上传。PHP接收POST参数,将NSData的16进制编码转换为PHP支持的二进制,再写出文件保存
暂时没有找到办法,PHP接收到16进制编码后, 使用算法 转换为二进制后无法输出图片
5.二进制POST上传。PHP直接将数据保存为图片
暂时没有找到办法,iOS端使用NSData的getBytes无法转换为二进制
转载请注明:苏demo的别样人生 » iOS上传图像到服务器PHP接收的几种方法