PHP + curl, пример кода HTTP POST?


Может ли кто-нибудь показать мне, как сделать php-завиток с помощью HTTP-СООБЩЕНИЯ?

Я хочу отправить данные следующим образом:

username=user1, password=passuser1, gender=1

К www.domain.com

Я ожидаю, что локон вернет ответ, подобный result=OK. Есть ли какие-нибудь примеры?

Author: Vladimir Kovpak, 2010-01-26

10 answers

<?php
//
// A very simple PHP example that sends a HTTP POST to a remote site
//

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,"http://www.example.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
            "postvar1=value1&postvar2=value2&postvar3=value3");

// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS, 
//          http_build_query(array('postvar1' => 'value1')));

// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$server_output = curl_exec($ch);

curl_close ($ch);

// Further processing ...
if ($server_output == "OK") { ... } else { ... }
?>
 625
Author: miku, 2018-08-07 07:50:19

Процедурный

// set post fields
$post = [
    'username' => 'user1',
    'password' => 'passuser1',
    'gender'   => 1,
];

$ch = curl_init('http://www.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

// execute!
$response = curl_exec($ch);

// close the connection, release resources used
curl_close($ch);

// do anything you want with your response
var_dump($response);

Объектно-ориентированный

<?php
namespace MyApp\Http;

class Curl
{
    /** @var resource cURL handle */
    private $ch;

    /** @var mixed The response */
    private $response = false;

    /**
     * @param string $url
     * @param array  $options
     */
    public function __construct($url, array $options = array())
    {
        $this->ch = curl_init($url);

        foreach ($options as $key => $val) {
            curl_setopt($this->ch, $key, $val);
        }

        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
    }

    /**
     * Get the response
     * @return string
     * @throws \RuntimeException On cURL error
     */
    public function getResponse()
    {
         if ($this->response) {
             return $this->response;
         }

        $response = curl_exec($this->ch);
        $error    = curl_error($this->ch);
        $errno    = curl_errno($this->ch);

        if (is_resource($this->ch)) {
            curl_close($this->ch);
        }

        if (0 !== $errno) {
            throw new \RuntimeException($error, $errno);
        }

        return $this->response = $response;
    }

    /**
     * Let echo out the response
     * @return string
     */
    public function __toString()
    {
        return $this->getResponse();
    }
}

// usage
$curl = new \MyApp\Http\Curl('http://www.example.com', array(
    CURLOPT_POSTFIELDS => array('username' => 'user1')
));

try {
    echo $curl;
} catch (\RuntimeException $ex) {
    die(sprintf('Http error %s with code %d', $ex->getMessage(), $ex->getCode()));
}

Примечание здесь: было бы лучше создать какой-то интерфейс с именем AdapterInterface, например, с помощью метода getResponse(), и позволить классу выше реализовать его. Затем вы всегда можете поменять эту реализацию на другой подобный адаптер без каких-либо побочных эффектов для вашего приложения.

Использование HTTPS/шифрование трафика

Обычно возникает проблема с cURL в PHP под операционной системой Windows. Пока при попытке подключиться к защищенной конечной точке https вы получите сообщение об ошибке, сообщающее вам, что certificate verify failed.

Что здесь делает большинство людей, так это говорит библиотеке cURL просто игнорировать ошибки сертификата и продолжать (curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);). Поскольку это заставит ваш код работать, вы создадите огромную дыру в безопасности и позволите злоумышленникам выполнять различные атаки на ваше приложение, такие как Атака "Человек посередине" или что-то в этом роде.

Никогда, никогда не делай этого. Вместо этого вам просто нужно изменить свой php.ini и сообщить PHP где ваш файл CA Certificate, чтобы он мог правильно проверять сертификаты:

; modify the absolute path to the cacert.pem file
curl.cainfo=c:\php\cacert.pem

Последнюю версию cacert.pem можно загрузить из Интернета или извлечь из вашего любимого браузера . При изменении любых php.ini связанных настроек не забудьте перезапустить свой веб-сервер.

 183
Author: emix, 2018-08-07 07:52:41

Живой пример использования php curl_exec для создания HTTP-сообщения:

Поместите это в файл под названием foobar.php :

<?php
  $ch = curl_init();
  $skipper = "luxury assault recreational vehicle";
  $fields = array( 'penguins'=>$skipper, 'bestpony'=>'rainbowdash');
  $postvars = '';
  foreach($fields as $key=>$value) {
    $postvars .= $key . "=" . $value . "&";
  }
  $url = "http://www.google.com";
  curl_setopt($ch,CURLOPT_URL,$url);
  curl_setopt($ch,CURLOPT_POST, 1);                //0 for a get request
  curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
  curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,3);
  curl_setopt($ch,CURLOPT_TIMEOUT, 20);
  $response = curl_exec($ch);
  print "curl response is:" . $response;
  curl_close ($ch);
