无法使用AFNetworking 2和Slim PHP框架上传图像


Failing to upload image with AFNetworking 2 and Slim PHP framework

这是我的纤薄框架php代码

    $app->post('/uploadPicture', function () {
    if (!empty($_FILES)) {
        global $config;
        $picturePath = $config->get('db', 'picture');
        $allowedExts = array("jpg", "jpeg", "png");
        $extension = end(explode(".", $_FILES["file"]["name"]));
        if ($_FILES["file"]["type"] == "image/jpg" || $_FILES["file"]["type"] == "image/jpeg" || $_FILES["file"]["type"] == "image/png" && $_FILES["file"]["size"] < 2500000 && in_array($extension, $allowedExts)) {
            if ($_FILES["file"]["error"] > 0) {
                echo "Error: " . $_FILES["file"]["error"] . "<br />";
            } else {
                if (move_uploaded_file($_FILES['file']['tmp_name'], $picturePath . $_FILES["file"]["name"])) {
                    echo "success";
                }
            }
        } else {
            echo "Invalid file type";
        }
    } else {
        echo "no file to upload";
    }
});

这是我在iPhone端使用的。

    -(void)uploadImage:(UIImage *)image withPersistentID:(NSString *)persistentID {
    [[MSMAMobileAPIClient sharedClient] POST:@"uploadPicture" parameters:nil constructingBodyWithBlock:^(id <AFMultipartFormData>formData) {
        NSData *imageData = UIImageJPEGRepresentation(image, 90);
        NSString *fileName = [NSString stringWithFormat:@"%@.jpg", persistentID];
        [formData appendPartWithFileData:imageData name:@"file" fileName:fileName mimeType:@"image/jpg"];
    } success:^(NSURLSessionDataTask * task, id responderData) {
        self.itemImageBlock(YES);
    } failure:^(NSURLSessionDataTask * task, NSError * error) {
        NSLog(@"%@",[error.userInfo objectForKey:@"JSONResponseSerializerWithDataKey"]);
        self.itemImageBlock(NO);
    }];
}

在iPhone方面,它似乎只是挂起,就像服务器繁忙一样,然后最终因超时而失败。

我一直在使用CocoaRestClient,并且能够上传图像。

尝试从 iPhone 上传时,我还看到文件被添加到 php 的临时目录中。

我做错了什么吗?

编辑:我刚刚在uploadPicture功能中添加了一个错误日志行,它甚至看起来都不像是iPhone首先调用的! :(

编辑2:这是返回错误消息的NSLog

Error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x17d6e1c0 {NSErrorFailingURLStringKey=https://192.168.1.15/mamobile/index.php/uploadPicture, NSErrorFailingURLKey=https://192.168.1.15/mamobile/index.php/uploadPicture, NSLocalizedDescription=The request timed out., NSUnderlyingError=0x17db1460 "The request timed out."}

编辑3:我取消了纤薄的php框架,只是创建了一个简单的php脚本,只上传图片。

<?php 

if (!empty($_FILES)) {
    //load configuration file
    require_once 'Lite/Lite.php';
    $config = new Config_Lite('config.ini');
    $picturePath = $config->get('db', 'picture');
        $allowedExts = array("jpg", "jpeg", "png");
        $extension = end(explode(".", $_FILES["file"]["name"]));
        if ($_FILES["file"]["type"] == "image/jpg" || $_FILES["file"]["type"] == "image/jpeg" || $_FILES["file"]["type"] == "image/png" && $_FILES["file"]["size"] < 2500000 && in_array($extension, $allowedExts)) {
            if ($_FILES["file"]["error"] > 0) {
                echo "Error: " . $_FILES["file"]["error"] . "<br />";
            } else {
                if (move_uploaded_file($_FILES['file']['tmp_name'], $picturePath . $_FILES["file"]["name"])) {
                    echo "success";
                }
            }
        } else {
            echo "Invalid file type";
        }
    } else {
        echo "no file to upload";
    }
?>

然后我更改了我的代码以这种方式工作。

NSString *urlString = [NSString stringWithFormat:@"https://%@/mamobile/uploadPicture.php", [[NSUserDefaults standardUserDefaults] stringForKey:@"serviceIPAddress"]];
    AFHTTPSessionManager *imageSession = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:urlString]];
    imageSession.responseSerializer = [MSJSONResponseSerializerWithData serializer];
    [imageSession.requestSerializer setAuthorizationHeaderFieldWithUsername:@"fake username" password:@"fake password"];
    [imageSession.securityPolicy setAllowInvalidCertificates:YES];
    [imageSession POST:@"" parameters:nil constructingBodyWithBlock:^(id <AFMultipartFormData>formData) {
        NSData *imageData = UIImageJPEGRepresentation(image, 90);
        NSString *fileName = [NSString stringWithFormat:@"%@.jpg", persistentID];
        NSLog(@"uploading image '%@' with size = %@",fileName,[NSByteCountFormatter stringFromByteCount:imageData.length countStyle:NSByteCountFormatterCountStyleFile]);
        [formData appendPartWithFileData:imageData name:@"file" fileName:fileName mimeType:@"image/jpg"];
    } success:^(NSURLSessionDataTask * task, id responderData) {
        NSLog(@"Success: %@", responderData);
        self.itemImageBlock(YES);
    } failure:^(NSURLSessionDataTask * task, NSError * error) {
        NSLog(@"Error: %@",error);
        self.itemImageBlock(NO);
    }];

但我仍然收到相同的超时消息。所以它与苗条的php框架无关。

您得到的错误是: The request timed out.

这意味着,您从移动设备上传到 PHP 脚本的图像花费的时间比 PHP 上脚本执行时间配置的最大设置要长。

要解决此问题,您可以在 PHP 脚本的开头添加以下内容:

<?php 
// Allow script to run longer
set_time_limit(600); // in seconds, set it to 0 to run forever until completion
// Proceed with upload
if (!empty($_FILES)) {
    ...
}

https://github.com/AFNetworking/AFNetworking/issues/1510#issuecomment-29687300

有一个问题我也类似。解决方案是从以下代码添加。

[formData appendPartWithFormData:[[NSNumber numberWithInt:imageData.length].stringValue dataUsingEncoding:NSUTF8StringEncoding] name:@"filelength"];