2015-10-04 2 views
0

Я пытаюсь загрузить изображение с помощью своего приложения iOS (Swift 2.0). Сервер получает запрос и отправляет статус 200, но когда дело доходит до загрузки файла, данные изображения не загружаются. Команда print_r($_FILES); дает мне ответ:Загрузить многостраничное изображение на PHP-сервер из приложения iOS

Array 
(
) 
wrong format for image 

Это код:

func send() 
{ 

    let request = NSMutableURLRequest(URL: NSURL(string: "***URL to upload.php***")!) 

    request.HTTPMethod = "POST" 
    let postString = "username=\(globalUsr)&photo-name=\(globalImage.description)&photo-description=\(message.text)" 

    let myData : NSData! = postString.dataUsingEncoding(NSUTF8StringEncoding) 

    let imageData :NSData = UIImageJPEGRepresentation(globalImage, 1.0)!; 

    let boundary = "-----SwiftBoundary-----" 
    let contentType = "multipart/form-data; boundary=\(boundary)" 
    let body = NSMutableData(); 

    let tempData = NSMutableData() 
    let fileName = "\(globalImage.description).jpg" 
    let parameterName = "contest-photo" 

    tempData.appendData(myData) 
    tempData.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    let fileNameContentDisposition = "name=\(parameterName)" 
    let contentDisposition = "Content-Disposition: form-data; name=\"\(fileName)\"; \(fileNameContentDisposition)\r\n" 
    tempData.appendData(contentDisposition.dataUsingEncoding(NSUTF8StringEncoding)!) 
    tempData.appendData("Content-Type: \(contentType)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    tempData.appendData(imageData) 
    tempData.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 


    body.appendData(tempData) 

    body.appendData("\r\n--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 

    request.setValue("\(body.length)", forHTTPHeaderField: "Content-Length") 
    request.HTTPBody = body 


    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { 
     data, response, error in 

     if error != nil { 
      print("error=\(error)") 
      return 
     } 

     let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) 
     print("responseString = \(responseString!)") 
    } 
    task.resume() 


} 

код РНР:

<?php 

// Load Wordpress 
define('WP_USE_THEMES', false); 
require_once("../../../../../wp-load.php"); 

    $username = $_POST["username"]; 

    $m = contest_upload_photo('contest-upload-photo','contest_upload_photo',username_exists($username)); 




function contest_upload_photo($atts, $content = null,$user_ID=null) { 

//Important variables 
if ($user_ID == null){ 
    die(json_encode("There is no user.")); 
} 

$html = '';//Inciate output string 
$koncovky = array('jpg', 'jpeg', 'png', 'gif'); 

$number_images = get_user_meta($user_ID, 'contest_user_images', true); 
if(empty($number_images)){$number_images=0;} 


$error = array(); 
// Do some minor form validation to make sure there is content 

$name = trim($_POST['photo-name']); 
    /*if (empty($_POST['photo-title'])){ 
    $error['title'] = __('Please enter the photo title','photo-contest'); 
} else { 
    $title = trim($_POST['photo-title']); 
}*/ 


//Check photo 
if ($_FILES['contest-photo']['error'] == UPLOAD_ERR_NO_FILE){ 
    $error['photo'] = __('Please select the image','photo-contest'); 
    die("no photo selected"); 
} else { 

    //Control upload and extension 
    if ($_FILES['contest-photo']['error']) { 
    $error['upload_error'] = __('Error image upload.','photo-contest'); 
    die("Image upload error"); 
    } 
    elseif (!in_array(strtolower(pathinfo($_FILES['contest-photo']['name'], PATHINFO_EXTENSION)), $koncovky)) { 
    $error['extension_error'] = __('Image must be jpg, png or gif.','photo-contest'); 
    print($koncovky); 
    print_r($_FILES); 
    die("wrong format for image"); 
    } 
    elseif (!($imagesize = getimagesize($_FILES['contest-photo']['tmp_name'])) || $imagesize[2] > 3) { 
    $error['type_error'] = __('Image type must be jpg, png or gif.','photo-contest'); 
    die("image too big"); 
    } 
    else { 

    @$img=getimagesize($_FILES['contest-photo']['tmp_name']); 

    $minimum = array('width' => '400', 'height' => '400'); 
    $width= $img[0]; 
    $height =$img[1]; 
     if ($width < $minimum['width']){ 
     $error['type_error'] = __('Minimum image width is 400px.','photo-contest'); 
     die("width is too small"); 
     } 
     elseif ($height < $minimum['height']){ 
     $error['type_error'] = __('Minimum image height is 400px.','photo-contest'); 
     die("height is too small"); 
     } 
     $photo_limit = get_option('pcplugin-photo-limit', true); 
     $size_maxi = $photo_limit; 
     $size = filesize($_FILES['contest-photo']['tmp_name']); 
     if($size>$size_maxi){ 
     $error['size_error'] = __('File size is above allowed limitations!','photo-contest'); 
     die("file is too big"); 
} 
    } 


} 


if(empty($error)){ 
//If no exist error - create attachment post 
    if(empty($_POST['photo-description'])){ 
    $description = sanitize_text_field($_POST['photo-description']); 
    }else{ 
    $description = ''; 
    } 

@$wp_filetype = wp_check_filetype(basename($_FILES['contest-photo']['name']), null); 
@$wp_upload_dir = wp_upload_dir(); 
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename($_FILES['contest-photo']['name']), 
'post_mime_type' => $wp_filetype['type'], 
'post_title' => $name, 
'post_content' => $description, 
'post_status' => 'inherit' 
); 

require_once(ABSPATH . 'wp-admin/includes/image.php'); 
require_once(ABSPATH . "wp-admin" . '/includes/file.php'); 
require_once(ABSPATH . "wp-admin" . '/includes/media.php'); 
$attach_id = media_handle_upload('contest-photo', 0,$attachment); 

$attach_data = wp_generate_attachment_metadata($attach_id, $wp_upload_dir['url'] . '/' . basename($_FILES['contest-photo']['name'])); 

wp_update_attachment_metadata($attach_id, $attach_data); 

update_post_meta($attach_id,'contest-active',1); 
update_post_meta($attach_id,'contest-photo-points',0); 
update_post_meta($attach_id,'contest-photo-author',$user_ID); 
    update_post_meta($attach_id,'post_author',$user_ID); 

$number_images = $number_images+1; 
update_user_meta($user_ID, 'contest_user_images', $number_images); 


    $my_post = array(
    'ID'   => $attach_id, 
    'post_author' => $user_ID, 
    ); 

    wp_update_post($my_post); 


    $image = get_post($attach_id); 

    if ($attach_id==""){ 
     die("306"); 
    }else{ 
     echo($attach_id); 
    } 
    if (! $image || 'attachment' != $image->post_type || 'image/' != substr($image->post_mime_type, 0, 6)) 
     die(json_encode(array('error' => sprintf(__('Failed resize: %s is an invalid image ID.', 'regenerate-thumbnails'), esc_html($attach_id))))); 



    $fullsizepath = get_attached_file($image->ID); 

    if (false === $fullsizepath || ! file_exists($fullsizepath)) 

    // @set_time_limit(900); // 5 minutes per image should be PLENTY 

    $metadata = wp_generate_attachment_metadata($image->ID, $fullsizepath); 

    if (is_wp_error($metadata)) 
    if (empty($metadata)) 
    wp_update_attachment_metadata($image->ID, $metadata); 
return $attach_id; 


} 


} 
    ?> 

