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

387

Может ли кто-нибудь показать мне, как сделать php curl с HTTP POST?

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

username=user1, password=passuser1, gender=1

To www.domain.com

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

Теги:
curl
http
http-post

11 ответов

634
Лучший ответ
<?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 { ... }
?>
  • 27
    нет необходимости использовать http_build_query() для обработки параметров; достаточно просто передать массив в CURLOPT_POSTFIELDS .
  • 4
    @Raptor, предоставляющий массив напрямую в CURLOPT_POSTFIELDS, фактически curl делает немного другой тип POST. (Ожидайте: 100-продолжение)
Показать ещё 5 комментариев
202

процедурный

// 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

// mutatis mutandis
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);). Поскольку это заставит ваш код работать, вы создадите огромную дыру в безопасности и дадите злоумышленникам возможность выполнять различные атаки на ваше приложение, такие как атака Man In The Middle или тому подобное.

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

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

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

  • 4
    Это действительно должен быть принятый ответ, потому что наилучшей практикой было бы позволить HTTP-библиотеке обрабатывать кодирование ваших переменных.
  • 4
    Это не всегда так. Я видел веб-серверы, которые ожидают, что переменные POST будут закодированы определенным образом, в противном случае они будут давать сбой. Мне кажется, что http_build_query () на самом деле более надежен, чем cURL для этого.
Показать ещё 6 комментариев
27

Живой пример использования 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>

Итак, вы сделали POST PHP на www.google.com и отправили ему некоторые данные.

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

  • 0
    $postvars .= $key . $value; должен $postvars .= $key . $value ."&"; или нет?
  • 0
    Посмотрев еще раз на этот ответ, вы также можете заменить свою собственную реализацию конвертера строки запроса на http_build_query , просто передайте ему массив $fields и он выведет строку запроса.
Показать ещё 3 комментария
19

До него легко достичь:

<?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);
7

Curl Post + Обработка ошибок + Установить заголовки [спасибо @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',
]);
  • 0
    Ваш код не закроет дескриптор и освободит ресурсы, потому что вы curl_close после создания исключения. Вы должны curl_close внутри блока finally.
6

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

  • 0
    Если вы хотите придерживаться стандартной curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); , попробуйте добавить curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  • 0
    Единственным недостатком является то, что вам все еще приходится иметь дело с установкой файла cookie и другими потенциальными проблемами (например, следует ли выполнять перенаправления, как обращаться с аутентификацией не на основе HTTP и т. Д.). Спустя 6 лет я бы порекомендовал более общую концепцию «безголового браузера» вместо этой конкретной библиотеки (или что-нибудь о sourceforge, как устарело, верно?) И хотя я обычно просто имею дело с опциями curl напрямую, я бы все же посоветовал глядя на библиотеку безголовых браузеров, которая совместима с PSR-7 (Guzzle - единственная, которую я знаю, не знаю), чтобы избежать головной боли.
4
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);
    $error = curl_error($ch);
    curl_close($ch);
    if ($error !== '') {
        throw new \Exception($error);
    }

    return $response;
}
  • 1
    Ваш код не закроет дескриптор и освободит ресурсы, потому что вы curl_close после создания исключения. Вы должны curl_close внутри блока finally .
  • 0
    Спасибо, исправил код. Вы хорошо разбираетесь в деталях;)
4

Вот несколько шаблонов для 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

Более простой ответ, если вы передаете информацию на свой собственный сайт, - это использовать переменную SESSION. Начать php-страницу с помощью:

session_start();

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

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

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

if (isset($_SESSION['message'])) {echo $_SESSION['message']; unset($_SESSION['message']);}
2

Если вы попытаетесь войти на сайт с помощью файлов 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

Пример кода cURL PHP для интеграции API Flickr

    # build the API URL to call

    $params = array(
        'api_key'   => '3bd4375728949f7d689ae85c5072b83a',
        'method'    => 'flickr.photos.getRecent',
        'format'    => 'php_serial',
        'per_page' => '5'
    );

    $encoded_params = array();

    foreach ($params as $k => $v){

        $encoded_params[] = urlencode($k).'='.urlencode($v);
    }

    # call the API and decode the response

    $url = "https://api.flickr.com/services/rest/?".implode('&', $encoded_params);

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    $rsp = curl_exec($ch); 
    curl_close($ch);

    $rsp_obj = unserialize($rsp);

    echo '<pre>';
    print_r($res_obj);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню