2012-03-13 43 views
12

Tôi hiện đang phát triển một Json-API Restful trong PHP. Tôi muốn gửi yêu cầu PUT đến items/:id để cập nhật hồ sơ. Dữ liệu sẽ được chuyển thành application/json.PHP nhận cơ chế yêu cầu PUT

Tôi muốn gọi API với

curl -H "Content-Type: application/json" -X PUT -d '{"example" : "data"}' "http://localhost/items/someid" 

Về phía server, tôi không thể lấy những cơ thể theo yêu cầu. Tôi đã thử

file_get_contents("php://input"); 

nhưng điều này trả về một chuỗi trống. Ngoài ra, kết hợp fopen()/fread() không hoạt động.

Khi gọi qua POST, mọi thứ đều hoạt động tuyệt vời, tôi có thể đọc hoàn toàn json ở phía máy chủ. Nhưng API không còn hiệu quả nữa. Có ai có một giải pháp cho điều này? Có cách nào khác để gửi và nhận Json không?

btw, tôi đang phát triển API với Slim Framework.

+0

Bạn đã thử fopen ("php: // input", "r") chưa? – sethcall

+0

Có, không hoạt động. – aladin

+1

Tuyệt vời khi bạn sử dụng thiết bị mỏng. Tôi hy vọng bạn có trải nghiệm tốt. Tôi đã thực sự thích thú với việc tạo ra api an toàn của SLIM – Jake

Trả lời

13

php://input chỉ có thể đọc được một lần cho các yêu cầu PUT:

Lưu ý: Một dòng mở với php: // đầu vào chỉ có thể được đọc một lần; luồng không hỗ trợ hoạt động tìm kiếm. Tuy nhiên, tùy thuộc vào việc thực hiện SAPI, có thể mở một luồng đầu vào php: // khác và khởi động lại đọc. Điều này chỉ có thể nếu dữ liệu nội dung yêu cầu đã được lưu. Thông thường, đây là trường hợp cho các yêu cầu POST, nhưng không phải là các phương thức yêu cầu khác, chẳng hạn như PUT hoặc PROPFIND.

http://php.net/manual/en/wrappers.php.php

Khung Slim đã đọc dữ liệu theo yêu cầu. Lấy dữ liệu từ đối tượng Request, vào đó nó được đọc.

+4

Cảm ơn bạn rất nhiều, điều này đã giải quyết được vấn đề của tôi. Tôi có thể lấy dữ liệu thô với $ app-> request-> getBody(); và sau đó thực hiện một json_decode. Tôi đã không nhận thức được phương pháp này, vì nó không có trong tài liệu. – aladin

+0

+1 đây là vấn đề của tôi khi sử dụng khung công tác PHP restTonic. Biến $ this-> request-> này đã giữ phần thân PUT. Tôi đã đọc php: // đầu vào trong trình xử lý POST của tôi và không thể thấy tại sao trình xử lý PUT không thể sử dụng cùng một phương thức để xử lý phần thân của nó. – Neek

-1

Tôi đã đọc tài liệu về khung công tác SLIM vào ngày khác và nói rằng một số trình duyệt có vấn đề với PUT và DELETE.

Trích:

Thật không may, trình duyệt hiện đại không hỗ trợ gốc cho yêu cầu PUT. Để làm việc xung quanh hạn chế này, đảm bảo phương pháp hình thức HTML của bạn là “bài”, sau đó thêm một tham số phương pháp ghi đè vào biểu mẫu HTML như thế này:

<form action="/books/1" method="post"> 
    ... other form fields here... 
    <input type="hidden" name="_METHOD" value="PUT"/> 
    <input type="submit" value="Update Book"/> 
</form> 

Nguồn: http://www.slimframework.com/documentation/stable

+0

OP đang sử dụng Curl để thực hiện thao tác HTTP PUT. – GordonM

+0

Tôi cũng hơi mới với điều này, nhưng cURL có bỏ qua vấn đề trình duyệt không? Điều gì xảy ra nếu anh ta đang thực hiện yêu cầu curl thông qua PHP và đó là dòng lệnh tương đương? (Tôi không nói là anh ấy, tôi đang nói rằng dòng lệnh cURL sẽ vẫn tồn tại) – Jake

+0

@Jake: vâng, việc sử dụng cURL sẽ giải quyết vấn đề trình duyệt. Không có trình duyệt nào liên quan đến cách anh ta gọi dịch vụ. – Crontab

0

Ví dụ từ PHP manual sử dụng fopen để truy cập vào php: // input ở chế độ đọc. Bạn đã thử làm theo cách đó?

EDIT: manual page for PHP:// nói một số nội dung có vẻ gợi ý rằng dữ liệu PUT có thể không khả dụng trong một số trường hợp!

Lưu ý: Một luồng được mở bằng đầu vào php: // chỉ có thể đọc một lần; luồng không hỗ trợ hoạt động tìm kiếm. Tuy nhiên, tùy thuộc vào việc triển khai thực hiện SAPA , có thể mở một dòng php: // input khác và khởi động lại đọc. Điều này chỉ có thể nếu cơ thể yêu cầu dữ liệu đã được lưu. Thông thường, đây là trường hợp yêu cầu POST, nhưng không phải là các phương thức yêu cầu khác, chẳng hạn như PUT hoặc PROPFIND.

Tôi không biết điều này sẽ khiến bạn liên quan đến việc xử lý PUT. Một trang có vẻ như có thể nói, có vẻ như trang có vẻ ngụ ý rằng nó sẽ không hoạt động theo tập hợp các trường hợp sai

1

Ở phía máy chủ, tôi không thể truy xuất phần thân yêu cầu. Tôi đã thử file_get_contents ("php: // input");

Bạn chỉ có thể sử dụng file_get_contents('php://input', 'r'); một lần cho mỗi yêu cầu. Lấy giá trị của nó cũng sẽ cắt bớt các giá trị, vì vậy nếu bạn gọi nó hai lần, nó sẽ trả về một chuỗi rỗng.đối tượng yêu cầu Slim chứa các giá trị bạn cần, vì vậy:

<?php 
$app = new Slim(); 

$app->put('/items/someid', function() use ($app) { 
    echo $app->request()->put('example'); // should display "data". 
}); 
+1

Điều này đúng với dữ liệu được mã hóa url, nhưng không đúng với dữ liệu json thô. nếu tôi gửi url dữ liệu được mã hóa, tôi có thể truy cập nó thông qua đối tượng yêu cầu của Slim. không làm việc cho json khó khăn. – aladin

+0

Vấn đề vẫn còn; bạn chỉ có thể đọc từ php: // input * once * và Slim đã thực hiện điều đó. Bạn sẽ phải sử dụng đối tượng yêu cầu của Slim để lấy giá trị của bạn. –

+1

Rõ ràng khung công tác Slim đọc phần thân yêu cầu khi xây dựng, do đó, php: // input đã bị xóa. cám ơn! – aladin

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