UPDATE:

Если я попробовать без:

request.setValue(contentType, forHTTPHeaderField: "Content-Type") 

я получаю:

data =<22546865 72652069 73206e6f 20757365 722e22> 
response = <NSHTTPURLResponse: 0x7fcd7e184980> { URL: http://www.clip2gether.com/mobile/app/v1/iOS/upload/upload.php } { status code: 200, headers { 
"Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"; 
Connection = close; 
"Content-Type" = "text/html; charset=UTF-8"; 
Date = "Sun, 04 Oct 2015 20:39:26 GMT"; 
Expires = "Thu, 19 Nov 1981 08:52:00 GMT"; 
Pragma = "no-cache"; 
Server = "Apache/2.4.10"; 
"Set-Cookie" = "qtrans_cookie_test=1; path=/; domain=www.clip2gether.com"; 
"Transfer-Encoding" = Identity; 
"X-Powered-By" = "PHP/5.6.12"; 
} } 

И если я пытаюсь его с линии:

request.setValue(contentType, forHTTPHeaderField: "Content-Type") 

data =<41727261 79417272 61790a28 0a290a77 726f6e67 20666f72 6d617420 666f7220 696d6167 65> 
response = <NSHTTPURLResponse: 0x7fdd22f3e660> { URL: http://www.clip2gether.com/mobile/app/v1/iOS/upload/upload.php } { status code: 200, headers { 
"Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"; 
Connection = close; 
"Content-Type" = "text/html; charset=UTF-8"; 
Date = "Sun, 04 Oct 2015 20:46:19 GMT"; 
Expires = "Thu, 19 Nov 1981 08:52:00 GMT"; 
Pragma = "no-cache"; 
Server = "Apache/2.4.10"; 
"Set-Cookie" = "qtrans_cookie_test=1; path=/; domain=www.clip2gether.com"; 
"Transfer-Encoding" = Identity; 
"X-Powered-By" = "PHP/5.6.12"; 
} } 

