I am trying to send from a php code running on a nginx server a get request to another remote django server. I am expecting to get data in REST API using serializer.
First if I open this link in my local browser:
http://192.168.2.0:8000/myapp/documents/
I will get:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": "000e3588-9544-4df6-a589-cc0166242b5b",
"docfile": "/media/documents/2017/06/30/DSC03623.JPG"
},
{
"id": "3dc6be9f-8659-41d8-8282-b64662032da6",
"docfile": "/media/documents/2017/06/30/DSC03611_9KWbftQ.JPG"
},
{
"id": "28eacb2d-0798-46e9-b63e-10ff704482ce",
"docfile": "/media/documents/2017/06/30/DSC03555.JPG"
}
]
and this is exactly the info I want to get when i run my php code.
This is what I was working on, the commented parts are previous failed attempts:
<?php
echo "<h1>I am here</h1>";
$url = "http://192.168.2.0:8000/myapp";
/*$body = http_parse_message(http_get($url))->body;
$body = http_get($url);
echo $body;*/
/*$client = new Client($url);
$request = $client->newRequest('/documents/');
$response = $request->getResponse();
echo $response->getParsedResponse();*/
$r = new HttpRequest('http://192.168.2.0:8000/myapp/documents/', HttpRequest::METH_GET);
$r->send();
echo $r->getResponseCode();
if ($r->getResponseCode() == 200)
{
echo "<h2>we get 200 response</h2>";
}
?>
non of the above 3 attempts printed anything except the first echo
I am here
Ok, finally this is the code that worked for me:
<?php
$ch = curl_init('http://192.168.2.0:8000/myapp/documents/');
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
echo $data;
?>
it needs cUrl to work.
cUrl usual enabled in php. To double check
run this code as a script:
<?php
phpinfo();
?>
search in in the results if cUrl is working.
Related
I'm new to JSON Code. I want to learn about the update function. Currently, I successfully can update data to the database. Below is the code.
<?php
require_once "../config/configPDO.php";
$photo_after = 'kk haha';
$report_id = 1;
$url = "http://172.20.0.45/TGWebService/TGWebService.asmx/ot_maintainReport?taskname=&reportStatus=&photoBefore=&photoAfter=". urlencode($photo_after) . "&reportID=$report_id";
$data = file_get_contents($url);
$json = json_decode($data);
$query = $json->otReportList;
if($query){
echo "Data Save!";
}else{
echo "Error!! Not Saved";
}
?>
the problem is, if the value of $photo_after is base64 string, which is too large string, it will give the error:
1) PHP Warning: file_get_contents.....
2) PHP Notice: Trying to get property 'otReportList' of non-object in C:
BUT
when I change the code to this,
<?php
require_once "../config/configPDO.php";
$photo_after = 'mama kk';
$report_id = 1;
$sql = "UPDATE ot_report SET photo_after ='$photo_after', time_photo_after = GETDATE(), ot_end = '20:30:00' WHERE report_id = '$report_id'";
$query = $conn->prepare($sql);
$query->execute();
if($query){
echo "Data Save!";
}else{
echo "Error!! Not Saved";
}
?>
The data will updated including when the value of $photo_after is in base 64 string.
Can I know what is the problem? Any solution to allow the base64 string update thru json link?
Thanks
// ...
// It's likely that the following line failed
$data = file_get_contents($url);
// ...
If the length of $url is more than 2048 bytes, that could cause file_get_contents($url) to fail. See What is the maximum length of a URL in different browsers?.
Consequent to such failure, you end up with a value of $json which is not an object. Ultimately, the property otReportList would not exist in $json hence the error: ...trying to get property 'otReportList' of non-object in C....
To surmount the URL length limitation, it would be best to embed the value of $photo_after in the request body. As requests made with GET method should not have a body, using POST method would be appropriate.
Below is a conceptual adjustment of your code to send the data with a POST method:
<?php
require_once "../config/configPDO.php";
# You must adapt backend behind this URL to be able to service the
# POST request
$url = "http://172.20.0.45/TGWebService/TGWebService.asmx/ot_maintainReport";
$report_id = 1;
$photo_after = 'very-long-base64-encoding-of-an-image';
$request_content = <<<CONTENT
{
"taskname": $taskname,
"report_id": $report_id,
"photoBefore": $photoBefore,
"photo_after": $photo_after,
"reportStatus": $reportStatus
}
CONTENT;
$request_content_length = strlen($request_content);
# Depending on your server configuration, you may need to set
# $request_headers as an associative array instead of a string.
$request_headers = <<<HEADERS
Content-type: application/json
Content-Length: $request_content_length
HEADERS;
$request_options = array(
'http' => array(
'method' => "POST",
'header' => $request_headers,
'content' => $request_content
)
);
$request_context = stream_context_create($request_options);
$data = file_get_contents($url, false, $request_context);
# The request may fail for whatever reason, you should handle that case.
if (!$data) {
throw new Exception('Request failed, data is invalid');
}
$json = json_decode($data);
$query = $json->otReportList;
if ($query) {
echo "Data Save!";
} else {
echo "Error!! Not Saved";
}
?>
sending a long GET URL is not a good practice. You need to use POST method with cURL. And your webservice should receive the data using post method.
Here's example sending post using 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.example.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close ($ch);
// Further processing ...
if ($server_output == "OK") { ... } else { ... }
Sample code from: PHP + curl, HTTP POST sample code?
And all output from the webservice will put in the curl_exec() method and from there you can decode the replied json string.
I am trying to display the response string from a PHP POST request in the browser. If I run:
<?php
$project_id = "abcdefgh";
$session_id = "123456789";
$url = "https://dialogflow.googleapis.com/v2/projects/".$project_id."/agent/sessions/".$session_id.":detectIntent";
$query = '{
"query_input": {
"text": {
"text": "Test input",
"language_code": "en-US"
}
}
}';
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $query);
//So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
//execute post
$result = curl_exec($ch);
echo $result;
curl_close($ch);
?>
in VSCode, I get the following response (this is expected behavior):
{
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
However, if I navigate to the index.php file running on my WAMP server in Chrome, I get a blank screen. I can echo other strings, such as:
I can even copy the response directly, and echo the response as a string in the browser. It just seems to not work with the post request (maybe it is a timing thing?). This could be a WAMP configuration/permissions problem, but I feel the problem might be elsewhere. Thanks for your help!
I had to download and add cacert.pem to my php.ini file and restart my WAMP server to get it to work. It was an error with the curl call.
Because your return is an object, you must access it by following its object chain. Unable to execute echo an object, you must retrieve the message attribute and return a string.
//execute post
$result = curl_exec($ch);
// Decode object ()
$result = json_decode($result);
// Message error
echo $result->error->message;
curl_close($ch);
Reference: Object
I'm building a PHP application which does a curl request to a number of different URL's. It's then attempting to parse the string of data returned by curl to extract everything in the <body> </body> tags. This is working absolutely fine for 99% of URL's.
However, one such URL is a page, which takes some time to load in a browser. Upon inspection I realised that the markup for the page is 16 Mb.
The settings I have for curl are as follows:
$ch = curl_init();
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$data = curl_exec($ch);
if (!$data) {
echo 'ERROR: Curl has reported an error: ' . curl_error($ch) . "\n";
}
return $data;
The error message I added for the !$data condition is not output - so my assumption is there are no errors from curl itself. I attempted to change CURLOPT_CONNECTTIMEOUT to 120 seconds (as opposed to 5) but this doesn't fix the issue.
When $data is returned to my script:
if ($data) {
$body = '';
preg_match("/<body[^>]*>(.*?)<\/body>/is", $data, $body);
if (empty($body)) {
echo 'WARNING: nothing found in <body> tag: ' . "\n";
var_dump($body);
} else {
// Writing to file occurs here...
// This bit works ok when $body is available.
}
}
It's showing me the warning message "WARNING: nothing found in tag:" and the output from var_dump($body) is an empty array:
array(0) {
}
Does anyone know how I can further debug this, as I'm not sure where the error is originating? I have manually saved a copy of the web page and there are indeed a starting and closing <body> tag with lots of HTML in between.
My assumption is this is some problem due to the file size. The "average" file size on this application is about 1 Mb, and my script works perfectly with these files.
I am running this on a server from the cli, i.e. php download.php not through a browser.
I wrote an API in PHP. It executes pretty fast for my purpose (3s) when I call it using the browser. However if I call it using another PHP script (which i wrote to do testing) it takes a looong time (24s) for each request! I use curl to call the URL. Anybody knows whats happening ?
System Config :
Using WAMP to run the PHP.
Hosted on local computer.
Solutions tried :
Disabled all firewalls
Added the option curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
I even wrote a python script to call the PHP API and it also takes a long time. Seems like browser gives the best response time.
Any help is appreciated.
Updated with the code :
<?php
// Class to handle all Utilities
Class Utilities{
// Make a curl call to a URL and return both JSON & Array
public function callBing($bingUrl){
// Initiate curl
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$bingUrl);
// Performance Tweak
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12');
session_write_close();
// Execute
$bingJSON=curl_exec($ch);
// Closing
curl_close($ch);
$bingArray = json_decode($bingJSON,true);
return array( "array" => $bingArray , "json" => $bingJSON );
}
}
?>
<?php
// The Test script
include_once('class/class.Utilities.php');
$util = new Utilities();
echo "<style> td { border : thin dashed black;}</style>";
// Test JSON
$testJSON = '
{
"data" : [
{ "A" : "24324" , "B" : "64767", "expectedValue" : "6.65" , "name" : "Test 1"},
{ "A" : "24324" , "B" : "65464", "expectedValue" : "14" , "name" : "Test 2"}
]
}
';
$testArray = json_decode($testJSON, TRUE);
echo "<h1> Test Results </h1>";
echo "<table><tr><th>Test name</th><th> Expected Value</th><th> Passed ? </th></tr>";
$count = count($testArray["data"]);
for ($i=0; $i < $count ; $i++) {
$url = "http://localhost/API.php?txtA=".urlencode($testArray["data"][$i]["A"])."&txtB=".urlencode($testArray["data"][$i]["B"]);
$result = $util->callutil($url);
if($testArray["data"][$i]["expectedValue"] == $result["value"])
$passed = true;
else
$passed = false;
if($passed)
$passed = "<span style='background:green;color: white;font-weight:bold;'>Passed</span>";
else
$passed = "<span style='background:red;color: white;font-weight:bold;'>Failed</span>";
echo "<tr><td>".$testArray["data"][$i]["name"]."</td><td>".$testArray["data"][$i]["expectedValue"]."</td><td>$passed</td></tr>";
}
echo "</table>";
?>
There is an overhead cost involved in starting up the interpreter and parsing the code (whether php, python, ruby, etc). When you have the code running in a server process that startup cost is payed when the server starts initially, and the application logic (plus some minor request/response overhead) is simply executed on the request. When running the code manually, however, that additional startup overhead happens before you code can be run and causes the slowness you are seeing. This is the reason that mod_php, and mod_wsgi exist (as opposed to frameworks that use the CGI api).
I am having some trouble working with curl and headers returned by servers.
1) My php file on my_website.com/index.php looks like this (trimmed version):
<?php
$url = 'http://my_content_server.com/index.php';
//Open connection
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
echo $result;
?>
The php file on my_content_server.com/index.php looks like this:
<?php
header("HTTP/1.0 404 Not Found - Archive Empty");
echo "Some content > 600 words to make chrome/IE happy......";
?>
I expect that when I visit my_website.com/index.php, I should get a 404, but that is not happening.
What am I doing wrong?
2) Basically what I want to achieve is:
my_content_server.com/index.php will decide the content type and send appropriate headers, and my_website.com/index.php should just send the same content-type and other headers (along with actual data) to the browser. But it seems that my_website.com/index.php is writing its own headers? (Or maybe I am not understanding the working correctly).
regards,
JP
Insert before curl_exec():
curl_setopt($ch,CURLOPT_HEADER,true);
Instead of just echo'ing the result, forward the headers to the client as well:
list($headers,$content) = explode("\r\n\r\n",$result,2);
foreach (explode("\r\n",$headers) as $hdr)
header($hdr);
echo $content;