Apakah ada cara untuk mendapatkan header dan isi untuk permintaan CURL menggunakan PHP? Saya menemukan bahwa opsi ini:
curl_setopt($ch, CURLOPT_HEADER, true);
akan mengembalikan tubuh plus header , tapi kemudian saya perlu menguraikannya untuk mendapatkan tubuh. Apakah ada cara untuk mendapatkan keduanya dengan cara yang lebih bermanfaat (dan aman)?
Perhatikan bahwa untuk "permintaan tunggal" yang saya maksud menghindari mengeluarkan permintaan HEAD sebelum GET / POST.
Jawaban:
Salah satu solusi untuk ini diposting dalam komentar dokumentasi PHP: http://www.php.net/manual/en/function.curl-exec.php#80442
Contoh kode:
Peringatan: Seperti disebutkan dalam komentar di bawah, ini mungkin tidak dapat diandalkan saat digunakan dengan server proxy atau saat menangani jenis pengalihan tertentu. Jawaban @ Geoffrey dapat menangani ini dengan lebih andal.
sumber
list($header, $body) = explode("\r\n\r\n", $response, 2)
, tetapi ini mungkin butuh sedikit lebih lama, tergantung pada ukuran permintaan Anda.list($header, $body) = explode("\r\n\r\n", $response, 2)
hanya varian yang berfungsi100
(Lanjutkan). Untuk tajuk ini, Anda dapat berkeliling dengan menentukan opsi permintaan yang benar:,curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
menonaktifkan pengiriman respons tajuk ini. Adapun302
, ini seharusnya tidak terjadi, karena 302 header adalah redirect, itu tidak mengharapkan tubuh, namun saya tahu, kadang-kadang server mengirim beberapa tubuh dengan302
respons, tetapi tetap akan diabaikan oleh browser, sejauh ini, mengapa curl harus menangani ini? )CURLOPT_VERBOSE
dimaksudkan untuk menampilkan informasi proses keSTDERR
(dapat mengganggu di CLI) dan untuk masalah yang dibahas tidak berguna.Banyak solusi lain yang ditawarkan utas ini tidak melakukan ini dengan benar.
\r\n\r\n
tidak dapat diandalkan saatCURLOPT_FOLLOWLOCATION
dinyalakan atau ketika server merespons dengan kode 100.\n
untuk saluran baru.CURLINFO_HEADER_SIZE
juga tidak selalu dapat diandalkan, terutama ketika proksi digunakan atau dalam beberapa skenario pengalihan yang sama.Metode yang paling benar adalah menggunakan
CURLOPT_HEADERFUNCTION
.Berikut adalah metode yang sangat bersih untuk melakukan ini menggunakan penutupan PHP. Ini juga mengubah semua header menjadi huruf kecil untuk penanganan yang konsisten di seluruh server dan versi HTTP.
Versi ini akan mempertahankan header yang digandakan
Ini sesuai dengan RFC822 dan RFC2616, tolong jangan menyarankan pengeditan untuk menggunakan
mb_
fungsi string, itu salah!sumber
$headers = [];
php valid?Curl memiliki opsi bawaan untuk ini, disebut CURLOPT_HEADERFUNCTION. Nilai opsi ini haruslah nama fungsi panggilan balik. Curl akan meneruskan tajuk (dan hanya tajuk!) Ke fungsi panggilan balik ini, baris demi baris (sehingga fungsi akan dipanggil untuk setiap baris tajuk, mulai dari atas bagian tajuk). Fungsi panggilan balik Anda kemudian dapat melakukan apa saja dengan itu (dan harus mengembalikan jumlah byte dari baris yang diberikan). Berikut adalah kode kerja yang diuji:
Di atas berfungsi dengan segalanya, protokol dan proksi yang berbeda juga, dan Anda tidak perlu khawatir tentang ukuran header, atau mengatur banyak opsi ikal yang berbeda.
PS: Untuk menangani garis header dengan metode objek, lakukan ini:
sumber
apakah ini yang Anda cari?
sumber
A server that does not understand or is unable to comply with any of the expectation values in the Expect field of a request MUST respond with appropriate error status. The server MUST respond with a 417 (Expectation Failed) status if any of the expectations cannot be met or, if there are other problems with the request, some other 4xx status.
100
di komentar di bawah jawaban "benar" .Cukup atur opsi:
CURLOPT_HEADER, 0
CURLOPT_RETURNTRANSFER, 1
dan gunakan curl_getinfo dengan CURLINFO_HTTP_CODE (atau tanpa opt param dan Anda akan memiliki array asosiatif dengan semua informasi yang Anda inginkan)
Lebih lanjut di: http://php.net/manual/fr/function.curl-getinfo.php
sumber
curl_getinfo()
.Jika Anda secara khusus menginginkannya
Content-Type
, ada opsi CURL khusus untuk mengambilnya:sumber
Bekerja dengan
HTTP/1.1 100 Continue
sebelum header lainnya.Jika Anda perlu bekerja dengan server buggy yang hanya mengirim LF alih-alih CRLF sebagai jeda baris, Anda dapat menggunakan
preg_split
sebagai berikut:sumber
$parts = explode("\r\n\r\nHTTP/", $response);
memiliki parameter ke-3 untuk meledak sebagai 2?HTTP/1.1 100 Continue
dapat muncul berkali-kali.HTTP/1.1 100 Continue
dapat muncul berkali-kali. Ia melihat case jika hanya muncul satu kali saja, tetapi itu salah dalam kasus yang umum. Misalnya untukHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK...\r\n\r\n...
kode nya tidak berfungsi dengan baikCara saya adalah
Jika perlu terapkan for loop dan hapus batas meledak.
sumber
Inilah kontribusi saya untuk debat ... Ini mengembalikan satu array dengan data yang dipisahkan dan header terdaftar. Ini bekerja atas dasar bahwa CURL akan mengembalikan data [baris kosong] header
sumber
Masalah dengan banyak jawaban di sini adalah bahwa
"\r\n\r\n"
dapat muncul secara sah di badan html, sehingga Anda tidak dapat memastikan bahwa Anda membelah header dengan benar.Tampaknya satu-satunya cara untuk menyimpan header secara terpisah dengan satu panggilan
curl_exec
adalah dengan menggunakan panggilan balik seperti yang disarankan di atas di https://stackoverflow.com/a/25118032/3326494Dan kemudian untuk (andal) mendapatkan hanya tubuh permintaan, Anda harus meneruskan nilai
Content-Length
headersubstr()
sebagai nilai awal negatif.sumber
list($head, $body) = explode("\r\n\r\n", $response, 2);
:, namun CURL sudah melakukan ini untuk Anda jika Anda menggunakancurl_setopt($ch, CURLOPT_HEADERFUNCTION, $myFunction);
Kalau-kalau Anda tidak bisa / tidak menggunakan
CURLOPT_HEADERFUNCTION
atau solusi lain;sumber
Kembalikan tajuk respons dengan parameter referensi:
sumber
$rtn=explode("\r\n\r\nHTTP/", $rtn, 2);
itu benar? Bukankah seharusnya parameter ledakan ke-3 dihapus?explode("\r\n\r\n", $parts, 2);
jadi keduanya benar.Jika Anda tidak benar-benar perlu menggunakan ikal;
Output yang mana
Lihat http://php.net/manual/en/reserved.variables.httpresponseheader.php
sumber