JQuery Ajax istekleri ile etkileşim php://input
yerine yöntemi kullanmak için yönlendirildi $_POST
. Anlamadığım şey, bu yöntemi $_POST
veya global yöntemle kullanmanın yararlarıdır $_GET
.
JQuery Ajax istekleri ile etkileşim php://input
yerine yöntemi kullanmak için yönlendirildi $_POST
. Anlamadığım şey, bu yöntemi $_POST
veya global yöntemle kullanmanın yararlarıdır $_GET
.
Yanıtlar:
Bunun nedeni, php://input
içerik türünden bağımsız olarak, isteğin HTTP üstbilgilerinden sonra tüm ham verileri döndürmesidir.
PHP Süper küresel $_POST
, sadece gerekiyordu ya olduğu sarma verilerinin
application/x-www-form-urlencoded
(basit form gönderileri için standart içerik türü) veyamultipart/form-data
(çoğunlukla dosya yüklemeleri için kullanılır)Bunun nedeni, bunların kullanıcı aracıları tarafından desteklenmesi gereken tek içerik türleri olmasıdır . Bu nedenle sunucu ve PHP geleneksel olarak başka bir içerik türü almayı beklemez (bu, yapamayacakları anlamına gelmez).
Yani, eski güzel bir HTML'yi POST yaparsanız form
, istek şöyle görünür:
POST /page.php HTTP/1.1
key1=value1&key2=value2&key3=value3
Ancak Ajax ile çok çalışıyorsanız, bu probaby aynı zamanda türler (string, int, bool) ve yapılarla (diziler, nesneler) daha karmaşık veri alışverişini de içerir, bu nedenle çoğu durumda JSON en iyi seçimdir. Ancak bir JSON yükü olan bir istek şöyle görünecektir:
POST /page.php HTTP/1.1
{"key1":"value1","key2":"value2","key3":"value3"}
İçerik şimdi application/json
(veya yukarıda belirtilenlerin en azından hiçbiri) $_POST
olmayacağından, PHP'nin -wrapper'ı bununla nasıl başa çıkacağını bilmiyor (henüz).
Veriler hala orada, sadece sarmalayıcıdan erişemiyorsunuz. Bu nedenle, ham kodda kendiniz almanız gerekir file_get_contents('php://input')
( kodlanmamış olduğu sürecemultipart/form-data
).
XML verilerine veya standart olmayan başka bir içerik türüne de bu şekilde erişirsiniz.
application/json
için geçerli veri kaynağı olarak tanınmasını engellemez $_POST
. Ve özellikle bu destek için yayınlanmış talepler bile var.
php://input
size verilerin ham baytlarını verebilir. POSTed verileri genellikle AJAX POST isteği için geçerli olan JSON kodlu bir yapı ise yararlıdır.
İşte bunu yapmak için bir işlev:
/**
* 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);
}
$_POST
Geleneksel POST tarafından sunulan bir form, anahtar-değer verilerini ele yaparken dizi daha kullanışlıdır. Bu yalnızca POSTed verileri genellikle tanınan bir formattaysa çalışır application/x-www-form-urlencoded
( ayrıntılar için bkz. Http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 ).
true
İkinci parametre olarak geçerseniz json_decode
, ilişkilendirilebilir bir dizi döndüreceğini belirtmek gerekir.
Kayıt verileri hatalı biçimlendirilirse, $ _POST hiçbir şey içermez. Ancak, php: // input hatalı biçimlendirilmiş dizeye sahip olacaktır.
Örneğin, bir dosyayı yüklemek için doğru anahtar / değer çifti sırası oluşturmayan ve sadece değişken adları veya herhangi bir şey olmadan tüm verileri gönderi verisi olarak dökmeyen bazı ajax uygulamaları vardır. $ _POST boş, $ _FILES boş olacak ve php: // girişinde dize olarak yazılan tam dosya bulunacaktır.
PHP açıkça HTTP isteklerini işlemek için saf bir REST (GET, POST, PUT, PATCH, DELETE) benzeri bir arayüz vermek üzere tasarlanmamıştır .
Ancak $_POST
, $_GET
ve $_FILES
superglobals ve işlev filter_input_array()
ortalama kişinin / meslekten olmayan ihtiyaçları için çok yararlıdır.
$_POST
(Ve $_GET
) 'nin bir numaralı gizli avantajı, giriş verilerinizin PHP tarafından otomatik olarak urldecode edilmiş olmasıdır . Bunu yapmak zorunda kalmayı bile düşünmüyorsunuz, özellikle de standart bir GET isteği içindeki sorgu dizesi parametreleri için.
Bununla birlikte, programlama bilginiz ilerledikçe ve JavaScript'in XmlHttpRequest
nesnesini (bazıları için jQuery) kullanmak istediğinizde , bu şemanın sınırlamasını görmeye gelirsiniz.
$_POST
sizi HTTP Content-Type
üstbilgisinde iki ortam türünün kullanımı ile sınırlar :
application/x-www-form-urlencoded
, vemultipart/form-data
Bu nedenle, sunucudaki PHP'ye veri değerleri göndermek ve $_POST
süper küreselde görünmesini istiyorsanız , istemci tarafında urlencode ve adı geçen verileri anahtar / değer çiftleri olarak göndermelisiniz - acemiler için rahatsız edici bir adım (özellikle URL'nin farklı bölümlerinin farklı urlencoding biçimleri gerektirip gerektirmediğini anlamaya çalışırken: normal, ham, vb.).
Tüm jQuery kullanıcıları için $.ajax()
yöntem, JSON'unuzu sunucuya aktarmadan önce URL kodlamalı anahtar / değer çiftlerine dönüştürmektir. Bu davranışı ayarlayarak geçersiz kılabilirsiniz processData: false
. Sadece $ .ajax () belgelerini okuyun ve Content-Type başlığında doğru ortam türünü göndermeyi unutmayın.
Genellikle, bir HTML formuyla normal, eşzamanlı (tüm sayfa yeniden çizildiğinde) HTTP istekleri yapıyorsanız, kullanıcı aracısı (web tarayıcısı) form verilerinizi sizin için kodlar. XmlHttpRequest
Nesneyi kullanarak eşzamansız bir HTTP isteği yapmak istiyorsanız , urlen kodlu bir dize biçimlendirmeli ve bu verilerin $_POST
süper küreselde görünmesini istiyorsanız onu göndermelisiniz .
Bir JavaScript dizisinden veya nesnesinden urlen kodlanmış bir dizeye dönüştürmek birçok geliştiriciyi rahatsız eder ( Form Verileri gibi yeni API'lerle bile ). Sadece JSON gönderebilirler ve istemci kodunun bunu yapması daha verimli olur .
Unutmayın (wink, wink), ortalama web geliştiricisi XmlHttpRequest
nesneyi doğrudan kullanmayı öğrenmez , global işlevler, dize işlevleri, dizi işlevleri ve sizin ve ben ;-) gibi düzenli ifadeler. Onlar için Urlencoding bir kabus. ;-)
PHP'nin sezgisel XML ve JSON işleme eksikliği birçok kişiyi kapatır. Şimdiye kadar PHP'nin bir parçası olacağını düşünürdünüz.
XML, JSON ve YAML'nin hepsinin HTTP Content-Type
üstbilgisine yerleştirilebilecek medya türleri vardır .
IANA tarafından kaç medya türünün (eski adıyla MIME türleri) tanımlandığına bakın.
Bakın kaç HTTP başlığı var.
php://input
Akışı kullanmak, PHP'nin dünya üzerinde zorladığı bebek bakıcılığı / el tutma seviyesini atlamanızı sağlar. :-) Büyük güç büyük sorumluluk getirir!
Şimdi, aktarılan veri değerleriyle uğraşmadan önce php://input
birkaç şey yapmanız / yapmanız gerekir.
AH, HA! Evet, uygulamanıza gönderilen veri akışının UTF-8 kodlu olmasını isteyebilirsiniz, ancak bunun olup olmadığını nasıl anlayabilirsiniz?
php://input
.İlk önce ne kadar olduğunu bilmeden akış verilerini ele almaya çalışacak mısınız? Bu korkunç bir fikir . Content-Length
Sahte girişin boyutu konusunda rehberlik için yalnızca HTTP başlığına güvenemezsiniz, çünkü kimlik sahtekarlığı yapılabilir.
Aşağıdakilere ihtiyacınız olacak:
Akışın geçerli kodlamasını bilmeden akış verilerini UTF-8'e dönüştürmeye çalışacak mısınız? Nasıl? İconv akış filtresi ( iconv akış filtresi örneği ) bunun gibi bir başlangıç ve bitiş kodlaması istiyor gibi görünüyor.
'convert.iconv.ISO-8859-1/UTF-8'
Dolayısıyla, vicdanlıysanız, ihtiyacınız olacak:
( Güncelleme : 'convert.iconv.UTF-8/UTF-8'
her şeyi UTF-8'e zorlar, ancak hala iconv kütüphanesinin nasıl çevrileceğini bilemeyeceği karakterleri hesaba katmanız gerekir. : 1) Sahte bir karakter girin, 2) Arıza / atış ve istisna).
Content-Encoding
Aşağıdaki gibi sıkıştırma gibi bir şeyi gösterebileceğinden, yalnızca HTTP başlığına güvenemezsiniz . İconv ile ilgili karar vermek istemediğiniz şey bu değildir.
Content-Encoding: gzip
Bölüm I: HTTP Talebi İle İlgili
Bölüm II: Akım Verileri İle İlgili
Bölüm III: Veri Türü İle İlgili
(Verilerin yine de ayrıştırıp URL kodunu çözmeniz gereken URL kodlu bir dize olabileceğini unutmayın).
Bölüm IV: İlgili Veri Değeri
Giriş verilerine filtre uygulayın.
Giriş verilerini doğrulayın.
$_POST
Girişi sınırları için php.ini ayarları ile birlikte süper küresel, rahip olmayan kimse için basittir. Bununla birlikte, karakter kodlaması ile uğraşmak akışları kullanırken çok daha sezgisel ve etkilidir çünkü uygun kodlama için giriş değerlerini kontrol etmek için süper küreseller (veya genellikle diziler) arasında geçiş yapmaya gerek yoktur.
Bu yüzden php: // input akışından POST verilerini alacak bir fonksiyon yazdım .
Bu yüzden burada zorluk PUT, DELETE OR PATCH istek yöntemine geçiyordu ve yine de bu istekle gönderilen gönderi verilerini elde ediyordu.
Bunu belki de benzer zorluklarla karşılaşan biri için paylaşıyorum. Aşağıdaki fonksiyon ben geldi ve işe yarıyor. Umut ediyorum bu yardım eder!
/**
* @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;
}
Nasıl kullanılacağına dair basit bir örnek
<?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; }
?>