Php 如何将http_post_data()重新编码为curl?

Php 如何将http_post_data()重新编码为curl?,php,curl,http-post,Php,Curl,Http Post,我有一个安装了curl的托管服务器,但没有安装http_post_data()pecl 我正在尝试将此(工作)http_post_data()代码转换为curl: $responseString = @http_post_data("http://" . $this->username . ":" . $this->password ."@" . $this->webserviceHost . $this->requestUriBase .$request, $r

我有一个安装了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);  
。。。失败:无法连接到主机


正确的代码是什么?

尝试从URL中删除用户名和密码,并使用不带括号的CURLOPT_USERPWD:

curl_setopt(CURLOPT_USERPWD, "$this->username:$this->password");

尝试从URL中删除用户名和密码,并使用不带括号的CURLOPT_USERPWD:

curl_setopt(CURLOPT_USERPWD, "$this->username:$this->password");

您的URL不应该包含用户名和密码-当您这样做时,curl将其解释为主机名的一部分

因此出现错误“无法连接到主机”


通过设置USERPWD选项包含身份验证信息,您已经完成了必要的操作。

您的URL不应该包含用户名和密码-当您这样做时,curl将其解释为主机名的一部分

因此出现错误“无法连接到主机”


通过设置USERPWD选项包括身份验证信息,您已经完成了必要的工作。

要配置和执行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
包含的内容。上面的设置很可能是错误的。看

编辑:您已通过以下方式指定它:

包含预编码post数据的字符串

Curl也支持这一点,只是不作为数组传递,而是作为字符串传递:

     CURLOPT_POSTFIELDS     => $requestString,

要配置和执行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
包含的内容。上面的设置很可能是错误的。看

编辑:您已通过以下方式指定它:

包含预编码post数据的字符串

Curl也支持这一点,只是不作为数组传递,而是作为字符串传递:

     CURLOPT_POSTFIELDS     => $requestString,

下面是一个函数,该函数应允许您在未修改的情况下使用现有代码:

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\u post\u data()
选项-也可以使用cURL实现其他功能,但我没有用不必要的实现来充实上述代码。If不会执行很多错误检查,特别是在验证提供的URL方面,因此您可能希望添加一些额外的清理


如果(!function_exists())将此函数包装在
中,以允许您将其放置在您的代码中并分发到任何地方。它不会与可用的本机函数发生冲突。

这里有一个函数,允许您不经修改地使用现有代码:

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\u post\u data()
选项-也可以使用cURL实现其他功能,但我没有用不必要的实现来充实上述代码。If不会执行很多错误检查,特别是在验证提供的URL方面,因此您可能希望添加一些额外的清理



如果(!function_exists())
将此函数包装在
中,以允许您将其放置在您的代码中并分发到任何地方。它不会与可用的本机函数发生冲突。

对于测试,简化它,只需使用CURLOPT_RETURNTRANSFER对页面进行请求,看看是否至少达到了这一步。我添加了CURLOPT_RETURNTRANSFER(这就是为什么我得到“无法连接到主机”),或者简化是什么意思?
curl\u setopt
有一个返回值。如果为
FALSE
,则设置失败。您应该通过检查返回值来检查所有设置是否有效。谢谢。这把坏了,我想钥匙丢了。你知道为什么吗?http_post_数据不需要密钥。curl_setopt($this->curl,CURLOPT_POSTFIELDS,array($requestString));啊,这也是我在下面的回答中假设的。请参见此处以获取提示。对于测试,请简化它,然后使用CURLOPT_RETURNTRANSFER向页面发出请求,看看您是否至少达到了这一步。我添加了CURLOPT_RETURNTRANSFER(这就是为什么我得到“无法连接到主机”),或者简化是什么意思?
curl_setopt
有一个返回值。如果为
FALSE
,则设置失败。您应该通过检查返回值来检查所有设置是否有效。谢谢。这把坏了,我想钥匙丢了。你知道为什么吗?http_post_数据不需要密钥。curl_setopt($this->curl,CURLOPT_POSTFIELDS,array($requestString));啊,这也是我在下面的回答中假设的。请看这里的提示。非常感谢您的帮助。不幸的是,这段代码(添加了对curl作为第一个参数的引用)也不起作用。非常感谢您的帮助。不幸的是,这段代码(添加了对curl的引用作为第一个参数)也不起作用。我已经测试过了,但它不起作用:($url=“http://”$this->webserviceHost.$this->requestUriBase.$request;我已经测试过了,但它不起作用:($url=“http://”.$this->webserviceHost.$this->requestUriBase.$request;首先,我要感谢大家的努力。由于您的函数返回false,我开始认为我的服务器可能被防火墙或类似的东西阻止。是否可以对此进行测试?查看错误消息会很有用,您应该确保删除ny
@
从函数调用中抑制错误,并将错误报告设置为最大值(
ini_set('display_errors',1);错误报告(E_STRICT | E_ALL);
)还可以查看
curl_error($ch)
显示的内容,并添加
print_r(curl_getinfo($ch))的输出
这个问题可能会有帮助……谢谢,这现在确实起作用了:我已经获得了对原始服务器的访问权限,并且脚本在那里工作。因此,