将原始数据从PHP Server API发送到Swift客户端API

时间:2018-11-23 10:30:54

标签: php swift post

我的目标是使用HTTP POST从PHP脚本和客户端Swift代码存储和检索原始数据。我正在使用存储MEDIUMBLOB数据的MySQL数据库。

我成功地从Swift中发送了数据并将其存储到数据库中。 这是我用于存储数据的工作代码(为简化起见,我删除了WHERE子句),我可以使用PHPMyAdmin查看存储的原始数据(例如[BLOB-345.6 KiB],其大小与客户端代码数据大小相同): / p>

<?php
//...
$file = $_FILES['file']['tmp_name'];
$file_data = file_get_contents($file);
$file_info = finfo_open(FILEINFO_MIME_TYPE);
$file_type = finfo_file($file_info, $file);
$file_size = filesize($file);

$worldMap1 = $file_data;
$query = $query = "INSERT INTO " . $this->table_name . " SET worldMap1=:worldMap1";
//...
?>

客户端Swift代码(请求结构):

let boundary = generateBoundaryString()
    var request = URLRequest(url: requestedUrl)
    request.httpMethod = POSTMETHOD
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
    request.httpBody = createBodyWithParametersForData(
        parameters: dataBody,
        filePathKey: "file",
        imageDataKey: data,
        boundary: boundary
    )

private func createBodyWithParametersForData(parameters: [String: Any]?, filePathKey: String?, imageDataKey: Data, boundary: String) -> Data {
    var body = Data();

    if parameters != nil {
        for (key, value) in parameters! {
            body.appendString(string: "--\(boundary)\r\n")
            body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
            body.appendString(string: "\(value)\r\n")
        }
    }

    let filename = "file"
    let mimetype = "application/octet-stream"

    body.appendString(string: "--\(boundary)\r\n")
    body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
    body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
    body.append(imageDataKey)
    body.appendString(string: "\r\n")
    body.appendString(string: "--\(boundary)--\r\n")

    return body
}

现在,我只想将数据发送回客户端Swift代码(非工作代码):

<?php
// required headers
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

// Fetch the record:
$query = "SELECT worldMap1 FROM " . $this->table_name . "";

// prepare query
$stmt = $db->prepare($query);

//...

// execute query
$stmt->execute();

if ($stmt->rowCount() == 1) {
    // Fetch the record into a variable:
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    $file_size = filesize($row["worldMap1"]);

    // Send the content information:
    header("Content-Type: application/octet-stream\n");
    header("Content-Disposition: attachment; filename=\"file\"\n");
    header("Content-Length: {$file_size}\n");

    // Send the file:
    echo $row["worldMap1"];
}
// Omit the closing PHP tag to avoid tainting the downloaded file

在客户端,我要么收到0字节数据,要么收到超时错误代码。 我也尝试硬编码Content-Length值,例如1000。 我没有看到任何有关如何从PHP代码发送原始数据的清晰文档。 这是我发现并用于存储数据的唯一有用信息:http://www.peachpit.com/articles/article.aspx?p=1967015&seqNum=4

1 个答案:

答案 0 :(得分:1)

通常,文件存储在目录中,而不是数据库中。

看来问题很可能与您的 {'search_default_draft_state': 1} 标头有关。我认为仅仅告诉浏览器还不够,我期待一个八位位组流。

为了让您的浏览器正确地将其识别为附件,我将更改标题以指示您正在处理的文件的实际类型,以便它知道如何解释该文件。

像这样:

Content-Type: application/octet-stream\n

以下是接受的MIME-TYPES

的列表

您还将覆盖您的内容类型标头,从“必需” header('Content-Type: ' . $type); application/json。我可能不会发送octet-stream标头。即使我相信它将被后者覆盖。

在脚本输出任何内容之前,请确保已发送标题。即使是未知的空格也会引起您的问题。

我也看不到标题中需要aplication/json

我还考虑使用单引号而不是双引号,因为您可能会犯错误,而将文件名用双引号转义。

希望有帮助。

再次,如果是我,我不会这样做。我会将所有文件上传到目录而不是数据库。