Viewed   106 times

Other people have already asked how to do this from perl, java, bash, etc. but I need to do it in PHP, and I don't see any question already asked relating specifically to (or with answers for) PHP.

My code:

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);

This doesn't work. The destination site has print_r($_GET); print_r($_POST);, so when I examine the $result I should be able to see the fields that are being sent. However, the $_POST array is empty - I only see the get variables. If I remove the ?... query string from the $url, then the POST array is populated correctly. But now I don't have the GET params. How do I do this?

My specific case is, I need to send too much data to fit it in the query string, but I can't send it all as POST because the site I want to submit to is selecting a handler for the posted data based on a variable in the GET string. I can try and have that changed, but ideally I would like to be able to send both get and post data in the same query.


# GET query goes in the URL you're hitting
$ch = curl_init('');
# POST fields go here.
curl_setopt($ch, CURLOPT_POSTFIELDS, array('post' => 'parameter', 'values' => 'go here'));

PHP itself wouldn't decide to ignore the GET parameters if a POST is performed. It'll populate $_GET regardless of what kind of http verb was used to load the page - if there's query parameters in the URL, they'll go into $_GET.

If you're not getting $_POST and $_GET with this, then something is causing a redirect or otherwise killing something. e.g. have you check $_SERVER['REQUEST_METHOD'] to see if your code is actually running as a POST? PHP won't populate $_POST if a post wasn't actually performed. You may have sent a post to the server, but that doesn't mean your code will actually be executed under a POST regime - e.g. a mod_rewrite redirect.

Since you have FOLLOW_REDIRECT turned on, you're simply ASSUMING you're actually getting a post when your code executes.

Friday, December 2, 2022

Solved: The problem lies here:

I set POST via both _CUSTOMREQUEST and _POST and the _CUSTOMREQUEST persisted as POST while _POST switched to _HTTPGET. The Server assumed the header from _CUSTOMREQUEST to be the right one and came back with a 411.

curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'POST');
Saturday, October 1, 2022

You don't. Constants are constant. You can't store anything in them.

You can use a static property though.

class My_Class {
  public static $DB_TABLE;
My_Class::$DB_TABLE = TABLE_PREFIX . 'class_table';

You can't do it within the declaration, so you might prefer a static method instead.

class My_Class {
  public static function dbTable() {
    return TABLE_PREFIX . 'class_table';
Saturday, October 1, 2022

CURLOPT_POSTREDIR can be set to configure this behaviour (request method for 301 location header based automatic redirects in curl):

curl_setopt( , CURLOPT_POSTREDIR, 3);

here 3 tells curl module to redirect both 301 as well as 302 requests.

0,1,2,3 are the valid options for the last argument.

0 -> do not set any behavior
1 -> follow redirect with the same type of request only for 301 redirects.
2 -> follow redirect with the same type of request only for 302 redirects.
3 -> follow redirect with the same type of request both for 301 and 302 redirects.

See as well: Request #49571 CURLOPT_POSTREDIR not implemented which has some useful comments, like setting a custom request method:

curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "POST"); 
Tuesday, December 27, 2022

When you start a thread this way your function must have one or less parameters. If you specify one parameter, it must be from type Object.

In your function you can simply cast this object parameter to your datatype:

private sub startMe(byval param as Object)
     dim b as Boolean = CType(param, Boolean)
end sub

When you want to pass multiple parameters, you can put them together into a class like this:

public class Parameters
     dim paramSTR as String
     dim paramINT as Integer
end class

private sub startMe(byval param as Object)
     dim p as Parameters = CType(param, Parameters)
     p.paramSTR = "foo"
     p.paramINT = 0
end sub

To start your Thread:

dim t as new Thread(AddressOf startMe)
dim p as new Parameters
p.paramSTR = "bar"
p.oaramINT = 1337
Monday, September 5, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :