?
Solved

Send data string from PHP

Posted on 2006-05-25
16
Medium Priority
?
473 Views
Last Modified: 2013-11-29
Hello X-perts,
How can I send a POST data string directly from PHP without constructing a HTML submit form? I cannot build a form, because of security (its a payment gateway) and I cannot reveal the string variables in HTML page.

Thanks,

Andy
0
Comment
Question by:andy7789
  • 6
  • 5
  • 3
  • +1
16 Comments
 
LVL 10

Expert Comment

by:ClickCentric
ID: 16758526
Well, really the only way to do this is through the CURL library.

http://www.php.net/manual/en/ref.curl.php

Without any details, it's hard to give an example.  But that page should tell you what you need to know.
0
 
LVL 2

Expert Comment

by:crnz
ID: 16758679
He's right - the only practical answer is curl, unless you want to open a socket to the web server's port 80 and start writing your own HTTP1.1 protocol.  Much easier to use Curl.  A good place to start for example is here http://curl.haxx.se/libcurl/php/examples/

<?php
//
// A very simple PHP example that sends a HTTP POST to a remote site
//

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,"http://www.mysite.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
            "postvar1=value1&postvar2=value2&postvar3=value3");

curl_exec ($ch);
curl_close ($ch);
?>

Looks simple, but the trick is learning how to set all the CURLOPTions :)
0
 
LVL 49

Assisted Solution

by:Roonaan
Roonaan earned 280 total points
ID: 16758735
Alternatively you can use this post function to do an xml post to another server:

  function get_remote($url, $strXML) {
            $urlParts = parse_url($url);
            $host = isset($urlParts['host'])?$urlParts['host']:'localhost';
            $port = isset($urlParts['port'])?$urlParts['port']:80;
            $path = isset($urlParts['path'])?$urlParts['path']:"/";

            // Open a connection with the required host
            $fp = fsockopen($host, $port, $errno, $errstr);
            if (!$fp) {
                  trigger_warning('Unable to connect to '.$host.' at port '.$port.': ('.$errno.') '.$errstr);
                  return false;
    }
            fputs($fp, "POST ".$path." HTTP/1.0\r\n".
                  "Host: ".$host."\r\n".
                  "Content-length: ".strlen($strXML)."\r\n".
                  "Content-type: text/xml\r\n".
                  "Connection: close\r\n\r\n".
                  $strXML."\r\n");
   
            $buf = '';
            while (!feof($fp)) $buf .= fread($fp, 128);
            fclose($fp);
            
            if (!preg_match("/(<.*>)/msi", $buf, $matches)) // Greedy match
              $return = '';
            else
              $return = $matches[1];
    return $return;

  }

-r-
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:andy7789
ID: 16758883
Thanks guys!
I have just tried the simplest curl code, but it seems that something is wrong, because nothing happens and I stay on the blank page. I have checked that curl library is supported by my server. This is the code I tried

<?php
//
// A very simple PHP example that sends a HTTP POST to a remote site
//

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,"https://www.xxx.xxx/xxx");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
            "postvar1=value1&postvar2=value2&postvar3=value3");

curl_exec ($ch);
curl_close ($ch);
?>
 Obviously, all the vars are replafed by my own.... What could be a reason that I am not getting to the specified https server?

Thanks

Andy
0
 

Author Comment

by:andy7789
ID: 16758908
Further to my last email. I have checked all http transaction with Fiddler proxy, and it seems that my curl php page is not sending anything at all.
Any ideas, please
0
 
LVL 2

Accepted Solution

by:
crnz earned 400 total points
ID: 16758944
Right Andy, you didn't tell us that!!! :)

https access using CURL is a whole different ball game.

<?php

/**
* Open an url on https using curl and return content
*
* @author hatem <info@phptunisie.net>
* @param string url            The url to open
* @param string refer        Referer (optional)
* @param mixed usecookie    If true, cookie.txt    will be used as default, or the usecookie value.
* @return string
*/
function open_https_url($url,$refer = "",$usecookie = false) {

    if ($usecookie) {
       
        if (file_exists($usecookie)) {
       
            if (!is_writable($usecookie)) {
               
                return "Can't write to $usecookie cookie file, change file permission to 777 or remove read only for windows.";
            }
        } else {
            $usecookie = "cookie.txt";
            if (!is_writable($usecookie)) {
               
                return "Can't write to $usecookie cookie file, change file permission to 777 or remove read only for windows.";
            }
        }
   
    }

    $ch = curl_init();
   
    curl_setopt($ch, CURLOPT_URL, $url);
   
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
   
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
   
    curl_setopt($ch, CURLOPT_HEADER, 1);
   
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
   
    if ($usecookie) {
        curl_setopt($ch, CURLOPT_COOKIEJAR, $usecookie);
       
        curl_setopt($ch, CURLOPT_COOKIEFILE, $usecookie);    
    }
   
    if ($refer != "") {
   
        curl_setopt($ch, CURLOPT_REFERER, $refer );
       
    }
   
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
   
   $result =curl_exec ($ch);
   
   curl_close ($ch);
   
   return $result;
}
?>


Usage:
<?php
echo  open_https_url("https://domain.com/","",true);
?>


from: http://www.weberdev.com/get_example-4136.html

Modify for a POST.

As I warned you earlier:  Looks simple, but the trick is learning how to set all the CURLOPTions :)

0
 
LVL 49

Expert Comment

by:Roonaan
ID: 16758952
At this stage it more looks like curl isn't installed.

-r-
0
 
LVL 2

Expert Comment

by:crnz
ID: 16758965
0
 

Author Comment

by:andy7789
ID: 16758974
In my php.ini config I do have a line
extension=curl.so

So, curl is here
0
 
LVL 2

Expert Comment

