Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/255.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用swift(php、json、swift)将图像上载到服务器_Php_Ios_Swift_Post_Image Uploading - Fatal编程技术网

使用swift(php、json、swift)将图像上载到服务器

使用swift(php、json、swift)将图像上载到服务器,php,ios,swift,post,image-uploading,Php,Ios,Swift,Post,Image Uploading,我正在做一个项目,我想选择一个图像,然后上传到服务器上。我可以点击上传图像按钮,选择图像,然后在iOS模拟器中更改图像,但上传失败。当我在request.httpBody=createbodywithparams()语句之后包含print(request)时,它表明原始url没有更改。我正在使用XAMPP设置一个虚拟服务器,并使用php与之通信 我的代码: // upload image button clicked @IBAction func edit_click(_ sender: Any

我正在做一个项目,我想选择一个图像,然后上传到服务器上。我可以点击上传图像按钮,选择图像,然后在iOS模拟器中更改图像,但上传失败。当我在
request.httpBody=createbodywithparams()语句之后包含
print(request)
时,它表明原始url没有更改。我正在使用XAMPP设置一个虚拟服务器,并使用php与之通信

我的代码:

// upload image button clicked
@IBAction func edit_click(_ sender: Any) {

    // select image
    let picker = UIImagePickerController()
    picker.delegate = self

    //picker.sourceType = UIImagePickerControllerSourceType.photoLibrary
    picker.allowsEditing = true
    self.present(picker, animated: true, completion: nil)
}

// selected image
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    avaImg.image = info[UIImagePickerControllerEditedImage] as? UIImage
    self.dismiss(animated: true, completion: nil)

    // call function of uploading image file to server
    uploadImage()
}

// create body of HTTP request to upload image file
func createBodyWithParams(parameters: [String : String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {

    let body = NSMutableData();

    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 = "image.jpg"

    let mimetype = "image/jpg"

    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 as Data)
    body.appendString(string: "\r\n")

    body.appendString(string: "--\(boundary)--\r\n")

    return body
}

// upload image to server
func uploadImage() {

    let id = user!["id"] as! String

    let address = URL(string: "http://localhost/project/uploadImage.php")!
    var request = URLRequest(url: address)
    request.httpMethod = "POST"
    let param = ["id" : id]

    let boundary = "Boundary-\(NSUUID().uuidString)"

    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    let imageData = UIImageJPEGRepresentation(avaImg.image!, 0.5)

    if imageData == nil {
        return
    }

    request.httpBody = createBodyWithParams(parameters: param, filePathKey: "file", imageDataKey: imageData! as NSData, boundary: boundary) as Data

    // launch session
    let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in

        // get main queue to communicate back to user
        DispatchQueue.main.async {

            if error == nil {

                do {

                    let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary

                    guard let parseJSON = json else {

                        print("error while parsing")
                        return

                    }

                    print(parseJSON)

                } catch {

                    print("Caught an error: \(error)")

                }

            } else {

                print(error)

            }
        }
    })

    task.resume()

}
扩展如下:

// creating protocol of appending string to var of type data
extension NSMutableData {

    appendString(string : String) {

        let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
        append(data!)

    }
}
我已经参考了以下几页寻求帮助,并尝试修改代码以反映他们方法的差异,但我的头撞到了墙上

编辑1:

忘记了错误消息(dur):
捕获到一个错误:error Domain=NSCocoaErrorDomain code=3840“JSON文本没有以数组或对象开头,允许未设置片段的选项。”UserInfo={NSDebugDescription=JSON文本没有以数组或对象开头,允许未设置片段的选项。}

do
语句中的某个地方出错。我认为
请求发生了一些问题,因为测试
http://localhost/project/uploadImage.php
在我的浏览器中返回数组
{“消息”:“缺少所需信息”}

编辑2:PHP代码

uploadImage.php

<?php

// report all errors except E_NOTICE
error_reporting(E_ALL & ~E_NOTICE);

