【问题标题】:How to upload a UIImage to MySQL via PHP from Swift?如何从 Swift 通过 PHP 将 UIImage 上传到 MySQL?
【发布时间】:2015-07-21 10:30:35
【问题描述】:

我有一个应用程序,它通过我编写的一些 PHP Web 服务将一些数据上传到 MySQL 数据库。我已经成功上传了文本数据,但我正在努力尝试上传图片。基本上,用户使用他们的 iPhone 相机拍照,我将其转换为 UIImage,现在想要上传它。

我查看了以下资源以寻求帮助,但它们似乎对我不起作用: How to Upload text, pdf, doc, zip file via PHP file upload to MySQL
https://www.youtube.com/watch?v=HqxeyS961Uk(这里的代码不会为我编译,我一个字母一个字母地复制了它)
How to post a picture from iPhone app (in Swift) to MySQL database?
Saving image on db mysql through swift
Swift - uploading base64 encoded image to php and displaying the image
@ 987654326@

如果可能,我想在同一个查询中一起上​​传图像和文本,因为它们相互关联,并且我的 MySQL 表为新行分配了一个自动编号。

编辑 感谢下面的答案。我有点不确定如何实施你们建议的更改。我目前上传文本数据的 Swift 代码是:

let url:NSURL = NSURL(string: "http://www.website.com.au/savenewexpense.php")!
        let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        var dataDictionary:[String:AnyObject] = ["Date" : strDate, "Staff" : strStaff, "Amount" : dblAmount, "Category" : strCategory]
        var data:NSData = NSJSONSerialization.dataWithJSONObject(dataDictionary, options: nil, error: nil)!
        request.HTTPBody = data

        request.addValue("application/json", forHTTPHeaderField: "Content-Type")

        let task:NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in

            let response:[String:String] = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! [String:String]
            if let result = response["result"] {
                if result == "success" {
                    NSLog("Text Data saved successfully")
                    if self.SendImageToServer() == true {
                        NSLog("Image Data saved successfully")
                        self.SaveSuccessful()
                    } else {
                        NSLog("Image Data failed to save")
                        self.DataFail()
                    }
                } else {
                    NSLog("Error saving data")
                    self.DataFail()
                }
            } else {
                NSLog("No response")
                self.NoResponse()
            }

        })

        task.resume()
    }

而我的 PHP 代码是:

    // Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$json = file_get_contents('php://input');
$data = json_decode($json, true);

$stmt = $conn->prepare("INSERT INTO tblExpenses (Date, Staff, Amount, Category) VALUES (?, ?, ?, ?)");
$txtDate = $data['Date'];
$txtStaff = $data['Staff'];
$txtAmount = $data['Amount'];
$txtCategory = $data['Category'];
$stmt->bind_param("ssds", $txtDate, $txtStaff, $txtAmount, $txtCategory);
$stmt->execute();
echo '{"result" : "success"}';


$stmt->close();
$conn->close();

我应该如何将图像实现到这个中?

谢谢

【问题讨论】:

  • 你不能像这样把二进制数据放在 JSON 中。两种基本方法:multipart/form-data 请求(Swift 代码为stackoverflow.com/a/26163136/1271826,然后 PHP 代码通过 $_FILES 或 base64-encoding in(将二进制数据转换为文本形式)访问上传,然后使用 JSON 或 application/x-www-form-urlencoded发送它(但是你必须接收它并将 base64 转换回二进制形式;加上传输比它需要的大 33%)。
  • @Rob 你是什么意思传输比它需要的大 33%?是什么让它变大了?你会如何减少它?
  • @the_pantless_coder - 基于文本的格式(例如 JSON 或 XML)要求二进制数据经过 base64 编码过程,该过程采用 8 位二进制数据并将其表示为 64 个不同文本字符的序列。该编码过程为每三个字节的输入二进制数据输出四个文本字符。 (您使用 3 x 8 位二进制字节并将其表示为 4 x 6 位文本字符。)为了避免这种开销,请使用不需要文本格式的传输机制,即不需要 base64 的传输机制编码(如x-www-form-urlencoded)。

标签: php ios mysql image swift


【解决方案1】:

你要做的就是设置图像的边界,例如使用代码将图像的 NSDATA 转换为边界值

if let dta = data as? NSData {
                bodyData.appendData(String(format:"\r\n--\(boundary)\r\n").dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!);
                bodyData.appendData(String(format:"Content-Disposition: form-data; name=\"photo\(i)\"; filename=\"image.png\"\r\n").dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!);
                bodyData.appendData(String(format:"Content-Type: image/png\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!);

                bodyData.appendData(dta);
            }

在这里您要做的是设置图像名称,然后设置图像数据,首先使用 allowLossyConversion 转换数据,然后将 POST 数据与其他数据一起发送到服务

request.HTTPBody = bodyData

只用它来发送图像

【讨论】:

  • 是的,这就是您为多部分请求创建一个部分的方式。但是,这显然假定(a)请求标头正确地将其指定为多部分请求以及边界是什么; (b) 确保在请求正文的末尾添加边界终止符。否则,这将不是一个格式良好的请求。
  • @Fatti Khan 好的,我编辑了问题以包含我用于上传文本数据的代码。我应该如何将图像实现到其中?我已经将数据设置为request.HTTPBody
猜你喜欢
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-13
  • 2011-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多