Как перекодировать http_post_data (), чтобы свернуться? - PullRequest
0 голосов
/ 12 марта 2012

У меня есть хост-сервер с установленным curl, но не http_post_data () pecl.

Я пытаюсь перевести этот (рабочий) код http_post_data () в curl:

$responseString = @http_post_data("http://" . $this->username . ":" . $this->password ."@" . $this->webserviceHost . $this->requestUriBase .$request,
    $requestString,
    array('http_auth' => $this->username . ":" . $this->password, 'headers' => array('Content-Type' => 'text/xml')));

Я пробовал:

$url = "http://" . $this->username . ":" . $this->password ."@" . $this->webserviceHost . $this->requestUriBase .$request;
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Accept: application/xml', 'Content-Type: application/xml'));
        curl_setopt($this->curl, CURLOPT_URL, $url);
        curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt(CURLOPT_USERPWD, "[$this->username]:[$this->password]");
        curl_setopt ($this->curl, CURLOPT_POST, true);
        curl_setopt ($this->curl, CURLOPT_POSTFIELDS, array($requestString));
        $content = curl_exec($this->curl);  

... и не удалось: не удалось подключиться к хосту

Какой правильный код?

Ответы [ 4 ]

2 голосов
/ 12 марта 2012

Вот функция, которая должна позволять вам использовать существующий код без изменений:

if (!function_exists('http_post_data')) {
  function http_post_data ($url, $data, $options) {

    // Construct the URL with the auth stripped out
    $urlParts = parse_url($url);
    $urlToUse = $urlParts['scheme'].'://'.$urlParts['host'];
    if (isset($urlParts['port'])) $urlToUse .= ':'.$urlParts['port'];
    $urlToUse .= $urlParts['path'];
    if (isset($urlParts['query'])) $urlToUse .= '?'.$urlParts['query'];

    // Convert headers to a format cURL will like
    $headers = array();
    if (isset($options['headers'])) {
      foreach ($options['headers'] as $name => $val) {
        $headers[] = "$name: $val";
      }
    }

    // Initialise cURL with the modified URL
    $ch = curl_init($urlToUse);

    // We want the function to return the response as a string
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);

    // Set the method to POST and set the body data
    curl_setopt ($ch, CURLOPT_POST, TRUE);
    curl_setopt ($ch, CURLOPT_POSTFIELDS, $data); // Wrapping this in an array() is definitely wrong, given that the content-type is xml

    // Set the auth details if specified
    if (isset($urlParts['user'], $urlParts['pass'])) {
      curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); // It's probably best to allow any auth method, unless you know the server ONLY supports basic
      curl_setopt($ch, CURLOPT_USERPWD, $urlParts['user'].':'.$urlParts['pass']); // The square brackets are not required and will be treated as part of the username/password
    }

    // Set any extra headers
    if ($headers) {
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }

    // Send the request and return the result:
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;

  }
}

Эта функция реализует только те опции для http_post_data(), которые вы использовали в исходном коде - она ​​будетМожно было бы реализовать и другие функции с использованием cURL, но я не раздул приведенный выше код с их ненужными реализациями.Если проверка ошибок не выполняется, особенно с точки зрения проверки предоставленного URL, возможно, вы захотите добавить дополнительную очистку.

Эта функция заключена в if (!function_exists()), чтобы вы могли разместить ее в своем коде.и распространяться где угодно.Он не будет вступать в конфликт с нативной функцией, где он доступен.

1 голос
/ 12 марта 2012

Чтобы настроить и выполнить запрос CURL, я предлагаю следующий формат:

    # in curl URL is scheme://hostname/rest, and hostname != authority
    #     (authority is hostname plus port and with user/pass in front)

    $url = sprintf('http://%s/%s', $this->webserviceHost
                    , $this->requestUriBase . $request);
    $options = array(
         CURLOPT_HTTPHEADER     => array(
             'Accept: application/xml', 
             'Content-Type: application/xml',
         ),
         CURLOPT_HTTPAUTH       => CURLAUTH_BASIC,
         # don't use the brackets []
         CURLOPT_USERPWD        => $this->username . ':' . $this->password,
         CURLOPT_POST           => TRUE,
         CURLOPT_POSTFIELDS     => $requestString,
         CURLOPT_RETURNTRANSFER => TRUE,
    );

    $this->curl = curl_init($url);
    $r = curl_ setopt_ array($this->curl, $options);
    if (!$r) throw new Exception('Failed to setup options.');
    $content = curl_exec($this->curl); # This needs CURLOPT_RETURNTRANSFER => TRUE

Я не уверен насчет CURLOPT_POSTFIELDS, потому что вы не указали, что содержит $requestString,Вполне вероятно, что этот параметр выше неправильный.См. curl POST формат для CURLOPT_POSTFIELDS .

Редактировать: Вы указали его с помощью http_post_data:

Строка, содержащая предварительно закодированные данные поста

Curl также поддерживает это, просто не передавайте как массив, передавайте его как строку:

     CURLOPT_POSTFIELDS     => $requestString,
0 голосов
/ 12 марта 2012

Ваш URL не должен содержать имя пользователя и пароль - когда вы делаете это, curl интерпретирует его как часть имени хоста.

Следовательно, ошибка "не удалось подключиться к хосту".

вы уже делаете необходимое, включив информацию для аутентификации, установив опцию USERPWD.

0 голосов
/ 12 марта 2012

Попробуйте удалить имя пользователя и пароль из URL-адреса и использовать CURLOPT_USERPWD без скобок:

curl_setopt(CURLOPT_USERPWD, "$this->username:$this->password");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...