2013-06-09 52 views
5

Tôi đang cố gắng tải lên tệp bằng cách sử dụng HTTP PUT.
Sau khi đọc một chút có vẻ như mảng $_FILES chỉ với POST và multipart/form-data. Trong khi với PUT, tôi cần đọc theo cách thủ công php://input để nhận dữ liệu. Cả hai phương pháp đều không hoạt động.Yêu cầu Curl PUT với tải tệp lên PHP

Tôi đã thử các tùy chọn sau và sẽ đánh giá cao bất cứ lời khuyên bạn có thể có:

curl --upload avatar.jpg http://api.test.com/user/dsadasdsa 
curl -X PUT -F "[email protected]" http://api.test.com/user/dsadasdsa 

PHP tập tin của tôi đang cố gắng để in này nhưng trả về một chuỗi rỗng:

echo file_get_contents("php://input"); 

tôi bắt đầu suy nghĩ điều này có thể là một vấn đề Nginx thiếu hỗ trợ PUT DELETE và cài đặt nginx-extras cũng như thêm phần sau vào cấu hình nginx của tôi nhưng điều này cũng không giúp được gì nhiều.

root /var/www/; 

dav_methods PUT DELETE MKCOL COPY MOVE; 

create_full_put_path on; 
dav_access group:rw all:r; 
+0

* tham chiếu * http://php.net/manual/en/features.file-upload.put-method.php – Gordon

+0

@Gordon - Cảm ơn bạn. Tôi biết trang đó nhưng nó chỉ cho tôi biết phải làm gì ở phía PHP (mà tôi đã làm). Và không thực sự nói với tôi những gì tôi đang làm sai trên lề đường. –

+0

Ngoài ra, cố gắng chạy mã chính xác từ hướng dẫn chỉ tạo một tệp trống. Vì vậy, tôi khá chắc chắn yêu cầu CURL của tôi là sai mặt. –

Trả lời

3

Tôi có một số ý tưởng để gỡ lỗi.

Thực hiện var_dump(file_get_contents('php://input')); thay vì một tiếng vọng. Theo số reference:

Hàm này có thể trả về Boolean FALSE, nhưng cũng có thể trả về giá trị Boolean không đánh giá FALSE. Vui lòng đọc phần trên Booleans để biết thêm thông tin. Sử dụng toán tử === để kiểm tra giá trị trả về của hàm này.

Nếu bạn nhận được bool(false) làm đầu ra, có điều gì đó sai khiến bạn không thể đọc được php://input - rất có thể là vấn đề về PHP. Nếu bạn nhận được string(0) "", sẽ không có gì trong số php://input (nữa?), Điều này khiến nhiều khả năng đây là vấn đề nginx.

Ngoài ra, theo số php:// reference, bạn không thể sử dụng php://input với enctype="multipart/form-data". Bạn có chắc là bạn không sử dụng cái đó không? Bạn cũng có thể thử một tệp HTML nếu nó quen thuộc hơn.

Bạn cũng có thể kiểm tra nhật ký lỗi, /var/log/nginx/error.log theo mặc định. Ngoài ra, hãy kiểm tra mã phản hồi HTTP. Có phải 200 không? Nếu không, đó có phải là mã hữu ích không?

+0

Thật không may tôi đã không có cơ hội để kiểm tra điều này được nêu ra, nhưng câu trả lời của bạn có vẻ là kỹ lưỡng nhất cho đến nay. Cảm ơn! –

+0

@ShaiMishali vui lòng cho tôi biết nếu bạn đã thử nghiệm. Và cảm ơn đại diện :) – Keelan

1

Nginx hỗ trợ tất cả các động từ http (đặt, xóa, tùy chọn, v.v.). Vì vậy, bạn không cần bất kỳ thiết lập đặc biệt trong nginx cho điều đó.

Các công trình sau đây (Tôi đang sử dụng máy chủ php5.4 để dễ dàng kiểm tra này):

Thêm kịch bản thử nghiệm php đơn giản này được gọi là put.php

$putdata = fopen("php://input", "r"); 
while ($data = fread($putdata, 1024)) { 
     echo $data . "\n"; 
} 

Bắt đầu một máy chủ php từ cùng một thư mục của put.php:

php -S localhost:5000 

Issue một PUT curl yêu cầu:

curl -d "@/path/to/put.php" -X PUT http://localhost:5000/put.php 

Thao tác này sẽ in nội dung của tệp.php

[cập nhật]

Trong trường hợp bạn muốn sử dụng php để gửi yêu cầu curl đến một trang web api yên tĩnh, tôi khuyên bạn nên Guzzle, mà bạn không cần phải nhớ tất cả những tùy chọn curl.

2

Tùy chọn -F bạn đang sử dụng nguyên nhân curl để POST dữ liệu bằng cách sử dụng dữ liệu đa dạng/biểu mẫu loại nội dung (xem man curl).

Bạn có thể sử dụng tùy chọn --data nhị phân như trong:

curl -X PUT --data-binary "@avatar.jpg" http://api.test.com/user/dsadasdsa 

Các tùy chọn -d chỉ dành cho văn bản và có thể làm hỏng dữ liệu của bạn.

Trong các thử nghiệm của tôi, lệnh sau đây đưa ra kết quả tương tự.

curl --upload "avatar.jpg" http://api.test.com/user/dsadasdsa 

Đây là máy chủ của tôi

<?php 
echo "request method : " . $_SERVER['REQUEST_METHOD'] . "\n"; 
echo "dump files "; 
var_dump($_FILES); 

$putdata = fopen("php://input", "r"); 
while ($data = fread($putdata, 1024)) { 
     echo $data . "\n"; 
} 
?> 
0

Nếu bạn đang cố gắng để tạo ra một yêu cầu PUT đến một máy chủ và không thể đọc từ wrapper php, hãy chắc chắn rằng:

  1. bạn có yêu cầu PUT phù hợp. hoàn chỉnh với tiêu đề và nội dung (Making a PUT request with PHP and CURL)

  2. máy chủ của bạn chấp nhận yêu cầu PUT.

  3. tập tin php của bạn có thể đọc yêu cầu PUT đơn giản đầu tiên (không có phần upload)

Bạn cũng có thể muốn kiểm tra 'lưu ý' ghi trong php: // đầu vào (http://php.net/manual/en/wrappers.php.php). Ngoài ra, nó có thể là một vấn đề trên máy chủ.

0

Cả hai phương pháp này không làm việc

Tôi chưa bao giờ cố gắng thực hiện DAV với PHP nhưng tôi có thể đảm bảo với bạn rằng POST với tải lên tập tin hoạt động, ngay cả với nginx.

curl --upload avatar.jpg http://api.test.com/user/dsadasdsa

tôi dự kiến ​​sẽ có này để làm việc - điều gì làm các bản ghi của bạn hiển thị? Bạn đã thử với '--trace'?

curl -X PUT -F "[email protected]" http://api.test.com/user/dsadasdsa

Sử dụng cờ -F với curl nghĩa để tải lên một tập tin như là một biến POST, sử dụng multipart/form-data mã hóa - không có ý nghĩa gì với yêu cầu PUT.

0

Bạn đã loại bỏ PHP là nguyên nhân của sự cố bằng cách đặt một loại webapp khác vào sau nginx và thử nghiệm xem liệu nó có thể xử lý tải lên PUT không? Một ứng dụng Python Flask rất ngắn sẽ cho phép bạn kiểm tra tải lên PUT bằng ngôn ngữ khác.

Các vấn đề liên quan