diff --git a/README.md b/README.md index 5ad1832..1644237 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,7 @@ Curl::setDigestAuthentication($username, $password = '') Curl::setHeader($key, $value) Curl::setJsonDecoder($function) Curl::setOpt($option, $value) +Curl::setOpts($options) Curl::setPort($port) Curl::setReferer($referer) Curl::setReferrer($referrer) @@ -225,8 +226,8 @@ Curl::setUserAgent($user_agent) Curl::setXmlDecoder($function) Curl::success($callback) Curl::unsetHeader($key) -Curl::verbose($on = true, $output=STDERR) -Curl::http_build_multi_query($data, $key = null) +Curl::verbose($on = true, $output = STDERR) +Curl::array_flatten_multidim($array, $prefix = false) Curl::is_array_assoc($array) Curl::is_array_multidim($array) MultiCurl::__construct($base_url = null) diff --git a/src/Curl/Curl.php b/src/Curl/Curl.php index 6ab15d3..e311ed8 100644 --- a/src/Curl/Curl.php +++ b/src/Curl/Curl.php @@ -892,8 +892,30 @@ class Curl trigger_error($required_options[$option] . ' is a required option', E_USER_WARNING); } - $this->options[$option] = $value; - return curl_setopt($this->curl, $option, $value); + $success = curl_setopt($this->curl, $option, $value); + if ($success) { + $this->options[$option] = $value; + } + return $success; + } + + /** + * Set Opts + * + * @access public + * @param $options + * + * @return boolean + * Returns true if all options were successfully set. If an option could not be successfully set, false is + * immediately returned, ignoring any future options in the options array. Similar to curl_setopt_array(). + */ + public function setOpts($options) + { + foreach ($options as $option => $value) { + if (!$this->setOpt($option, $value)) { + return false; + } + } } /** @@ -1198,7 +1220,8 @@ class Curl * * @return array */ - public static function array_flatten_multidim($array, $prefix = false) { + public static function array_flatten_multidim($array, $prefix = false) + { $return = array(); if (is_array($array) || is_object($array)) { if (empty($array)) { diff --git a/tests/PHPCurlClass/PHPCurlClassTest.php b/tests/PHPCurlClass/PHPCurlClassTest.php index 3d7bc84..309518c 100644 --- a/tests/PHPCurlClass/PHPCurlClassTest.php +++ b/tests/PHPCurlClass/PHPCurlClassTest.php @@ -2754,4 +2754,57 @@ class CurlTest extends PHPUnit_Framework_TestCase $test->server('request_method', 'GET'); $this->assertTrue(is_float($test->curl->totalTime)); } + + public function testOptionSet() + { + // Skip this test on 5.3, 5.4, and HHVM. + if (version_compare(PHP_VERSION, '5.5.0', '<') || defined('HHVM_VERSION')) { + return; + } + + $option = CURLOPT_ENCODING; + $value = 'gzip'; + $null = chr(0); + + // Ensure the option is stored when curl_setopt() succeeds. + $curl = new Curl(); + $success = $curl->setOpt($option, $value); + + $reflector = new ReflectionObject($curl); + $property = $reflector->getProperty('options'); + $property->setAccessible(true); + $options = $property->getValue($curl); + + $this->assertTrue($success); + $this->assertTrue(isset($options[$option])); + $this->assertEquals($value, $options[$option]); + + // Ensure the option is not stored when curl_setopt() fails. Make curl_setopt() return false and suppress + // errors. Triggers warning: "curl_setopt(): Curl option contains invalid characters (\0)". + $curl = new Curl(); + $success = @$curl->setOpt($option, $null); + + $reflector = new ReflectionObject($curl); + $property = $reflector->getProperty('options'); + $property->setAccessible(true); + $options = $property->getValue($curl); + + $this->assertFalse($success); + $this->assertFalse(isset($options[$option])); + + // Ensure options following a Curl::setOpt() failure are not set when using Curl::setOpts(). + $options = array( + $option => $null, + CURLOPT_COOKIE => 'a=b', + ); + $curl = new Curl(); + @$curl->setOpts($options); + + $reflector = new ReflectionObject($curl); + $property = $reflector->getProperty('options'); + $property->setAccessible(true); + $options = $property->getValue($curl); + + $this->assertFalse(isset($options[CURLOPT_COOKIE])); + } }