?>

Затем запустите его с помощью команды php foobar.php, он выводит на экран такой вывод:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Title</title>

<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<body>
  A mountain of content...
</body>
</html>

Итак, вы сделали СООБЩЕНИЕ на PHP, чтобы www.google.com и отправил ему некоторые данные.

Если бы сервер был запрограммирован на чтение переменных post, он мог бы решить сделать что-то другое на основе этого.

 25
Author: Eric Leschinski, 2014-09-21 12:48:17

До него можно легко добраться с помощью:

<?php

$post = [
    'username' => 'user1',
    'password' => 'passuser1',
    'gender'   => 1,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.domain.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$response = curl_exec($ch);
var_export($response);
 18
Author: Vladimir Kovpak, 2015-06-16 05:45:33

Запись Curl + Обработка ошибок + Набор заголовков [благодаря @mantas-d]:

function curlPost($url, $data=NULL, $headers = NULL) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    if(!empty($data)){
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    if (!empty($headers)) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }

    $response = curl_exec($ch);

    if (curl_error($ch)) {
        trigger_error('Curl Error:' . curl_error($ch));
    }

    curl_close($ch);
    return $response;
}


curlPost('google.com', [
    'username' => 'admin',
    'password' => '12345',
]);
 5
Author: MSS, 2017-04-28 14:54:38

Если в форме используются перенаправления, аутентификация, файлы cookie, SSL (https) или что-либо еще, кроме полностью открытого сценария, ожидающего переменных POST, вы очень быстро начнете скрежетать зубами. Взгляните на Snoopy, который делает именно то, что вы имеете в виду, устраняя необходимость в настройке большого количества накладных расходов.

 5
Author: Anthony, 2018-03-29 15:37:40

Вот несколько стандартных кодов для PHP +curl http://www.webbotsspidersscreenscrapers.com/DSP_download.php

Включение в эти библиотеки упростит разработку

<?php
# Initialization
include("LIB_http.php");
include("LIB_parse.php");
$product_array=array();
$product_count=0;

# Download the target (store) web page
$target = "http://www.tellmewhenitchanges.com/buyair";
$web_page = http_get($target, "");
    ...
?>
 3
Author: Azi, 2013-10-10 08:41:58

Более простой ответ, ЕСЛИ вы передаете информацию на свой собственный веб-сайт, заключается в использовании переменной СЕАНСА. Начните страницу php с:

session_start();

Если в какой-то момент вы хотите сгенерировать информацию в PHP и передать ее на следующую страницу сеанса, вместо использования переменной POST назначьте ее переменной СЕАНСА. Пример:

$_SESSION['message']='www.'.$_GET['school'].'.edu was not found.  Please try again.'

Затем на следующей странице вы просто ссылаетесь на эту переменную СЕАНСА. ПРИМЕЧАНИЕ: после того, как вы его используете, убедитесь, что вы его уничтожили, чтобы он не сохранялся после него используется:

if (isset($_SESSION['message'])) {echo $_SESSION['message']; unset($_SESSION['message']);}
 2
Author: user2532795, 2013-06-28 17:52:41
curlPost('google.com', [
    'username' => 'admin',
    'password' => '12345',
]);


function curlPost($url, $data) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    $response = curl_exec($ch);
    if (curl_error($ch)) {
        throw new \Exception(curl_error($ch));
    }
    curl_close($ch);

    return $response;
}
 2
Author: Mantas D, 2018-03-30 06:43:57

Если вы попытаетесь войти на сайт с помощью файлов cookie.

Этот код:

if ($server_output == "OK") { ... } else { ... }

Может не сработать, если вы попытаетесь войти в систему, потому что многие сайты возвращают статус 200, но публикация не удалась.

Простой способ проверить, успешно ли сообщение о входе в систему, - это проверить, снова ли оно устанавливает файлы cookie. Если в выводе есть строка Set-Cookies, это означает, что сообщения не завершились успешно и начинается новый сеанс.

Также сообщение может быть успешным, но вместо этого статус может быть перенаправлен 200.

Чтобы убедиться, что сообщение успешно, попробуйте следующее:

Следуйте за местоположением после публикации, чтобы оно перешло на страницу, на которую перенаправляется сообщение:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

И затем проверьте, существуют ли новые файлы cookie в запросе:

if (!preg_match('/^Set-Cookie:\s*([^;]*)/mi', $server_output)) 

{echo 'post successful'; }

else { echo 'not successful'; }
 1
Author: Atanas Atanasov, 2018-01-17 10:02:31