ฉันจะส่งคำขอ POST ด้วย PHP ได้อย่างไร


656

ที่จริงแล้วฉันต้องการอ่านเนื้อหาที่มาหลังจากการค้นหาเมื่อทำเสร็จแล้ว ปัญหาคือว่า URL ยอมรับPOSTวิธีการเท่านั้นและจะไม่ดำเนินการใด ๆ กับGETวิธีการ ...

ฉันต้องอ่านเนื้อหาทั้งหมดด้วยความช่วยเหลือของหรือdomdocument file_get_contents()มีวิธีใดบ้างที่จะให้ฉันส่งพารามิเตอร์ด้วยPOSTวิธีการแล้วอ่านเนื้อหาผ่านPHP?

คำตอบ:


1260

วิธี CURL-less ด้วย PHP5:

$url = 'http://server.com/path';
$data = array('key1' => 'value1', 'key2' => 'value2');

// use key 'http' even if you send the request to https://...
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data)
    )
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }

var_dump($result);

ดูคู่มือ PHP สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการและวิธีการเพิ่มส่วนหัวตัวอย่างเช่น


64
เป็นที่น่าสังเกตว่าถ้าคุณตัดสินใจใช้อาเรย์สำหรับส่วนหัวอย่าวางคีย์หรือค่าด้วย '\ r \ n' stream_context_create () จะใช้ข้อความถึง '\ r \ n' คนแรกเท่านั้น
raptor

11
URL สามารถใช้เป็นชื่อไฟล์ได้file_get_contents()ก็ต่อเมื่อตัวเลือก fopen ถูกเปิดใช้งาน ดูphp.net/manual/en/…
Pino

3
@ ฉันรักfile_get_contents()
deadlock

14
มีเหตุผลเฉพาะที่ไม่ใช้ CURL หรือไม่
jvannistelrooy

37
@jvannistelrooy CURL สำหรับ PHP เป็นส่วนเสริมที่อาจไม่มีอยู่ในทุกสภาพแวดล้อมในขณะที่file_get_contents()เป็นส่วนหนึ่งของคอร์ PHP นอกจากนี้การใช้ส่วนขยายโดยไม่จำเป็นสามารถขยายพื้นผิวการโจมตีของแอปของคุณได้ เช่น Google php curl cve
Pocketsand

139

คุณสามารถใช้cURL :

<?php
//The url you wish to send the POST request to
$url = $file_name;

//The data you want to send via POST
$fields = [
    '__VIEWSTATE '      => $state,
    '__EVENTVALIDATION' => $valid,
    'btnSubmit'         => 'Submit'
];

//url-ify the data for the POST
$fields_string = http_build_query($fields);

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);

//So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true); 

//execute post
$result = curl_exec($ch);
echo $result;
?>

3
อันนี้ใช้ได้สำหรับฉันเพราะหน้าที่ฉันกำลังส่งไปยังหน้าที่ไม่มีเนื้อหาดังนั้นเวอร์ชัน file_get_contents ไม่ทำงาน
CommentLuv

9
โซลูชัน file_get_contents ไม่ทำงานบนการกำหนดค่า PHP ด้วย allow_url_fopen Off (เช่นในโฮสติ้งที่ใช้ร่วมกัน) รุ่นนี้ใช้ไลบรารี curl และฉันคิดว่าเป็น "สากล" ที่สุดดังนั้นฉันให้คุณลงคะแนนของฉัน
Dayron Gallardo

81
คุณไม่ได้เว็บไซต์ที่คุณคัดลอกตัวอย่างโค้ดนี้จาก: davidwalsh.name/curl-post
efreed

4
แม้ว่ามันจะไม่สำคัญมาก แต่ข้อมูลพารามิเตอร์ CURLOPT_POSTFIELDS นั้นไม่จำเป็นต้องแปลงเป็นสตริง ("urlified") อ้างอิง: "พารามิเตอร์นี้สามารถส่งผ่านเป็นสตริง urlencoded เช่น 'para1 = val1 & para2 = val2 & ... ' หรือเป็นอาร์เรย์ที่มีชื่อเขตข้อมูลเป็นข้อมูลคีย์และฟิลด์ตามค่าถ้าค่าเป็นอาร์เรย์ประเภทเนื้อหา ส่วนหัวจะถูกตั้งค่าเป็น multipart / form-data " Link: php.net/manual/en/function.curl-setopt.php
Edward

2
นอกจากนี้ไม่มีความผิดในการเขียนมันแตกต่างกัน แต่ฉันไม่รู้ว่าทำไมพารามิเตอร์ CURLOPT_POST ถูกระบุเป็นตัวเลขที่นี่ตามที่กล่าวเพื่อตั้งเป็นบูลีนในหน้าคู่มือ อ้างอิง: "CURLOPT_POST: TRUE เพื่อทำ HTTP POST ปกติ" Link: php.net/manual/en/function.curl-setopt.php
Edward

68

ฉันใช้ฟังก์ชันต่อไปนี้เพื่อโพสต์ข้อมูลโดยใช้ curl $ data คืออาร์เรย์ของฟิลด์ที่จะโพสต์ (จะเข้ารหัสอย่างถูกต้องโดยใช้ http_build_query) ข้อมูลถูกเข้ารหัสโดยใช้ application / x-www-form-urlencoded

function httpPost($url, $data)
{
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($curl);
    curl_close($curl);
    return $response;
}

@Edward ระบุว่าอาจละเว้น http_build_query เนื่องจาก curl จะเข้ารหัสอาร์เรย์ที่ส่งผ่านไปยังพารามิเตอร์ CURLOPT_POSTFIELDS อย่างถูกต้อง แต่ขอแนะนำว่าในกรณีนี้ข้อมูลจะถูกเข้ารหัสโดยใช้หลายส่วน / แบบฟอร์มข้อมูล

ฉันใช้ฟังก์ชั่นนี้กับ API ที่คาดว่าข้อมูลจะถูกเข้ารหัสโดยใช้ application / x-www-form-urlencoded นั่นเป็นเหตุผลที่ฉันใช้ http_build_query ()


การส่งผ่านอาร์เรย์ไปยัง CURLOPT_POSTFIELDS ทำให้ข้อมูลถูกเข้ารหัสโดยใช้หลายส่วน / แบบฟอร์มข้อมูลซึ่งอาจไม่เป็นที่ต้องการ
Dima L.

ผู้ใช้ถามหา file_get_contents ดังนั้นเขาจึงต้องการโซลูชันสำหรับเปลี่ยน default_stream_context
Radon8472

เพื่อชี้แจง: ฉันคิดว่า @DimaL กำลังตอบกลับความคิดเห็นที่ถูกลบไปแล้ว http_build_queryแปลง$dataอาร์เรย์เป็นสตริงหลีกเลี่ยงเอาต์พุตเป็น multipart / form-data
ToolmakerSteve

@ Radon8472 - ... CURLOPT_RETURNTRANSFER, trueส่งผลให้$responseมีเนื้อหา
ToolmakerSteve

@ToolmakerSteve อย่างที่ฉันบอกไปแล้วคำถามนี้มีไว้เพื่อfile_get_contentsคุณและวิธีการแก้ปัญหาของคุณต้องการ CURL ที่หลายคนไม่มี ดังนั้นโซลูชันของคุณอาจทำงานได้ แต่ก็ไม่ได้ตอบคำถามว่าจะทำอย่างไรกับฟังก์ชั่นไฟล์ / สตรีมในตัว
Radon8472

42

ผมขอแนะนำให้คุณใช้โอเพนซอร์สแพคเกจล่อที่มีอย่างเต็มที่หน่วยทดสอบและใช้การเขียนโค้ดที่ล่าสุด

