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
.
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
.
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 baik
application/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:
POST /page.php HTTP/1.1
key1=value1&key2=value2&key3=value3
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:
POST /page.php HTTP/1.1
{"key1":"value1","key2":"value2","key3":"value3"}
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 tidak multipart/form-data
-dipode ).
Ini juga cara Anda mengakses data XML atau jenis konten non-standar lainnya.
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:
/**
* Returns the JSON encoded POST data, if any, as an object.
*
* @return Object|null
*/
private function retrieveJsonPostData()
{
// get the raw POST data
$rawData = file_get_contents("php://input");
// this returns null if not valid json
return json_decode($rawData);
}
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, biasanya application/x-www-form-urlencoded
(lihat http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 untuk detailnya).
true
sebagai parameter kedua json_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.
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 fungsi filter_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.
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 dalam Content-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 menetapkan processData: false
. Baca saja dokumentasi $ .ajax () , dan jangan lupa untuk mengirim jenis media yang benar di header Tipe-Konten.
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 .
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. ;-)
Kurangnya PHP XML intuitif dan penanganan JSON mematikan banyak orang. Anda akan berpikir itu akan menjadi bagian dari PHP sekarang (menghela nafas).
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.
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.
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?
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.
'convert.iconv.ISO-8859-1/UTF-8'
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.
Content-Encoding: gzip
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.
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.
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!
/**
* @method Post getPostData
* @return array
*
* Convert Content-Disposition to a post data
*/
function getPostData() : array
{
// @var string $input
$input = file_get_contents('php://input');
// continue if $_POST is empty
if (strlen($input) > 0 && count($_POST) == 0 || count($_POST) > 0) :
$postsize = "---".sha1(strlen($input))."---";
preg_match_all('/([-]{2,})([^\s]+)[\n|\s]{0,}/', $input, $match);
// update input
if (count($match) > 0) $input = preg_replace('/([-]{2,})([^\s]+)[\n|\s]{0,}/', '', $input);
// extract the content-disposition
preg_match_all("/(Content-Disposition: form-data; name=)+(.*)/m", $input, $matches);
// let's get the keys
if (count($matches) > 0 && count($matches[0]) > 0)
{
$keys = $matches[2];
foreach ($keys as $index => $key) :
$key = trim($key);
$key = preg_replace('/^["]/','',$key);
$key = preg_replace('/["]$/','',$key);
$key = preg_replace('/[\s]/','',$key);
$keys[$index] = $key;
endforeach;
$input = preg_replace("/(Content-Disposition: form-data; name=)+(.*)/m", $postsize, $input);
$input = preg_replace("/(Content-Length: )+([^\n]+)/im", '', $input);
// now let's get key value
$inputArr = explode($postsize, $input);
// @var array $values
$values = [];
foreach ($inputArr as $index => $val) :
$val = preg_replace('/[\n]/','',$val);
if (preg_match('/[\S]/', $val)) $values[$index] = trim($val);
endforeach;
// now combine the key to the values
$post = [];
// @var array $value
$value = [];
// update value
foreach ($values as $i => $val) $value[] = $val;
// push to post
foreach ($keys as $x => $key) $post[$key] = isset($value[$x]) ? $value[$x] : '';
if (is_array($post)) :
$newPost = [];
foreach ($post as $key => $val) :
if (preg_match('/[\[]/', $key)) :
$k = substr($key, 0, strpos($key, '['));
$child = substr($key, strpos($key, '['));
$child = preg_replace('/[\[|\]]/','', $child);
$newPost[$k][$child] = $val;
else:
$newPost[$key] = $val;
endif;
endforeach;
$_POST = count($newPost) > 0 ? $newPost : $post;
endif;
}
endif;
// return post array
return $_POST;
}
Contoh sederhana cara menggunakannya
<?php
if(!isset($_POST) || empty($_POST)) {
?>
<form name="form1" method="post" action="">
<input type="text" name="textfield"><br />
<input type="submit" name="Submit" value="submit">
</form>
<?php
} else {
$example = file_get_contents("php://input");
echo $example; }
?>