Поэтому в основном я получаю тот же ответ с установкой значения CONTENTTYPE как HEX- код:

There is no user 

и без установки его

ArrayArray 
(
) 
wrong format for image 
+0

начать отлаживать задачу, сначала добавьте тип контента на наш запрос HTTP, как это: 'request.setValue (CONTENTTYPE, forHTTPHeaderField: "Content-Type")' –

+0

@WilliamKinaan Если я добавляю контент- type Я получаю ответ «Нет пользователя», что означает user_id = null, а имя пользователя не отправляется на PHP –

+0

. Выполняйте этот запрос 'let session = NSURLSession.sharedSession() let task = session.dataTaskWithRequest (запрос , завершениеHandler: {(данные, ответ, ошибка) в if let error = error { print (ошибка) } если позволяют данные = данные { print ("data = \ (Данные) ") } если пусть ответ = {ответ печати (" ответ = \ (ответ) ") } }) task.resume()' и скажите мне, что будет написано –

ответ

2

Ваши данные body неверны в формате multipart/form-data enctype.Предполагая, что вы хотите POST следующие поля:

  • username текстовое поле
  • photo-name текстовое поле
  • photo-description текстовое поле
  • contest-photo поле файл (будет содержать двоичные данные изображения в)

Ваше тело должно выглядеть так:

--SwiftBoundary 
Content-Disposition: form-data; name="username" 

my username value 
--SwiftBoundary 
Content-Disposition: form-data; name="photo-name" 

my photo-name value 
--SwiftBoundary 
Content-Disposition: form-data; name="photo-description" 

my photo-description value 
--SwiftBoundary 
Content-Disposition: form-data; name="contest-photo"; filename="myfile.jpg" 
Content-Type: image/jpeg 

...my image binary data... 
--SwiftBoundary-- 

Вы также должны установить следующие заголовки по запросу:

  • Content-Length к длине тела
  • и Content-Type: multipart/form-data; boundary=SwiftBoundary, здесь важно, чтобы boundary строка соответствует той, которая используется в теле

Если вам удастся обновить ваш запрос, чтобы посмотреть, как указано выше, вы найдете данные вашего изображения ниже $_FILES['contest-photo']

Вашей send функция должна выглядеть следующим образом:

