How to make a post request without curl? - php

Considering I don't want to use curl, which is a valid alternative to make a post request? Maybe Zend_http_client?
I just need the basic stuff (I need to request an url with only one post param)

You could use file_get_contents().
The PHP manual has a nice example here. This is just copy past from the manual:
$postdata = http_build_query(
array(
'var1' => 'some content',
'var2' => 'doh'
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('http://example.com/submit.php', false, $context);

you can use stream_context_create and file_get_contents
<?php
$context_options = array (
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
?>
$context = stream_context_create($context_options);
$result = file_get_contents('http://www.php.net', false, $context);

You can implement it yourself via sockets:
$url = parse_url(''); // url
$requestArray = array('var' => 'value');
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($sock, $url['host'], ((isset($url['port'])) ? $url['port'] : 80));
if (!$sock) {
throw new Exception('Connection could not be established');
}
$request = '';
if (!empty($requestArray)) {
foreach ($requestArray as $k => $v) {
if (is_array($v)) {
foreach($v as $v2) {
$request .= urlencode($k).'[]='.urlencode($v2).'&';
}
}
else {
$request .= urlencode($k).'='.urlencode($v).'&';
}
}
$request = substr($request,0,-1);
}
$data = "POST ".$url['path'].((!empty($url['query'])) ? '?'.$url['query'] : '')." HTTP/1.0\r\n"
."Host: ".$url['host']."\r\n"
."Content-type: application/x-www-form-urlencoded\r\n"
."User-Agent: PHP\r\n"
."Content-length: ".strlen($request)."\r\n"
."Connection: close\r\n\r\n"
.$request."\r\n\r\n";
socket_send($sock, $data, strlen($data), 0);
$result = '';
do {
$piece = socket_read($sock, 1024);
$result .= $piece;
}
while($piece != '');
socket_close($sock);
// TODO: Add Header Validation for 404, 403, 401, 500 etc.
echo $result;
Of course you have to change it to fill your needs or wrap it into a function.

The simplest way if you have PHP configured with pecl_http is:
$response = http_post_data($url, $post_params_string);
The function is documented on php.net:
Documentation http://php.net/manual/en/function.http-post-data.php
Install: http://php.net/manual/en/http.install.php
PECL also provides a well documented way to handle Cookies, Redirects, Authentication etc before the POST:
http://php.net/manual/en/http.request.options.php

If you are using the Zend Framework already you should try the Zend_Http_Client you mentioned:
$client = new Zend_Http_Client($host, array(
'maxredirects' => 3,
'timeout' => 30));
$client->setMethod(Zend_Http_Client::POST);
// You might need to set some headers here
$client->setParameterPost('key', 'value');
$response = $client->request();

RESTclient is a nice little app for this: http://code.google.com/p/rest-client/

Related

dynamic site in file_get_contents

problem , Crossing the CAPTCHA in dynamic site .. :(
problem link action form in https://edu.uast.ac.ir ..
sorry My English is not good.
please test my code :
my source code :
a.php
<?php
echo file_get_contents("https://edu.uast.ac.ir");
?>
b.php
<?php
$a = $_POST["captcha_first_page"];
$postdata = http_build_query(
array(
'captcha_first_page' => $a
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('https://edu.uast.ac.ir/user/user_manage/userLogin/', false, $context);
echo $result;
?>
please help me
You have to replace the form action, too, cause if not the submitted form want posted to your b.php.
captcha-a.php
<?php
$content = file_get_contents("https://edu.uast.ac.ir");
$content = str_replace('https://edu.uast.ac.ir/user/user_manage/userLogin/','captcha-b.php', $content);
echo $content;
captcha-b.php
<?php
function redirect_post($url, array $data, array $headers = null) {
$params = array(
'http' => array(
'method' => 'POST',
'content' => http_build_query($data)
)
);
// replace
$headers['Host'] = "edu.uast.ac.ir";
$headers['Origin'] = "https://edu.uast.ac.ir";
$headers['Referer'] = "https://edu.uast.ac.ir";
if (!is_null($headers)) {
$params['http']['header'] = '';
foreach ($headers as $k => $v) {
$params['http']['header'] .= "$k: $v\n";
}
}
$ctx = stream_context_create($params);
$fp = fopen($url, 'rb', false, $ctx);
if ($fp) {
return stream_get_contents($fp);
} else {
// Error
throw new Exception("Error loading '$url', $php_errormsg");
}
}
setlocale(LC_ALL, "en_US.UTF8");
echo redirect_post("https://edu.uast.ac.ir/user/user_manage/userLogin/" ,$_POST, getallheaders());
This should be a good starting point. Don't know if it works cause I can't really speak arabian.

POST and GET without cURL PHP

I tried some times release POST and GET in this site http://www.sefaz.pe.gov.br/sintegra, but it doesn´t work
// POST
$data = array('CNPJ' => '02340534000192', 'consulta' => 'OK', 'vazio' => '');
$html = $this->HTTP_Post('http://www.sefaz.pe.gov.br/sintegra/consulta/consulta.asp', $data, $cookie);
$arr = split("Set-Cookie:", $html);
$cookie="";
$count=1;
while ($count < count($arr))
{
$cookie.=substr($arr[$count].";", 0, strpos($arr[$count].";",";")+1);
$count++;
}
// GET after POST
echo $this->get_url('http://www.sefaz.pe.gov.br/sintegra/consulta/exibirResultado.asp', $cookie);
I tried file_get_contents and curl too... both without success
function get_url($url,$cookie=false)
{
$url = parse_url($url);
$query = $url[path]."?".$url[query];
echo "Query:".$query;
$fp = fsockopen( $url[host], $url[port]?$url[port]:80 , $errno, $errstr, 30);
if (!$fp)
{
return false;
}
else
{
$request = "GET $query HTTP/1.1\r\n";
$request .= "Host: $url[host]\r\n";
$request .= "Connection: Keep-Alive\r\n";
if($cookie) $request.="Cookie: $cookie\n";
$request.="\r\n";
fwrite($fp,$request);
while (!feof($fp))
{
$result .= fgets($fp, 128);
}
fclose($fp);
return $result;
}
}
function HTTP_Post($URL,$data,$cookie, $referrer="")
{
$URL_Info=parse_url($URL);
if($referrer=="") $referrer="111";
foreach($data as $key=>$value)
$values[]="$key=".urlencode($value);
$data_string=implode("&",$values);
if(!isset($URL_Info["port"]))
$URL_Info["port"]=80;
$request.="POST ".$URL_Info["path"]." HTTP/1.1\n";
$request.="Host: ".$URL_Info["host"]."\n";
$request.="Referer: $referer\n";
$request.="Content-type: application/x-www-form-urlencoded\n";
$request.="Content-length: ".strlen($data_string)."\n";
$request.="Connection: Keep-Alive\n";
$request.="Cookie: $cookie\n";
$request.="\n";
$request.=$data_string."\n";
$fp = fsockopen($URL_Info["host"],$URL_Info["port"]);
fputs($fp, $request);
while(!feof($fp))
{
$result .= fgets($fp, 1024);
}
fclose($fp);
return $result;
}
functions GET and POST with fsocket.
any ideas are welcome
Thanks
EDIT 1:
Thank you, but it doesn´t work. I tried 20 times, but this website doesn´t work...
The browser message appears: Atenção: Acesso negado! Favor selecionar algum parâmetro de consulta.
Caution: Access Denied! Please select a query parameter.
my code with your code
function POST()
{
$postdata = http_build_query(
array(
'CNPJ' => '02340534000192',
'consulta' => 'OK',
'vazio' => '',
'CPF' => '',
'IE' => '',
'razaosocial' => ''
));
$headers = array(
'Content-type: application/x-www-form-urlencoded',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => implode("\r\n", $headers),
'content' => $postdata,
));
$context = stream_context_create($opts);
$result = file_get_contents('http://www.sefaz.pe.gov.br/sintegra/consulta/consulta.asp', false, $context);
return $result;
}
I think you can do file_get_contents for GET
or http://php.net/manual/en/context.http.php for POST
Example from php.net website
$postdata = http_build_query(
array(
'var1' => 'some content',
'var2' => 'doh'
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('http://example.com/submit.php', false, $context);
Your IP is probably blocked by the website.

PHP - Posting JSON via file_get_contents

I am trying to POST JSON content to a remote REST endpoint, however the 'content' value appears to be empty on delivery. All other headers etc are being received correctly, and the web service tests successfully with a browser based test client.
Is there a problem with my syntax below where I specify the 'content' field?
$data = array("username" => "duser", "firstname" => "Demo", "surname" => "User", "email" => "example#example.com");
$data_string = json_encode($data);
$result = file_get_contents('http://test.com/api/user/create', null, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => array('Content-Type: application/json'."\r\n"
. 'Authorization: username:key'."\r\n"
. 'Content-Length: ' . strlen($data_string) . "\r\n"),
'content' => $data_string)
)
));
echo $result;
This is the code I always use and it looks pretty similar (though this is of course for x-www-form-urlencoded).
Perhaps your username:key needs to be base64_encode'd.
function file_post_contents($url, $data, $username = null, $password = null)
{
$postdata = http_build_query($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
if($username && $password)
{
$opts['http']['header'] .= ("Authorization: Basic " . base64_encode("$username:$password"));
}
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);
}
The question was about json, why the accepted answer is about x-www-form?
Json has many cool stuff to struggle about, like utf8_encode
function my_utf8_encode(array $in): array
{
foreach ($in as $key => $record) {
if (is_array($record)) {
$in[$key] = my_utf8_encode($record);
} else {
$in[$key] = utf8_encode($record);
}
}
return $in;
}
function file_post_contents(string $url, array $data, string $username = null, string $password = null)
{
$data = my_utf8_encode($data);
$postdata = json_encode($data);
if (is_null($postdata)) {
throw new \Exception('decoding params');
}
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => $postdata
)
);
if (!is_null($username) && !is_null($password)) {
$opts['http']['header'] .= "Authorization: Basic " . base64_encode("$username:$password");
}
$context = stream_context_create($opts);
try {
$response = file_get_contents($url, false, $context);
} catch (\ErrorException $ex) {
throw new \Exception($ex->getMessage(), $ex->getCode(), $ex->getPrevious());
}
if ($response === false) {
throw new \Exception();
}
return $response;
}
The earlier response of
function file_post_contents($url, $data, $username = null, $password = null) {
$postdata = http_build_query($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
if($username && $password)
{
$opts['http']['header'] = ("Authorization: Basic " . base64_encode("$username:$password"));
}
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);}
is incorrect. This function works sometimes, but it is inaccurate and will fail if you're not using the Content-type of application/x-www-form-urlencoded and you pass in a username and password.
It's working for the writer because application/x-www-form-urlencoded is the default Content-type, but his handling of the username and password is overwriting the earlier declaration of content type.
Here is the corrected function:
function file_post_contents($url, $data, $username = null, $password = null){
$postdata = http_build_query($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'content' => $postdata
)
);
if($username && $password)
{
$opts['http']['header'] .= ("Authorization: Basic " . base64_encode("$username:$password")); // .= to append to the header array element
}
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);}
Note the line:
$opts['http']['header' .= (dot equals to append to the array element.)

HTTP request using fopen and curl_setopt

If cURL is unavailable I want to send HTTP requests using fopen. I got the code for a class from a PACKT RESTful PHP book but it does nto work. Any ideas why?
if ($this->with_curl) {
//blah
} else {
$opts = array (
'http' => array (
'method' => "GET",
'header' => array($auth,
"User-Agent: " . RESTClient :: USER_AGENT . "\r\n"),
)
);
$context = stream_context_create($opts);
$fp = fopen($url, 'r', false, $context);
$result = fpassthru($fp);
fclose($fp);
}
return $result;
}
The HTTP context options are laid out here: http://www.php.net/manual/en/context.http.php
The header option is a string, so as #Mob says you should be using \r\n and string concatenation rather than an array. However, user_agent is a valid key, so you could just use that instead.
I'm guessing that the contents of the $auth variable is something along the lines of Authorization: blah - i.e. standard header format?
The below code is a working example. Note that I've changed your fpassthru() (which outputs the content to the browser, and does not store it to $result) to a fread() loop. Alternatively you could have wrapped the fpassthru() call with ob_start(); and $result = ob_get_clean();
<?php
class RESTClient {
const USER_AGENT = 'bob';
}
$url = 'http://www.example.com/';
$username = "fish";
$password = "paste";
$b64 = base64_encode("$username:$password");
$auth = "Authorization: Basic $b64";
$opts = array (
'http' => array (
'method' => "GET",
'header' => $auth,
'user_agent' => RESTClient :: USER_AGENT,
)
);
$context = stream_context_create($opts);
$fp = fopen($url, 'r', false, $context);
$result = "";
while ($str = fread($fp,1024)) {
$result .= $str;
}
fclose($fp);
echo $result;
You're mixing this. Shouldn't it be ::
$opts = array (
'http' => array (
'method' => "GET",
'header' => $auth . "\r\n" . //removed array()
"User-Agent: " . RESTClient :: USER_AGENT . "\r\n" )
)
Here's an example of setting headers from the PHP manual
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);