การติดตั้ง Guzzle

ไปที่บรรทัดคำสั่งในโฟลเดอร์โครงการและพิมพ์คำสั่งต่อไปของคุณ (สมมติว่าคุณมีแพคเกจผู้จัดการนักแต่งเพลงที่ติดตั้ง) หากคุณต้องการความช่วยเหลือวิธีการติดตั้งนักแต่งเพลง, คุณควรจะมีดูที่นี่

php composer.phar require guzzlehttp/guzzle

การใช้ Guzzle เพื่อส่งคำขอ POST

การใช้ Guzzle นั้นตรงไปตรงมามากเนื่องจากใช้ API เชิงวัตถุน้ำหนักเบา:

// Initialize Guzzle client
$client = new GuzzleHttp\Client();

// Create a POST request
$response = $client->request(
    'POST',
    'http://example.org/',
    [
        'form_params' => [
            'key1' => 'value1',
            'key2' => 'value2'
        ]
    ]
);

// Parse the response object, e.g. read the headers, body, etc.
$headers = $response->getHeaders();
$body = $response->getBody();

// Output headers and body for debugging purposes
var_dump($headers, $body);

7
มันจะมีประโยชน์ที่จะทราบว่าสิ่งนี้มีประโยชน์เหนือโซลูชั่น PHP พื้นเมืองแล้วโพสต์และหนึ่ง cURL เกินไป
artfulrobot

9
@artfulrobot: โซลูชัน PHP ดั้งเดิมมีปัญหามากมาย (เช่นการเชื่อมต่อกับ https, การตรวจสอบใบรับรอง, ฯลฯ .) ซึ่งเป็นเหตุผลที่นักพัฒนา PHP เกือบทุกรายใช้ cURL และทำไมไม่ใช้ cURL ในกรณีนี้ มันง่าย: Guzzle มีส่วนต่อประสานที่ตรงไปตรงมาง่ายและน้ำหนักเบาซึ่งจะทำให้นามธรรม "ปัญหาการจัดการขนลุกระดับต่ำ" ทั้งหมดออกไป เกือบทุกคนที่พัฒนา PHP สมัยใหม่จะใช้ Composer อยู่แล้วดังนั้นการใช้ Guzzle นั้นง่ายมากจริงๆ
Andreas

2
ขอบคุณฉันรู้ว่า guzzle เป็นที่นิยม แต่มีกรณีการใช้งานเมื่อผู้แต่งทำให้เกิดความเศร้าโศก (เช่นการพัฒนาปลั๊กอินสำหรับโครงการซอฟต์แวร์ขนาดใหญ่ที่อาจใช้ guzzle (รุ่นอื่น) หรือการอ้างอิงอื่น ๆ ) ดังนั้นจึงเป็นการดีที่จะทราบข้อมูลนี้ การตัดสินใจว่าโซลูชันใดจะมีประสิทธิภาพสูงสุด
artfulrobot

26

มีอีกวิธี CURL ถ้าคุณไปทางนั้น

นี่เป็นเรื่องตรงไปตรงมาเมื่อคุณเข้าใจวิธีการทำงานของส่วนขยาย PHP curl โดยรวมการตั้งค่าสถานะต่าง ๆ กับการเรียก setopt () ในตัวอย่างนี้ฉันมีตัวแปร $ xml ซึ่งเก็บ XML ที่ฉันได้เตรียมไว้ - ฉันจะโพสต์เนื้อหาของวิธีทดสอบของตัวอย่าง

$url = 'http://api.example.com/services/xmlrpc/';
$ch = curl_init($url);

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);
//process $response