by:crnz
ID: 16758990
Here's one from the PHP manual, using streams:

<?php
/* Send POST request to https://secure.example.com/form_action.php
 * Include form elements named "foo" and "bar" with dummy values
 */

$sock = fsockopen("ssl://secure.example.com", 443, $errno, $errstr, 30);
if (!$sock) die("$errstr ($errno)\n");

$data = "foo=" . urlencode("Value for Foo") . "&bar=" . urlencode("Value for Bar");

fwrite($sock, "POST /form_action.php HTTP/1.0\r\n");
fwrite($sock, "Host: secure.example.com\r\n");
fwrite($sock, "Content-type: application/x-www-form-urlencoded\r\n");
fwrite($sock, "Content-length: " . strlen($data) . "\r\n");
fwrite($sock, "Accept: */*\r\n");
fwrite($sock, "\r\n");
fwrite($sock, "$data\r\n");
fwrite($sock, "\r\n");

$headers = "";
while ($str = trim(fgets($sock, 4096)))
  $headers .= "$str\n";

echo "\n";

$body = "";
while (!feof($sock))
  $body .= fgets($sock, 4096);

fclose($sock);
?>
0
 

Author Comment

by:andy7789
ID: 16759291
crnz,
Yes, it is not for 5min debugging (as I thought earlier :)). Anyway, before I get to some other options, I would like to dig curl. First, I do have a working library, because, if i disable it in my php.ini, my code generates an error. It is clear. Second, I have found a similafr solution on the net for 2checkout.com (the same as i need). It is here:

<?php
 
  // read the post from 2checkout system and add 'sid'
  $req = "x_login={$config['method'][2]['sid']}";
 
  foreach ($_POST as $key => $value) {
    $value = urlencode(stripslashes($value));
    $req .= "&$key=$value";
  }
 
  ## CURL TESTING
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "https://www.2checkout.com/cgi-bin/Abuyers/purchase.2c");
  curl_setopt($ch, CURLOPT_POST, $req);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $result = curl_exec($ch);
  curl_close($ch);

  $result = str_replace("purchase1.2c","purchase.2c",$result);
  $result = str_replace("src=\"/","src=\"https://www.2checkout.com/",$result);
  $result = str_replace("src=\\\"/","src=\\\"https://www.2checkout.com/",$result);
  $result = str_replace("src=/","src=https://www.2checkout.com/",$result);
  $result = str_replace("href=\"/","href=\"https://www.2checkout.com/",$result);
  $result = str_replace("href=\\\"/","href=\\\"https://www.2checkout.com/",$result);
  $result = str_replace("action=\"/", "action=\"https://www.2checkout.com/", $result);
  $result = str_replace("action=\\\"/", "action=\\\"https://www.2checkout.com/", $result);
  echo $result;
?>
It is quite old script and the paramerers are obsolete, but it ises the simplest form of curl. My question to you - why it is so complicated and we cannot do it in a simple way like done above? FYI, this script is not working on my server, but probably there is another reason than https. Is the problem because of cookies?

Anyway, I am testing it on my own server (a simple http) and its not working and does not give any messages - I just stay on the same page. What could be a reason?

Thanks
Andy
0
 

Author Comment

by:andy7789
ID: 16759312
Yes, it is working on http, but not on https!!!
0
 
LVL 2

Expert Comment

by:crnz
ID: 16759319
The problem is the S part of https.  Secure.  That means encryption, SSL, digital certificates and all sorts of drama.  I strongly suggest you contact the payment provider and ask if they have a ready-to-go library for you to use.  The ones locally have code for .asp, .php, .js, .vba and so on, already tested and ready to go.  Unless you want to know the internals of it all, I'd go that way.

In your above example, you don't seem to be setting any SSL related options from the CURL_OPT_SSL range of options?

I kind of warned you that as soon as you went secure, you were entering a world of pain... :)
0
 
LVL 10

Expert Comment

by:ClickCentric
ID: 16760748
Ok, you have curl, but is openssl intalled?  As for that 2checkout code, I don't think it would have ever actually worked as-is.
0
 
LVL 10

Assisted Solution

by:ClickCentric
ClickCentric earned 320 total points
ID: 16761163
The following does work, but is only an example as different options are needed by different hosts.  And this method kind of forces things to work and isn't very secure so should only be used for testing:

<?php
$ch = curl_init();
$res= curl_setopt ($ch, CURLOPT_URL,"https://pathtoformprocessor"); // change pathtoformprocessor to the script that processes the form. Note:  Make sure you're pointing to the form processor and not just the form, otherwise you'll never get anything back.

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  // for testing, ignores invalid peer in certificate
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // for testing, ignores invalid host in certificate
curl_setopt ($ch, CURLOPT_HEADER, 0); // Header
curl_setopt($ch, CURLOPT_POST, 1); // set it to post
curl_setopt($ch, CURLOPT_POSTFIELDS, "username=admin&password=test"); // obviously replace with the appropriate post fields
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // follow the location if it redirects
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); // lets you save the returned value to a variable rather than just dumping it out
$ret = curl_exec ($ch);


echo "=============================================================<br>";
echo $ret;
if ($ret == NULL) {
           echo "Error:<br>";
           echo curl_errno($ch) . " - " . curl_error($ch) . "<br>";
}
curl_close ($ch);
?>
0
 

Author Comment

by:andy7789
ID: 16766191
Thanks ClickCentric,

Your code returns

Error:
7 - Failed to connect to 66.194.132.146: Permission denied

What are other settings I could play with?

Andy
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article discusses how to implement server side field validation and display customized error messages to the client.
Why WooCommerce is one of the majorly favored choices when it comes to having an eCommerce store. This article will acquaint you with some reasons that I believe make it one of the best eCommerce platforms available.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Suggested Courses

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question