Send HTTP Post with Array - PHP

I'm trying to use this nice function:
function do_post_request($url, $data, $optional_headers = null) {
$params = array('http' => array(
'method' => 'POST',
'content' => $data
));
if ($optional_headers !== null) {
$params['http']['header'] = $optional_headers;
}
$ctx = stream_context_create($params);
$fp = #fopen($url, 'rb', false, $ctx);
if (!$fp) {
throw new Exception("Problem with $url, $php_errormsg");
}
$response = #stream_get_contents($fp);
if ($response === false) {
throw new Exception("Problem reading data from $url, $php_errormsg");
}
return $response;
}
to send a POST command to a specific url, my problem is i'm trying to send the post paramters in a form of an array, something like this
login[username]: myusername
login[password]: mypassword,
however i'm not able to do that, calling the function with :
$login_post = array('login[username]' => $email,
'login[password]' => '');
do_post_request(getHost($website['code']), $login_post);
always send the data to the post in the form:
username: myusername
password: mypassword
How can I avoid this (without using curl)? Thanks a lot.
Thanks
Yehia
Maybe with that ?
<?php
// Define POST data
$donnees = array(
'login' => 'test',
'password' => '******' );
function http_build_headers( $headers ) {
$headers_brut = '';
foreach( $headers as $name => $value ) {
$headers_brut .= $name . ': ' . $value . "\r\n";
}
return $headers_brut;
}
$content = http_build_query( $donnees );
// define headers
$headers = http_build_headers( array(
'Content-Type' => 'application/x-www-form-urlencoded',
'Content-Length' => strlen( $content) ) );
// Define context
$options = array( 'http' => array( 'user_agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) Gecko/20061010 Firefox/2.0',
'method' => 'POST',
'content' => $content,
'header' => $headers ) );
// Create context
$contexte = stream_context_create( $options );
// Send request
$return = file_get_contents( 'http://www.exemple.com', false, $contexte );
?>
$login_post = array(
'login' => array(
'username' => $email,
'password' => ''))
Try using stream_context_create
$url = 'http://your_url.com/path';
$data = array('login' => 'usrnname', 'password' => '**');
$opt = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($opt);
$result = file_get_contents($url, false, $context);
var_dump($result);
This method doesnt use curl.

Categories