Open 0xearl opened 1 year ago
curl_setopt_array
is equivalent to a foreach loop that calls curl_setopt
. There is something else responsible for the problems you're seeing...
I'm honestly confused myself, that's the whole code.
Not sure what all I can tell you, other than this problem doesn't make sense.
What does var_dump($options)
show? Are you sure the script (the entire file) is exactly as you've posted, with the output exactly as you've posted, and using exactly PHP 8.1.6 and/or 8.1.12? And it does so when you run php -n file.php
, which guarantees there's no custom configuration being loaded like extensions or an auto_prepend_file?
Running php -n file.php
returns Fatal error: Uncaught Error: Call to undefined function curl_init()
var_dump($options)
shows
array(4) {
[10002]=>
string(18) "https://google.com"
[244]=>
bool(true)
[53]=>
bool(false)
[19913]=>
bool(true)
}
Yes I have tested both 8.1.6 and 8.1.12
Ah, right, yeah -n will totally disable ext/curl as well. Ahem.
So what I meant was php -n -d extension=curl file.php
.
running php -n -d extension=curl file.php
returns bool(false)
@0xearl Can you run the following code with the configuration from the beginning? We should see what is the actual version of the curl, which features are compiled in, if setopt was even successful and eventual error messages.
<?php
error_reporting(-1);
ini_set('display_errors', '1');
var_dump(curl_version());
echo "\ncurl_setopt_array\n";
$ch = curl_init();
$options = [CURLOPT_URL => 'https://google.com', CURLOPT_TCP_FASTOPEN => true, CURLOPT_TRANSFERTEXT => false, CURLOPT_RETURNTRANSFER => true];
var_dump(curl_setopt_array($ch, $options));
var_dump(curl_error($ch));
$res = curl_exec($ch);
var_dump($res, curl_error($ch));
curl_close($ch);
echo "\ncurl_setopt\n";
$ch = curl_init();
foreach ($options as $key => $value) {
var_dump(curl_setopt($ch, $key, $value));
}
$res = curl_exec($ch);
var_dump($res, curl_error($ch));
curl_close($ch);
@KapitanOczywisty running your code returns
array(16) {
["version_number"]=>
int(478464)
["age"]=>
int(9)
["features"]=>
int(288165789)
["ssl_version_number"]=>
int(0)
["version"]=>
string(6) "7.77.0"
["host"]=>
string(15) "x86_64-pc-win32"
["ssl_version"]=>
string(14) "OpenSSL/1.1.1n"
["libz_version"]=>
string(6) "1.2.12"
["protocols"]=>
array(24) {
[0]=>
string(4) "dict"
[1]=>
string(4) "file"
[2]=>
string(3) "ftp"
[3]=>
string(4) "ftps"
[4]=>
string(6) "gopher"
[5]=>
string(7) "gophers"
[6]=>
string(4) "http"
[7]=>
string(5) "https"
[8]=>
string(4) "imap"
[9]=>
string(5) "imaps"
[10]=>
string(4) "ldap"
[11]=>
string(5) "ldaps"
[12]=>
string(4) "mqtt"
[13]=>
string(4) "pop3"
[14]=>
string(5) "pop3s"
[15]=>
string(4) "rtsp"
[16]=>
string(3) "scp"
[17]=>
string(4) "sftp"
[18]=>
string(3) "smb"
[19]=>
string(4) "smbs"
[20]=>
string(4) "smtp"
[21]=>
string(5) "smtps"
[22]=>
string(6) "telnet"
[23]=>
string(4) "tftp"
}
["ares"]=>
string(0) ""
["ares_num"]=>
int(0)
["libidn"]=>
string(0) ""
["iconv_ver_num"]=>
int(0)
["libssh_version"]=>
string(14) "libssh2/1.10.0"
["brotli_ver_num"]=>
int(0)
["brotli_version"]=>
string(0) ""
}
curl_setopt_array
bool(false)
string(0) ""
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>
bool(true)
string(0) ""
curl_setopt
bool(true)
bool(false)
bool(true)
bool(true)
string(220) "<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>
"
string(0) ""
reading https://www.php.net/manual/en/function.curl-setopt-array.php
it seems like curl_setopt_array is failing to set CURLOPT_TCP_FASTOPEN => true,
and is returning false
hence the next curl options are not being set.
I'm not sure as to why curl_setopt_array is failing to set CURLOPT_TCP_FASTOPEN
Seems like it's not supported on windows: https://curl.se/libcurl/c/CURLOPT_TCP_FASTOPEN.html
I see, thanks @KapitanOczywisty
I think there should be a warning when curl_setopt_array
is failing on the libcurl side. TBH it's too easy to miss such error.
it didn't even error out @KapitanOczywisty even with var_dump($res, curl_error($ch));
it didn't even error out @KapitanOczywisty even with
var_dump($res, curl_error($ch));
Indeed. That is because curl_error()
is implemented via CURLOPT_ERRORBUFFER
and as such does not apply to curl_easy_setopt()
(i.e. when setting options). That needs to be clarified in the documentation.
You can, however, use curl_errno()
(and curl_strerror()
):
<?php
$ch = curl_init();
$options = [
CURLOPT_URL => 'https://google.com',
CURLOPT_TCP_FASTOPEN => true,
CURLOPT_TRANSFERTEXT => false,
CURLOPT_RETURNTRANSFER => true
];
curl_setopt_array($ch, $options);
var_dump($errno = curl_errno($ch), curl_strerror($errno));
outputs:
int(4)
string(108) "A requested feature, protocol or option was not found built-in in this libcurl due to a build-time decision."
I think there should be a warning when
curl_setopt_array
is failing on the libcurl side. TBH it's too easy to miss such error.
I agree that this might be a good idea, but given the potential BC break, I don't think that we should see this as bug fix, but rather as a feature.
Description
The following code:
When using curl_setopt_array to set CURLOPT_RETURNTRANSFER it returns the result and bool. I was able to fix this by adding
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
Resulted in this output:
But I expected this output instead:
PHP Version
8.1.6 & 8.1.12
Operating System
Windows 10