func send() 
{ 
    let request = NSMutableURLRequest(URL: NSURL(string: "***URL to upload.php***")!) 

    request.HTTPMethod = "POST" 

    let imageData :NSData = UIImageJPEGRepresentation(globalImage, 1.0)!; 

    let boundary = "SwiftBoundary" 
    let contentType = "multipart/form-data; boundary=\(boundary)" 
    let fileName = "\(globalImage.description).jpg" 
    let parameterName = "contest-photo" 

    let body = NSMutableData() 

    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("Content-Disposition: form-data; name=\"username\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("\(globalUsr)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 

    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("Content-Disposition: form-data; name=\"photo-name\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("\(globalImage.description)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 

    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("Content-Disposition: form-data; name=\"photo-description\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("\(message.text)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 

    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("Content-Disposition: form-data; name=\"\(parameterName)\"; filename=\"\(fileName)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
    body.appendData(imageData) 
    body.appendData("\r\n--\(boundary)--".dataUsingEncoding(NSUTF8StringEncoding)!) 

    request.setValue(contentType, forHTTPHeaderField: "Content-Type") 
    request.setValue("\(body.length)", forHTTPHeaderField: "Content-Length") 
    request.HTTPBody = body 


    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { 
     data, response, error in 

     if error != nil { 
      print("error=\(error)") 
      return 
     } 

     let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) 
     print("responseString = \(responseString!)") 
    } 
    task.resume() 
} 
+0

Спасибо за ваш ответ. Если я поместил границу перед именем пользователя, сценарий не получит имя пользователя и остановится на 'if user_ID == nil'. Кроме того, если я делаю 'request.addValue (" multipart/form-data; border = \ (border) ", forHTTPHeaderField:" Content-Type ")' запрос get застрял в сообщении об ошибке «Нет пользователя». –

+0

@AlRas Я добавил фрагмент кода для того, как должна выглядеть ваша функция 'send'. – godvsdeity

+0

Спасибо за запись фрагмента кода. Мне пришлось кодировать строки, потому что я получил сообщение об ошибке «Невозможно преобразовать значение типа String в ожидаемый тип аргумента« NSData », поэтому я добавил' .dataUsingEncoding (NSASCIIStringEncoding)! 'Для каждой строки, но я все равно получаю ответ' Нет пользователя'. Таким образом, запрос не проходит через имя пользователя. В моем коде до того, как он прошел мимо имени пользователя и 'user_ID', которые были правильными, когда я их распечатал, но он сказал мне, что изображение имеет неправильный формат. У вас есть другие идеи, почему это не работает? –

0

Я искал в течение нескольких часов и, наконец, кусочками этого рабочего кодом вместе, используя в основном данные с этой страницы.

Вот как вы можете загрузить изображение вместе с текстовым параметром в скрипт PHP и сохранить изображение на сервере.

// PHP SCRIPT (the content of upload.php) 
<?php 
$image = $_FILES['image-upload']['tmp_name']; 
$username = $_POST['username']; 
$filename = "upload_" . date("ymd_at_H_i_s", time()) . ".jpg"; 
if (move_uploaded_file($image, $filename)) { 
    echo "Image upload for user ".$username." Success"; // this will show up in XCode output 
} else { 
    echo "Image upload for user ".$username." Failed"; // this will show up in XCode output 
} 
?> 




// SWIFT 2.3 IMAGE UPLOAD FUNCTION 
let uploadPHPURL = "http://somehost.com/uploads/upload.php" 
func uploadImage(image:UIImage?, userName:String) 
{ 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 

     let request = NSMutableURLRequest(URL: NSURL(string: self.uploadPHPURL)!) 
     request.HTTPMethod = "POST" 

     //let image = self.imageView.image 
     let imageData :NSData = UIImageJPEGRepresentation(image!, 0.3)! 

     let boundary = "--- unique boundary string ---" 
     let contentType = "multipart/form-data; boundary=\(boundary)" 
     let fileName = "image.jpg" 
     let parameterName = "image-upload" 

     let body = NSMutableData() 


     // duplicate this if you need to send more parameters to the php script 
     body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
     body.appendData("Content-Disposition: form-data; name=\"username\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
     body.appendData("\(userName)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 



     // this is the file parameter 
     body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
     body.appendData("Content-Disposition: form-data; name=\"\(parameterName)\"; filename=\"\(fileName)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
     body.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
     body.appendData(imageData) 
     body.appendData("\r\n--\(boundary)--".dataUsingEncoding(NSUTF8StringEncoding)!) 

     request.setValue(contentType, forHTTPHeaderField: "Content-Type") 
     request.setValue("\(body.length)", forHTTPHeaderField: "Content-Length") 
     request.HTTPBody = body 


     let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { 
      data, response, error in 

      if error != nil { 
       print("error=\(error)") 
       return 
      } 

      let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) 
      print("imageUpload responseString: \(responseString!)") 
     } 
     task.resume() 
    } 
} 
Смежные вопросы