php-mod / curl Goto Github PK
View Code? Open in Web Editor NEWThis library provides an object-oriented and dependency free wrapper of the PHP cURL extension.
License: MIT License
This library provides an object-oriented and dependency free wrapper of the PHP cURL extension.
License: MIT License
Hi, is there a reason why "setopt" is used in all examples (being all-lowercase function name), but in the code the function is "setOpt"?
Function names are case insensitive, but it kinda stinks. To fix this, should the examples be changed to camelCase, or should the function name be changed to all lowercase?
Docblock to post():
/**
* Make a post request with optional post data.
*
* @param string $url The url to make the post request
* @param array $data Post data to pass to the url
* @param boolean $asJson Whether the data should be passed as json or not. {@insce 2.2.1}
* @return self
*/
but then preparePayload accepts
/**
* @param array|object|string $data
*/
for $data. Can we update post() with this signature too? Right now, Psalm shows an error because of it.
I'm trying to figure out how to do this CURL command:
curl https://uploads.stripe.com/v1/files
-u sk_test_OCHANGEDPcDr0:
-F purpose=identity_document
-F file="@/path/to/a/file.jpg"
With this PHP script? What would be the equivalent PHP command?
Verbose mode is not working because of $this->setOpt(CURLINFO_HEADER_OUT, true); in init function.
even if you will try to set to false verbose will not work. you must not set it at all if you need verbose output.
just want to know if it works with php 5.2?
Hello
How to authenticate with the Bearer method ?
I was wondering could you change some permissions for class methods and attributes?
For example, private curl
property at Client
class to protected curl
?
There are a lot of any class members that are desired to be changed.
Current permission model makes your classes completely not extendable.
It would be nice to have some more getters, so I don't depend on the object properties, and also mock this lib properly in my projects.
For tests, it's cleaner to mock methods than just setting the $curl->response
property, for example.
The following getters would be appreciated:
public function getResponse(); // Returns response prop
public function getErrorCode(); // Returns curl_error_code prop
public function getErrorMessage(); // Returns curl_error_message prop
public function getHttpStatus(); // Returns http_status_code prop
Of course I could build a wrapper for this, but then I'd have two dependencies for something as simple as making a request.
when i run it on php cli mode,Memory overflow ! because the object method \Curl\Curl::__destruct()never run. i have to call method \CurlCurl::_close() on every curl request.
Hi, I use:
$curl->post($curlUrl, $data2send);
if ($curl->error) {
///
}
BUt SENTRY is returning a bug:
Unhandled
Warning: curl_error(): supplied resource is not a valid cURL handle resource
ErrorException
Warning: curl_setopt(): supplied resource is not a valid cURL handle resource
What could it be?
In version 2, you force post data to be array. That prevents you from sanding raw json post requests. I guess that CURLOPT_POSTFIELDS can also take string values.
POSTing files does not work as intended.
This is what I'd like to do:
$file = new \CURLFile($filePath, mime_content_type($filePath), 'file_post_name');
$data = array(
'mode' => 'import',
'file' => $file,
);
$this->curl->setHeader('Accept', 'application/json');
$this->curl->setHeader('Content-Type', 'application/json');
$this->curl->post('http://example.com', $data);
$this->curl->close();
However what is posted is a string representation of the data, including the CURLFile instance, not the actual file. I.e:
mode=import&file%5Bname%5D=path/to/file/&file%5Bmime%5D=mime_type_of_file&file%5Bpostname%5D=file_post_name
This is due to the preparePayload
method - that runs http_build_query
on the data. If I remove those lines everything works as expected.
The library should include a way to skip http_build_query
, or a special method for adding a file to the posted data.
Thanks
Remove the methods which are marked as deprectated.
Hello!
I have no prior knowledge of PHP and I was handed down a project made entirely out of PHP.
My issue is that whenever I try to run my project, I receive the following error:
Fatal error: Class 'Curl\Curl' not found in /Users/jayanpatel/Desktop/Clickstream-Generator/mainstream//rrapi.php on line 74
This what it looks like in line 74:
$curl = new Curl\Curl();
And this is what I have in the composer.json:
Can you please help a beginner in PHP understand what is going on and how to solve this issue?
Thanks!
J.
see https://github.com/php-mod/curl/blob/1.9.0/src/Curl/Curl.php#L668
composer.json still claims compatibility with 5.3 tho.
I am using this class for doing SFTP upload/download (i have found that curl is the most reliable method of doing this as opposed to other methods within PHP. Which on some servers seem to have issues.Since i am not using any standard put/delete/get I am using _exec. Can we not deprecate this function?
Deprecated: strtolower(): Passing null to parameter #1 ($string) of type string is deprecated in ...\vendor\curl\curl\src\Curl\Curl.php on line 713
This issue expands on issue #65, which noted a memory issue. This is an explanation for the memory leak and why the suggested unset()
won't fix it. Additionally, the original poster's solution of manually calling close()
won't prevent the memory leak in PHP8+.
Minimum reproducible code:
$curl = new Curl\Curl();
unset($curl); // destructor not called; object still in memory
In short, the destructor is never being called. Even if you manually unset()
the object, the destructor will not be called. This means the object is never garbage collected, the curl resource is never closed, and the memory is never cleaned up, until the end of the script.
From the PHP manual:
The destructor method will be called as soon as there are no other references to a particular object...
The reason the destructor is not called is because there is a circular reference between the Curl object and the underlying curl resource. The Curl constructor calls the init()
function, and the init()
function has this line:
$this->setOpt(CURLOPT_HEADERFUNCTION, array($this, 'addResponseHeaderLine'));
The Curl object has a reference to the curl resource, and now, because of that line, the curl resource has a reference to the Curl object.
Therefore, when you call unset($curl)
in the code above, the variable will be unset, but the object will not actually be destroyed because the curl resource still has a reference to it.
This is why manually calling the close()
method removes the memory leak (at least before PHP8). When the close()
method is called, it closes the curl resource, which removes the reference to the Curl object, leaving the only reference being the one we created. Therefore, when we unset our reference (or our reference goes out of scope), there will be no more references and the object can be destroyed.
However, this is not true in PHP8. From the PHP8 migration guide:
curl_init() will now return a CurlHandle object rather than a resource. The curl_close() function no longer has an effect, instead the CurlHandle instance is automatically destroyed if it is no longer referenced.
In PHP8, the curl functions were changed to operate on a CurlHandle object instead of a curl resource. Additionally, the curl_close()
function was updated to have no effect. Therefore, in PHP8, manually calling the close()
method will not resolve the memory leak because it doesn't actually do anything. The circular reference between the Curl object and the CurlHandle object will still exist.
The easiest solution would be to remove the line from the init()
function and add it into the exec()
function, so you can set it before the curl request and then unset it after the curl request:
$this->setOpt(CURLOPT_HEADERFUNCTION, array($this, 'addResponseHeaderLine'));
$this->response = curl_exec($this->curl);
$this->setOpt(CURLOPT_HEADERFUNCTION, null);
Thanks,
Patrick
in src/Curl/Curl.php, line 162
Method names should be declared in
camelCase
. You should rename this method to comply with PSR-1.
$this->response_headers = null;
$this->response = null;
$this->init();
}
public function _exec()
{
$this->response = curl_exec($this->curl);
$this->curl_error_code = curl_errno($this->curl);
$this->curl_error_message = curl_error($this->curl);
$this->curl_error = !($this->curl_error_code === 0);
Posted from SensioLabsInsight
What's the proper method to set parameters on when attempting to emulate
“application/x-www-form-urlencoded”
Is there such a built in helper method? I don't see anything in Curl main class.
Hi
I was testing your code and I found a problem.
Basically, I amb using GET with multiple parameters:
$client->get($method_url, $data);
where data is some like:
$data = array("module_id" => 1, "module_instance" => 2)
When I call to get the built URL is:
HTTP GET /api/course/87/activity/?module_id=1&module_instance=2
But the REST API should get:
HTTP GET /api/course/87/activity/?module_id=1&module_instance=2
It looks like a problem with:
http_build_query($data)
When I change with:
str_replace("&","&",http_build_query($data,"&"))
It works
Can you help me to understand my error?
Thanks!!
Line 189 in 4c7cbc6
trim( string $str[, string $character_mask = " \t\n\r\0\x0B"] )
I am using this class to integrate my REST API, now I get to the problem, that my application expects the data, which gets sent through PUT, to update an ressource in the content-body of the Request. (Using Symfony2 HTTP Components to parse Request)
As the RFC (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) indicates that the "enclosed entity" should be saved at the given URI, I would guess it should be within the Request body. It also states, that the "fundamental difference between the POST and PUT" methods are, that POST creates a new entity stored at the given endpoint and PUT updates the entity the URI points at.
Last-but-not-least I will reference to http://www.restapitutorial.com/lessons/httpmethods.html which also states, that the entity should be within the request body.
Am I wrong somewhere and Curl already does this in the background and the "fail" is on my side? As in the current implementation you append the data to the URI with http_build_query.
Hi I followed your tutorial and tried to call $curl = new Curl\Curl(); in my controller but this error Class 'App\Http\Controllers\Curl\Curl' not found appears. Did I miss something? Thanks
When a server responses with more than one HTTP/1.1 100 Continue
message, the header array contains only the second HTTP/1.1 100 Continue
message and the actual headers are part of the response body.
One solution is to change the corresponding if-condition to a while-loop.
I'll make a pull request to solve this issue.
I would suggest to automatically set header Content-type: application/json
when calling prepareJsonPayload
. Typically when doing post as json.
What do you think? I could prepare PR for this change.
Nice to see this library is covered with Travis. Would it be possible to add a build badge to the README for this?
Looks like some fixing is necessary anyway - PHP 7 and HHVM builds are broken presently.
There is a useful http method missing!
Curl.php doesn't set CURLOPT_CONNECTTIMEOUT
private function init()
{
$this->curl = curl_init();
$this->setUserAgent(self::USER_AGENT);
$this->setOpt(CURLINFO_HEADER_OUT, true);
$this->setOpt(CURLOPT_HEADER, true);
$this->setOpt(CURLOPT_RETURNTRANSFER, true);
return $this;
}
My code like follow
use Curl\Curl;
$curl = new Curl();
for($i=1;i<200;$i++){
$res = json_decode($curl->get('api url' . $i)->response);
$data = $res->data;
}
So $data
isn't sure that get data from $res
,because the $res
may be a null
, and $data = $res ->data
may repote errors.
Can you please add PHPDoc-Documentation.
Thank you.
Does this support multi curl? (Asynchronous)
I'm using curl in my stripe webhook. When a payment if complete, my function will run a curl to pull data from an api URL. here is my curl code
$curl = new Curl();
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, (YII_ENV == 'dev') ? false : true);
$curl->setOpt(CURLOPT_SSL_VERIFYHOST, (YII_ENV == 'dev') ? false : 2);
//$curl->setOpt(CURLOPT_RETURNTRANSFER, false);
//$curl->setOpt(CURLOPT_URL, $apiURL);
$curl->get($apiURL);
if ($curl->error) {
Yii::error($curl->errorMessage);
die;
} else {
$response = $curl->response;
}
In general the code works fine, but once in a while it will pull data from $apiURL
twice. Any idea how to fix this, or prevent it? Thanks.
in version 2.2.0
in the src agent still tells it is 1.9
const USER_AGENT = 'PHP Curl/1.9 (+https://github.com/php-mod/curl)';
It is not a bug, however, when I tail logs I wanted to check if it updated correctly but it cannot be checked by this. Maybe it just need a change to
const USER_AGENT = 'PHP Curl/2.0 (+https://github.com/php-mod/curl)';
Also just to confirm, no breaking changes were made (except for php 5.5 removal of course) when transitioning from 1.* to 2.* ? Will nothing breaking gonna be changed continuing with 2.* ? I would suggest jump to 3.* if something breaking gonna be done. Let me know if there is something I need to keep an eye out.
Thanks :)
The library provides to many error message properties. They need either a better documentation or we should provide the user an error message function which returns the right message. The following error message properties are available:
I assume that error_message
contains the what users are looking for, either its a curl error or a http request error but there is also getErrorMessage()
which is equals to curl_error_message
.
What could we do to improve the developer experience?
This file ends with no newline character. It won't render properly on a terminal, and it's considered a bad practice. Add a simple line feed as the last character to fix it.
<testsuite name="PHP MP4Box Tests Suite"><directory>tests</directory></testsuite></testsuites></phpunit>
Posted from SensioLabsInsight
I passed following data to post method.
array(4) {
["amount"]=>
int(900)
["currency"]=>
string(3) "JPY"
["card"]=>
string(28) "tok_SMJhkoibbHr9CYsv2wwcZ1Ik"
["capture"]=>
bool(false)
}
However the value of capture
is changed from false
to 0
.
string(67) "amount=900¤cy=JPY&card=tok_SMJhkoibbHr9CYsv2wwcZ1Ik&capture=0"
This is caused http_build_query
inside of post method.
https://github.com/php-mod/curl/blob/master/src/Curl/Curl.php#L60
This case of scenario is missing in test cases.
Let's say you have a page that just echo or dies a response. For example, echo "hi" or die("hi");
Using syntax like this:
if ($curl->error) {
echo $curl->error_code;
} else {
if ($curl->response === "hi") {
echo "response worked";
}
}
I am unable to get "response worked" no matter what. Even though echo $curl->response returns "hi" just fine. I var_dump'ed it and difference is that it has different size string but still it should work because it is same type (hence triple equals). Doesn't work with double equals too. I got it work by checking if it contains "hi" and that seems to work but it seems to be a bit excessive.
Am I doing something wrong?
@amouhzi We should change or remove php version restrictions, since php 8 has been released.
https://github.com/php-mod/curl/blob/master/composer.json#L24
I have noticed that the constructor throws an ErrorException and the IDE always marks the warning that the Exception is not captured, so I propose to change it for RuntimeException since the dependency of the library is in execution time and not process.
I got the problem, that your Curl class can't handle multidimensional arrays for certain methods - data (and maybe all others that use the POSTFIELDS).
$curl = new Curl();
$curl->patch('some-endpoint', ['multi'=>['dimensional' => ['data'] => 'payload']]);
This will throw an error, that string was excepted but got array, so it did an Array=>string conversion.
The correct usage would be to use http_build_query on the POSTFIELDS data so it will get converted into the correct scheme and won't raise an error anymore.
Currently it would create an request with the following "payload"
multi=Array
But it would be more correct to have the request body:
multi[dimensional][data]=payload
EDIT: Just saw that POST already does this, but patch for example, does not.
how do you set the Curl body on put? I want to send a json body as part of my request to the endpoint and I don't see an "setBody" option of sorts.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.