ก่อนอื่นเราเริ่มการเชื่อมต่อจากนั้นเราตั้งค่าตัวเลือกบางอย่างโดยใช้ setopt () สิ่งเหล่านี้บอก PHP ว่าเราทำการร้องขอโพสต์และเรากำลังส่งข้อมูลบางอย่างไปพร้อมกับให้ข้อมูล ค่าสถานะ CURLOPT_RETURNTRANSFER บอกให้ curl ให้ผลลัพธ์กับเราเป็นค่าส่งคืนของ curl_exec แทนที่จะแสดงผลลัพธ์ จากนั้นเราโทรออกและปิดการเชื่อมต่อ - ผลลัพธ์คือ $ การตอบกลับ


1
ในการโทร curl_setopt () ครั้งที่ 3 หาเรื่องแรกควรจะ$chไม่$curlถูกต้อง?
jcomeau_ictx

คุณสามารถใช้รหัสเดียวกันนี้กับข้อมูล POST JSON ได้หรือไม่ แต่แทนที่ $ xml ด้วยคำพูด $ json (ที่ $ json น่าจะเป็นสตริง JSON?)
Neal Davis

24

หากคุณใช้ Wordpress ในการพัฒนาแอพของคุณ (เป็นวิธีที่สะดวกในการขออนุญาตหน้าข้อมูล ฯลฯ แม้จะเป็นเรื่องง่าย ๆ ) คุณสามารถใช้ตัวอย่างต่อไปนี้:

$response = wp_remote_post( $url, array('body' => $parameters));

if ( is_wp_error( $response ) ) {
    // $response->get_error_message()
} else {
    // $response['body']
}

มันใช้วิธีที่แตกต่างกันในการทำคำขอ HTTP จริงขึ้นอยู่กับสิ่งที่มีอยู่บนเว็บเซิร์ฟเวอร์ สำหรับรายละเอียดเพิ่มเติมโปรดดูเอกสารประกอบ HTTP APIเอกสาร

หากคุณไม่ต้องการพัฒนาชุดรูปแบบหรือปลั๊กอินที่กำหนดเองเพื่อเริ่มใช้งานโปรแกรม Wordpress คุณสามารถทำสิ่งต่อไปนี้ในไฟล์ PHP แบบแยกในรูท WordPress:

require_once( dirname(__FILE__) . '/wp-load.php' );

// ... your code

มันจะไม่แสดงธีมหรือส่ง HTML ใด ๆ เพียงแค่แฮ็คไปกับ Wordpress APIs!


22

ฉันต้องการเพิ่มความคิดเห็นเกี่ยวกับคำตอบของ Fred Tanrikut ฉันรู้ว่าพวกเขาส่วนใหญ่เขียนไว้แล้วในคำตอบข้างต้น แต่ฉันคิดว่ามันเป็นความคิดที่ดีที่จะแสดงคำตอบที่รวมพวกเขาทั้งหมดเข้าด้วยกัน

นี่คือคลาสที่ฉันเขียนเพื่อสร้างคำร้องขอ HTTP-GET / POST / PUT / DELETE ตาม curl ซึ่งเกี่ยวข้องกับเนื้อหาการตอบสนอง:

class HTTPRequester {
    /**
     * @description Make HTTP-GET call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPGet($url, array $params) {
        $query = http_build_query($params); 
        $ch    = curl_init($url.'?'.$query);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-POST call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPost($url, array $params) {
        $query = http_build_query($params);
        $ch    = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-PUT call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPut($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'PUT');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
    /**
     * @category Make HTTP-DELETE call
     * @param    $url
     * @param    array $params
     * @return   HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPDelete($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'DELETE');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
}

ปรับปรุง

  • การใช้ http_build_query เพื่อดึงเคียวรีสตริงออกจาก request-array (คุณสามารถใช้อาร์เรย์เองได้ดังนั้นโปรดดู: http://php.net/manual/en/function.curl-setopt.php )
  • ส่งคืนการตอบสนองแทนที่จะสะท้อนกลับ Btw คุณสามารถหลีกเลี่ยงการส่งคืนได้โดยลบบรรทัดcurl_setopt ($ ch, CURLOPT_RETURNTRANSFER จริง) . หลังจากนั้นค่าส่งคืนจะเป็นบูลีน (คำขอจริง = สำเร็จแล้วมิฉะนั้นจะเกิดข้อผิดพลาดขึ้น) และการตอบสนองจะถูกสะท้อนกลับ ดู: http://php.net/en/manual/function.curl-exec.php
  • ปิดเซสชั่นที่สะอาดและลบขดจัดการโดยใช้curl_close ดู: http://php.net/manual/th/function.curl-close.php
  • การใช้ค่าบูลีนสำหรับฟังก์ชั่นcurl_setoptแทนที่จะใช้ตัวเลขใด ๆ (ฉันรู้ว่าหมายเลขใด ๆ ที่ไม่เท่ากับศูนย์ก็ถือว่าเป็นจริงเช่นกัน แต่การใช้งานจริงสร้างรหัสที่อ่านได้มากขึ้น
  • ความสามารถในการโทร HTTP-PUT / DELETE (มีประโยชน์สำหรับการทดสอบบริการที่สงบ)

ตัวอย่างการใช้งาน

GET

$response = HTTPRequester::HTTPGet("http://localhost/service/foobar.php", array("getParam" => "foobar"));

โพสต์

$response = HTTPRequester::HTTPPost("http://localhost/service/foobar.php", array("postParam" => "foobar"));

PUT

$response = HTTPRequester::HTTPPut("http://localhost/service/foobar.php", array("putParam" => "foobar"));

ลบ

$response = HTTPRequester::HTTPDelete("http://localhost/service/foobar.php", array("deleteParam" => "foobar"));

การทดสอบ

นอกจากนี้คุณยังสามารถทำการทดสอบการบริการที่ยอดเยี่ยมโดยใช้คลาสง่าย ๆ นี้

class HTTPRequesterCase extends TestCase {
    /**
     * @description test static method HTTPGet
     */
    public function testHTTPGet() {
        $requestArr = array("getLicenses" => 1);
        $url        = "http://localhost/project/req/licenseService.php";
        $this->assertEquals(HTTPRequester::HTTPGet($url, $requestArr), '[{"error":false,"val":["NONE","AGPL","GPLv3"]}]');
    }
    /**
     * @description test static method HTTPPost
     */
    public function testHTTPPost() {
        $requestArr = array("addPerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPost($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPPut
     */
    public function testHTTPPut() {
        $requestArr = array("updatePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPut($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPDelete
     */
    public function testHTTPDelete() {
        $requestArr = array("deletePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPDelete($url, $requestArr), '[{"error":false}]');
    }
}

สำหรับผมมันบอกว่า"ข้อผิดพลาด Uncaught: โทรไปไม่ได้กำหนดวิธีการ HTTPRequester :: HTTPost ()" ฉันเพิ่งวางชั้นเรียนของคุณลงในไฟล์. php ของฉัน มีอะไรอีกบ้างที่ฉันต้องทำ
LinusGeffarth

1
คุณช่วยกรุณาโพสต์รหัสของคุณได้ไหม มันค่อนข้างยากที่จะคาดเดาสิ่งที่ผิดปกติโดยไม่มีข้อมูลโค้ดใด ๆ
mwatzer

อย่างที่ฉันบอกไปฉันได้คัดลอกไฟล์ของคุณไปยังไฟล์ php ธรรมดาและมันทำให้ฉันมีข้อผิดพลาดนี้
LinusGeffarth

1
ตกลงตอนนี้ฉันเห็นปัญหา .. มันผิดในตัวอย่าง! คุณต้องโทร HTTPRequester :: HTTPPost () แทน HTTPRequester :: HTTPost ()
mwatzer

1
อา. คนนั้นง่ายที่จะพลาด ฉันได้อ่านความคิดเห็นของคุณเช่น 5x ก่อนที่ผมเห็นเป็นพิเศษP ขอบคุณ!
LinusGeffarth

19

อีกทางเลือกหนึ่งของวิธีการที่ไม่ใช้ขดตัวด้านบนนี้คือการใช้ฟังก์ชั่นสตรีมดั้งเดิม

  • stream_context_create():

    สร้างและส่งกลับบริบทการสตรีมด้วยตัวเลือกใด ๆ ที่ให้มาในตัวเลือกที่ตั้งไว้ล่วงหน้า

  • stream_get_contents():

    เหมือนกับfile_get_contents()ยกเว้นว่าstream_get_contents() ทำงานกับกระแสเปิดอยู่แล้วทรัพยากรและผลตอบแทนที่เหลือเนื้อหาในสตริงถึงmaxlengthไบต์และเริ่มต้นที่ระบุชดเชย

ฟังก์ชั่น POST ด้วยสิ่งเหล่านี้สามารถเป็นเช่นนี้:

<?php

function post_request($url, array $params) {
  $query_content = http_build_query($params);
  $fp = fopen($url, 'r', FALSE, // do not use_include_path
    stream_context_create([
    'http' => [
      'header'  => [ // header array does not need '\r\n'
        'Content-type: application/x-www-form-urlencoded',
        'Content-Length: ' . strlen($query_content)
      ],
      'method'  => 'POST',
      'content' => $query_content
    ]
  ]));
  if ($fp === FALSE) {
    return json_encode(['error' => 'Failed to get contents...']);
  }
  $result = stream_get_contents($fp); // no maxlength/offset
  fclose($fp);
  return $result;
}

1
วิธี CURL-less ใช้งานได้ดีสำหรับฉันในการตรวจสอบ reCAPTCHA จาก google คำตอบนี้มาบรรจบกับรหัส google นี้: github.com/google/recaptcha/blob/master/src/ReCaptcha/…
Xavi Montero

1
คุณไม่จำเป็นต้องใช้fclose()ถ้า$fpfalseเป็น เพราะfclose()คาดว่าทรัพยากรคือพารามิเตอร์
Floris

1
@ Floris แก้ไขได้ทันทีและแน่นอนfcloseเอกสารกล่าวถึง "ตัวชี้ไฟล์จะต้องถูกต้อง" ขอบคุณที่สังเกตว่า!
CPHPython

8

วิธีที่ดีกว่าในการส่งGETหรือPOSTการร้องขอมีPHPดังนี้:

<?php
    $r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
    $r->setOptions(array('cookies' => array('lang' => 'de')));
    $r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));

    try {
        echo $r->send()->getBody();
    } catch (HttpException $ex) {
        echo $ex;
    }
?>

รหัสนี้มาจากเอกสารอย่างเป็นทางการที่นี่http://docs.php.net/manual/da/httprequest.send.php


1
@ akinuri ขอบคุณสำหรับการเน้นฉันจะแบ่งปันใหม่
Imran Zahoor

วิธีทำบน PHP 5x?

@YumYumYum โปรดชำระเงินคำตอบของ dbau ด้านบนสำหรับ 5x ซึ่งใช้เทคนิคนี้php.net/manual/en/function.stream-context-create.php หรือคุณสามารถกลับไปที่วิธีแก้ปัญหามาตรฐานทั่วไป
Imran Zahoor

5

มีอีกหนึ่งที่คุณสามารถใช้

<?php
$fields = array(
    'name' => 'mike',
    'pass' => 'se_ret'
);
$files = array(
    array(
        'name' => 'uimg',
        'type' => 'image/jpeg',
        'file' => './profile.jpg',
    )
);

$response = http_post_fields("http://www.example.com/", $fields, $files);
?>

คลิกที่นี่เพื่อดูรายละเอียด


2
สิ่งนี้ขึ้นอยู่กับส่วนขยาย PECL ซึ่งส่วนใหญ่จะไม่ได้ติดตั้ง ไม่แน่ใจว่ายังคงมีอยู่เนื่องจากหน้าคู่มือถูกลบแล้ว
miken32

5

ฉันกำลังมองหาปัญหาที่คล้ายกันและพบวิธีที่ดีกว่าในการทำเช่นนี้ ดังนั้นที่นี่มันจะไป

คุณสามารถใส่บรรทัดต่อไปนี้ในหน้าการเปลี่ยนเส้นทาง (พูด page1.php)

header("Location: URL", TRUE, 307); // Replace URL with to be redirected URL, e.g. final.php

ฉันต้องการสิ่งนี้เพื่อเปลี่ยนเส้นทางคำขอ POST สำหรับการโทรREST API โซลูชันนี้สามารถเปลี่ยนเส้นทางด้วยข้อมูลการโพสต์เช่นเดียวกับค่าส่วนหัวที่กำหนดเอง

นี่คือการเชื่อมโยงการอ้างอิง


1
คำตอบนี้วิธีการเปลี่ยนเส้นทางการร้องขอหน้าเว็บไม่ได้ฉันจะส่งคำขอ POST กับ PHP? แน่นอนว่าสิ่งนี้จะส่งต่อพารามิเตอร์ POST ใด ๆ แต่นั่นไม่ใช่สิ่งเดียวกัน
Wesley Smith

@ DelightedD0D ขอโทษฉันไม่ได้รับความแตกต่างระหว่างVSredirect a page request with POST param send POST requestสำหรับฉันวัตถุประสงค์ของทั้งคู่เหมือนกันแก้ไขให้ฉันถ้าฉันผิด
Arindam Nayak

1
มีวิธีใดบ้างที่จะให้ฉันส่งพารามิเตอร์ด้วยวิธี POST แล้วอ่านเนื้อหาผ่าน PHP? OP ต้องการสคริปต์ php ของพวกเขาเพื่อสร้างชุดพารามิเตอร์ POST และส่งไปยังหน้า php อื่นและเพื่อให้สคริปต์รับผลลัพธ์จากหน้านั้น โซลูชันนี้จะยอมรับชุดของค่าที่โพสต์แล้วและส่งต่อไปยังหน้าอื่น พวกเขาแตกต่างกันค่อนข้าง
Wesley Smith

5

นี่คือการใช้เพียงคำสั่งเดียวโดยไม่มี cURL ง่ายสุด ๆ

echo file_get_contents('https://www.server.com', false, stream_context_create([
    'http' => [
        'method' => 'POST',
        'header'  => "Content-type: application/x-www-form-urlencoded",
        'content' => http_build_query([
            'key1' => 'Hello world!', 'key2' => 'second value'
        ])
    ]
]));

Key2 จะทำงานอย่างไร คั่นระหว่างพวกเขาคืออะไร?
มูฮัมหมัด Idrees

@ ล่าช้าเมื่อต้องการเพิ่ม key2 คุณสามารถป้อนมันเป็นรายการอาร์เรย์ที่สอง 'key1' => 'Hello world!', 'key2' => 'ค่าที่สอง'
Liga

มันใช้งานได้ดีมากเมื่อใช้กับ zapier
Moxet

3

ลองใช้แพ็คเกจHTTP_Request2ของ PEAR เพื่อส่งคำขอ POST ได้อย่างง่ายดาย หรือคุณสามารถใช้ฟังก์ชั่นม้วนงอของ PHP หรือใช้บริบทสตรีม PHPบริบทกระแส

HTTP_Request2 ยังทำให้เป็นไปได้ที่จะเยาะเย้ยเซิร์ฟเวอร์ดังนั้นคุณจึงสามารถทดสอบรหัสของคุณได้อย่างง่ายดาย


7
ฉันอยากเห็นคุณให้ทำอย่างละเอียดถ้าเป็นไปได้
Gui Imamura
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.