2
\$\begingroup\$

I have a loop in a php file to HTTP_Request Server Via CURL->POST.

But I don't know if I'm missing any security considerations. Also, is there a better way to perform this http request?

<?php
$j = 0;
while ($j <= 1) {
    $url    = 'http://127.0.0.1/index.php';
    $fields = array(
        'input1' => 'variable1',
        'input2'    => 'variable2',
    );
    $postvars         = http_build_query($fields);
    $COOKIE_FILE_PATH = "/tmp/cookiescron.txt";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, count($fields));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
    curl_setopt($ch, CURLOPT_TIMEOUT, 2);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
    curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
    curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: close'));
    // execute post
    curl_exec($ch);
    // close connection
    curl_close($ch);
    $j++;
    sleep(25);
}
?>

This executes 2 requests in around 25~30 seconds.

\$\endgroup\$
  • \$\begingroup\$ Is it possible to repackage your array data so that you don't need to perform iterated curl calls? The variability of your project data is not evident in your posted snippet. \$\endgroup\$ – mickmackusa Jun 16 at 0:37
  • \$\begingroup\$ is mandatory, becouse i need sleep 25 second every bucle...i think \$\endgroup\$ – walter nuñez Jun 16 at 0:39
  • \$\begingroup\$ So, whatever url you are sending your data to will only accept single doses of data? Can't send a deeper data structure? If you have written the receiving script, I recommend writing it to receive multiple rows of data so that only one curl call is necessary. \$\endgroup\$ – mickmackusa Jun 16 at 0:40
  • \$\begingroup\$ the url is the one mentioned in the script; and yes, the php is ready to receive other types of data passed by post, json, etc ... but I do not understand the question around the data structure ... \$\endgroup\$ – walter nuñez Jun 16 at 0:44
  • 1
    \$\begingroup\$ ...well, if you want a review regarding security, you should probably show the security part. \$\endgroup\$ – mickmackusa Jun 16 at 7:53
2
\$\begingroup\$

Well, I didn't take the time to test my snippets, but here are two suggestions...

#1 (preferred) - Bundle all of your input data into a single array, then pass it to your receiving url with a single curl call. It is best practice to minimize total calls (avoid iterated calls) so long as the operation works for your project, of course. This avoids sleepy time too.

$ch = curl_init();
$fields = [
    ['input1' => 'variable1', 'input2' => 'variable2'],
    ['input1' => 'variable3', 'input2' => 'variable4']
];
$COOKIE_FILE_PATH = "/tmp/cookiescron.txt";  // this doesn't appear to be used
$options = [
    CURLOPT_URL               => 'http://127.0.0.1/index.php',
    CURLOPT_POST              => true,  // https://www.php.net/manual/en/function.curl-setopt.php says boolean is expected
    CURLOPT_POSTFIELDS        => http_build_query($fields),
    CURLOPT_TIMEOUT           => 2,
    CURLOPT_RETURNTRANSFER    => false,
    CURLOPT_FORBID_REUSE      => true,
    CURLOPT_CONNECTTIMEOUT    => 2,
    CURLOPT_DNS_CACHE_TIMEOUT => 10,
    CURLOPT_FRESH_CONNECT     => true,
    CURLOPT_HTTPHEADER        => ['Connection: close']
];
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);

#2 - If your requirements obligate the use of iterated curl calls, I'd recommend only updating the CURLOPT_POSTFIELDS value within the loop. (Again, not tested)

$ch = curl_init();
$fields = [
    ['input1' => 'variable1', 'input2' => 'variable2'],
    ['input1' => 'variable3', 'input2' => 'variable4']
];
$COOKIE_FILE_PATH = "/tmp/cookiescron.txt";  // this doesn't appear to be used
$options = [
    CURLOPT_URL               => 'http://127.0.0.1/index.php',
    CURLOPT_POST              => true,  // https://www.php.net/manual/en/function.curl-setopt.php says boolean is expected
    CURLOPT_TIMEOUT           => 2,
    CURLOPT_RETURNTRANSFER    => false,
    CURLOPT_CONNECTTIMEOUT    => 2,
    CURLOPT_DNS_CACHE_TIMEOUT => 10,
];
foreach ($fields as $data) {
    $options[CURLOPT_POSTFIELDS => http_build_query($data)]; // overwrites previous data
    curl_setopt_array($ch, $options);
    curl_exec($ch);
    sleep(25);
}
curl_close($ch);

The takeaway here is to always try to leave as many processes as possible OUTSIDE of the loop to reduce calls/workload.

Relevant documentation:

\$\endgroup\$
  • \$\begingroup\$ if CURLOPT_FORBID_REUSE is true , this will get a warning??? \$\endgroup\$ – walter nuñez Jun 16 at 20:04
  • \$\begingroup\$ That makes sense. If I want to keep the connection / reuse the curl handle, I'd better allow its reuse. Updated. \$\endgroup\$ – mickmackusa Jun 16 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.