Saya telah diarahkan untuk menggunakan metode php://input
alih-alih $_POST
ketika berinteraksi dengan permintaan Ajax dari JQuery. Apa yang saya tidak mengerti adalah manfaat menggunakan ini vs metode global $_POST
atau $_GET
.
243
Jawaban:
Alasannya adalah bahwa
php://input
mengembalikan semua data mentah setelah HTTP-header permintaan, terlepas dari jenis konten.Superglobal PHP
$_POST
, hanya seharusnya membungkus data yang baikapplication/x-www-form-urlencoded
(tipe konten standar untuk posting bentuk sederhana) ataumultipart/form-data
(kebanyakan digunakan untuk unggah file)Ini karena ini adalah satu-satunya jenis konten yang harus didukung oleh agen pengguna . Jadi server dan PHP biasanya tidak berharap untuk menerima tipe konten lain (yang tidak berarti mereka tidak bisa).
Jadi, jika Anda hanya POST HTML lama yang baik
form
, permintaan terlihat seperti ini:Tetapi jika Anda sering bekerja dengan Ajax, probaby ini juga termasuk bertukar data yang lebih kompleks dengan tipe (string, int, bool) dan struktur (array, objek), sehingga dalam banyak kasus JSON adalah pilihan terbaik. Tetapi permintaan dengan payload JSON akan terlihat seperti ini:
Konten sekarang akan
application/json
(atau setidaknya tidak ada yang disebutkan di atas), jadi PHP-$_POST
pembungkus tidak tahu bagaimana mengatasinya (belum).Data masih ada, Anda tidak bisa mengaksesnya melalui pembungkus. Jadi, Anda perlu mengambilnya sendiri dalam format mentah dengan
file_get_contents('php://input')
( asalkan tidakmultipart/form-data
-dipode ).Ini juga cara Anda mengakses data XML atau jenis konten non-standar lainnya.
sumber
application/json
sebagai sumber data yang valid untuk$_POST
array. Dan bahkan ada permintaan khusus untuk dukungan yang dipublikasikan.php://input
dapat memberi Anda byte mentah data. Ini berguna jika data POSTed adalah struktur yang dikodekan JSON, yang sering terjadi untuk permintaan POST AJAX.Inilah fungsi untuk melakukan hal itu:
The
$_POST
array lebih berguna ketika Anda menangani data kunci-nilai dari bentuk, disampaikan oleh POST tradisional. Ini hanya berfungsi jika data POSTed dalam format yang dikenal, biasanyaapplication/x-www-form-urlencoded
(lihat http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 untuk detailnya).sumber
true
sebagai parameter keduajson_decode
, itu akan mengembalikan array asosiatif.Jika data posting salah format, $ _POST tidak akan berisi apa pun. Namun, input php: // akan memiliki string yang salah bentuk.
Misalnya ada beberapa aplikasi ajax, yang tidak membentuk urutan nilai kunci posting yang benar untuk mengunggah file, dan hanya membuang semua file sebagai data posting, tanpa nama variabel atau apa pun. $ _POST akan kosong, $ _FILES juga kosong, dan php: // input akan berisi file yang tepat, ditulis sebagai string.
sumber
Pertama, kebenaran dasar tentang PHP.
PHP tidak dirancang untuk secara eksplisit memberi Anda SISA murni (GET, POST, PUT, PATCH, DELETE) seperti antarmuka untuk menangani permintaan HTTP .
Namun,
$_POST
,$_GET
, dan$_FILES
superglobals , dan fungsifilter_input_array()
yang sangat berguna untuk kebutuhan rata-rata orang / awam.Keuntungan tersembunyi nomor satu dari
$_POST
(dan$_GET
) adalah bahwa data input Anda di- urecode secara otomatis oleh PHP . Anda bahkan tidak pernah berpikir harus melakukannya, terutama untuk parameter string kueri dalam permintaan GET standar.Namun, maka Anda belajar lebih banyak ...
Yang sedang berkata, saat Anda maju dalam pengetahuan pemrograman Anda dan ingin menggunakan JavaScript
XmlHttpRequest
(jQuery untuk beberapa), Anda datang untuk melihat batasan skema ini.$_POST
membatasi Anda untuk penggunaan dua jenis media dalamContent-Type
tajuk HTTP :application/x-www-form-urlencoded
, danmultipart/form-data
Dengan demikian, jika Anda ingin mengirim nilai data ke PHP di server, dan menampilkannya di
$_POST
superglobal , maka Anda harus urlencode di sisi klien dan mengirim data tersebut sebagai pasangan kunci / nilai - langkah yang tidak nyaman untuk pemula (terutama ketika mencoba mencari tahu apakah bagian URL yang berbeda memerlukan bentuk urlencoding yang berbeda: normal, mentah, dll.).Untuk semua Anda pengguna jQuery,
$.ajax()
metode ini mengubah JSON Anda ke pasangan kunci / nilai yang disandikan URL sebelum mengirimkannya ke server. Anda dapat mengganti perilaku ini dengan menetapkanprocessData: false
. Baca saja dokumentasi $ .ajax () , dan jangan lupa untuk mengirim jenis media yang benar di header Tipe-Konten.Pengkodean URL? Apa apaan!!!???
Biasanya, jika Anda melakukan normal, sinkron (ketika seluruh halaman redraws) permintaan HTTP dengan formulir HTML, agen-pengguna (browser web) akan urlencode data formulir Anda untuk Anda. Jika Anda ingin melakukan permintaan HTTP asinkron menggunakan
XmlHttpRequest
objek, maka Anda harus membuat string urlencoded dan mengirimkannya, jika Anda ingin data itu muncul di$_POST
superglobal .Seberapa dekat Anda dengan JavaScript? :-)
Konversi dari array JavaScript atau objek ke string urlencoded mengganggu banyak pengembang (bahkan dengan API baru seperti Formulir Data ). Mereka lebih suka mengirim JSON, dan akan lebih efisien bagi kode klien untuk melakukannya.
Ingat (mengedipkan mata, mengedipkan mata), rata-rata pengembang web tidak belajar untuk menggunakan
XmlHttpRequest
objek secara langsung, fungsi global, fungsi string, fungsi array, dan ekspresi reguler seperti Anda dan saya ;-). Urlencoding untuk mereka adalah mimpi buruk. ;-)PHP, apa yang menyebabkannya?
Kurangnya PHP XML intuitif dan penanganan JSON mematikan banyak orang. Anda akan berpikir itu akan menjadi bagian dari PHP sekarang (menghela nafas).
Begitu banyak jenis media (tipe MIME di masa lalu)
XML, JSON, dan YAML semuanya memiliki tipe media yang dapat dimasukkan ke dalam
Content-Type
header HTTP .Lihat berapa banyak jenis media (sebelumnya, tipe MIME) yang ditentukan oleh IANA.
Lihat berapa banyak header HTTP ada.
php: // input atau bust
Menggunakan
php://input
aliran memungkinkan Anda menghindari tingkat abstraksi baby-sitting / hand holding yang dipaksakan PHP di dunia. :-) Dengan kekuatan besar datang tanggung jawab besar!Sekarang, sebelum Anda berurusan dengan nilai data yang mengalir
php://input
, Anda harus / harus melakukan beberapa hal.Bagaimana dengan pengkodean karakter?
AH, HA! Ya, Anda mungkin ingin aliran data yang dikirim ke aplikasi Anda dikodekan UTF-8, tetapi bagaimana Anda bisa tahu apakah itu atau tidak?
Dua masalah kritis.
php://input
.Apakah Anda akan mencoba menangani data streaming tanpa mengetahui berapa banyak yang ada terlebih dahulu? Itu ide yang buruk . Anda tidak dapat bergantung secara eksklusif pada
Content-Length
tajuk HTTP untuk panduan tentang ukuran input yang dialirkan karena dapat dipalsukan.Anda akan membutuhkan:
Apakah Anda akan mencoba untuk mengkonversi data stream ke UTF-8 tanpa mengetahui pengkodean arus stream? Bagaimana? Filter stream iconv ( contoh filter iconv stream ) tampaknya menginginkan penyandian awal dan akhir, seperti ini.
Jadi, jika Anda teliti, Anda akan membutuhkan:
( Perbarui :
'convert.iconv.UTF-8/UTF-8'
akan memaksakan segalanya untuk UTF-8, tetapi Anda masih harus memperhitungkan karakter yang mungkin tidak diketahui oleh pustaka iconv. Dengan kata lain, Anda harus memahami cara menentukan tindakan apa yang harus diambil ketika karakter tidak dapat diterjemahkan. : 1) Masukkan karakter dummy, 2) Gagal / melempar dan pengecualian).Anda tidak dapat bergantung secara eksklusif pada
Content-Encoding
tajuk HTTP , karena ini mungkin menunjukkan sesuatu seperti kompresi seperti berikut ini. Ini bukan yang Anda inginkan untuk membuat keputusan sehubungan dengan ikonv.Oleh karena itu, langkah-langkah umum mungkin ...
Bagian I: Terkait Permintaan HTTP
Bagian II: Stream Data Terkait
Bagian III: Jenis Data Terkait
(Ingat, data masih bisa berupa string yang disandikan URL yang harus Anda uraikan dan dekode URL).
Bagian IV: Nilai Terkait Data
Memfilter data input.
Validasi input data.
Sekarang kamu lihat?
The
$_POST
superglobal, bersama dengan pengaturan php.ini untuk batas atas masukan, lebih sederhana bagi orang awam. Namun, berurusan dengan pengkodean karakter jauh lebih intuitif dan efisien ketika menggunakan stream karena tidak perlu mengulang melalui superglobals (atau array, umumnya) untuk memeriksa nilai input untuk pengkodean yang tepat.sumber
Jadi saya menulis fungsi yang akan mendapatkan data POST dari php: // input stream .
Jadi tantangan di sini adalah beralih ke metode permintaan PUT, DELETE ATAU PATCH, dan masih mendapatkan data pos yang dikirim bersama permintaan itu.
Saya membagikan ini mungkin untuk seseorang dengan tantangan serupa. Fungsi di bawah ini adalah apa yang saya temukan dan berfungsi. Saya harap ini membantu!
sumber
Contoh sederhana cara menggunakannya
sumber