// Part 1: Upload File
// Step 1: check data passed to this php file
if (empty($_REQUEST["id"])) {

    $returnArray["message"] = "Missing required information";
    print json_encode($returnArray);
    return;
}

// request user id
$id = htmlentities($_REQUEST["id"]);

// step 2: create a folder for user with id as folder name
$folder = "/Applications/XAMPP/xamppfiles/htdocs/project/image/" . $id;

// if folder doesn't exist
if (!file_exists($folder)) {

    mkdir($folder, 0777, true);

}

// step 3: move uploaded file
$folder = $folder . "/" . basename($_FILES["file"]["name"]);

if (move_uploaded_file($_FILES["file"]["tempname"], $folder)) {
    $returnArray["status"] = "200";
    $returnArray["message"] = "The file has been uploaded successfully.";
} else {
    $returnArray["status"] = "300";
    $returnArray["message"] = "Error while uploading.";
}


// Part 2: Updating image path
// build secure connection

$file = parse_ini_file("../../../project.ini");

// store variable information from ini file in php as variables
$host = trim($file["dbhost"]);
$user = trim($file["dbuser"]);
$pass = trim($file["dbpass"]);
$name = trim($file["dbname"]);

// include access.php to call connect function from access.php file
require ("secure/access.php");
$access = new access($host, $user, $pass, $name);
$access->connect();

// STEP 5: save path to uploaded file in database
$path = "http://localhost/project/image/" . $id . "/ava.jpg";
$access->updateImagePath($path, $id);

// STEP 6: get new user information after updating
$user = $access->selectUserViaID($id);

$returnArray["id"] = $user["id"];
$returnArray["username"] = $user["username"];
$returnArray["fullname"] = $user["fullname"];
$returnArray["email"] = $user["email"];
$returnArray["image"] = $user["image"];

// Step 7. Close Connection
$access->disconnect();

// Step 8. feedback array to app
echo json_encode($returnArray);

?>

在@OOper的帮助下,在注释中,我能够跟踪由我的主uploadImage.php文件(参见main post)调用的函数中的语法错误,以及在我应该使用“tmp_name”时使用的
“tempname”

在@OOper的帮助下,在注释中,我能够跟踪由我的主uploadImage.php文件调用的函数中的语法错误(参见主帖子),以及在我应该使用“tmp_name”时使用的
“tempname”

当它打印到控制台窗口时,错误会显示什么?如果您将
打印(字符串)放在(数据:数据!编码:.utf8))
DispatchQueue.main.async
?@OOPer当我添加
打印时(字符串(数据:数据!编码:.utf8))
DispatchQueue.main.async之前
我在主要帖子中包含的错误消息之前得到了以下信息:

注意:未定义索引:第31行
{“状态”:“300”,“消息”:“上传时出错”,“id”:“98”,“用户名”:“用户名”,“全名”:“全名”,“电子邮件”:“******@me.com”,“图像”:“http:\/\/localhost\/project\/image\/98\/ava,jpg”}
@Pierce我在原始帖子中添加了错误。我想这与
createBodyWithParams()有关
函数和最终的
请求
@OOPer我看到URL上出现了一些奇怪的东西。我猜我在添加正文时出错了。有什么见解吗?当它打印到控制台窗口时会显示什么错误?如果您将
打印(字符串(数据:data!,编码:.utf8))会得到什么
DispatchQueue.main.async之前
?@OOPer当我添加
打印时(字符串(数据:数据!编码:.utf8))
DispatchQueue.main.async之前
我在主要帖子中包含的错误消息之前得到了以下信息:

注意:未定义索引:第31行
{“状态”:“300”,“消息”:“上传时出错”,“id”:“98”,“用户名”:“用户名”,“用户名”全名“:”全名“,”电子邮件“:”*****@me.com“,”图像“:”http:\/\/localhost\/project\/image\/98\/ava,jpg”}
@Pierce我在原始帖子中添加了错误。我想这与
createBodyWithParams()有关
函数和最终的
请求
@OOPer我看到URL出现了一些奇怪的东西。我猜我在添加正文时出了问题。有什么见解吗?