So I have this piece of function to grab the postal zip within 30 miles of the target zip.
I used this function in my webpage but then I realize sometime the page couldn't finish loading. Once it stuck in loading, opening the url in new tab won't work as well and I have to restart the entire browser just to "resume" it.
After a very long time debugging I found out the culprit was this function.
This function hangs(takes forever to respond and return the result) from time to time on the same parameter.
//Get nearby postal zip by using geoname api
//genoname api provide both xml and json version
function getNearByPostalZip($zip){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://api.geonames.org/findNearbyPostalCodesJSON?postalcode=".$zip."&country=US&radius=30&username=xxxx&maxRows=100");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
curl_close($ch);
$temp = json_decode($output);
$zips = array();
foreach($temp->postalCodes as $key=>$postalcode)
{
$zips[] = array('zip'=>$postalcode->postalCode,'distance'=>$postalcode->distance);
}
return $zips;
}
Related
I have a large system with an API.
On the frontend, JavaScript uses AJAX to talk to the API.
I have a PHP file that runs every 5-min as a CRON job.
I want this PHP code to interact with the API.
All it has to submit is query-vars.
All that is sent back is a single number.
For Example:
https://examplesite.com/api/create?id=1&data=2
This replies with a simple number that is the SQL last-insert-id.
EXTRA:
The API also needs two Session variables (user-id and system-id)
Can I just start session and set them before calling the API I guess?
I need the PHP script, ran by the CRON system, to talk to this API.
I have tried using cURL but no luck yet:
//Need to add a user-id to session, does this work?
session_start();
$_SESSION['user-id'] = 1;
//HOW TO CALL API FROM CRON?
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($ch, CURLOPT_URL, 'https://example.com/api/create?id=1&gid=2');
//curl_setopt($ch, CURLOPT_URL, 'http://example.com/api/create?id=1&gid=2');
curl_setopt($ch, CURLOPT_URL, 'file://../framework/api/create.php?id=1&data=2');
$result = curl_exec($ch);
curl_close($ch);
$result = str_replace("\n", '', $result); // remove new lines
$result = str_replace("\r", '', $result); // remove carriage returns
//Expect Result to be a number only
file_put_contents("curl.log", "[".date('Y-m-d H:i:s')."] $result\n\n", FILE_APPEND);
The file method doesn't seem to work... maybe path issue with ../
The http method doesn't seem to work... server loopback issue?
Any advice on how to best have my PHP CRON robot use my API will be much appreciated.
I have simply copied API code into the CRON, but then I am duplicating code, and not allowing the robot to test the real API.
Thanks.
Assuming you still wanted to use a session. Your first curl should be a request that to a script that will create the SESSION then respond.
I created this get_cookie.php this to test this concept:
<?php
session_start();
$_SESSION['time'] = time();
echo 'Time=' . $_SESSION['time'];
?>
I called this script to get the PHPSESSID from the response cookie
$ch = curl_init('http://example.com/get_cookie.php');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE));
$head = substr($response,0,$skip);
$data = substr($response,$skip);
$end = 0;
$start = strpos($head,'Set-Cookie: ',$end);
$start += 12;
$end = strpos($head,';',$start );
$cookie = substr($head,$start ,$end-$start );
file_put_contents('cookie.txt',$cookie);
echo "\ncookie=$cookie";
echo "\n$data\n";
RESPONSE:
cookie=PHPSESSID=bc65c95468d08dd02cc5ab8ab87bbd39
Time=1664237484
The CRON job URL, session.php:
<?php
session_start();
echo 'Time=' . $_SESSION['time'];
?>
This is the CRON job script.
$cookie = file_get_contents('cookie.txt');
$ch = curl_init('http://example.com/session.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIE, $cookie );
curl_setopt($ch, CURLOPT_HEADER, false);
$response = curl_exec($ch);
echo $response;
RESPONSE:
Time=1664237484
The result "Time" ($_SESSION['TIME']) is always the same as the time from the get_cookie.php.
Thanks for the help, but in the end my alternate approach will be easiest and work best. Here is the answer for others in need...
To have an external PHP (run via CRON) test an internal PHP API (that the frontend JavaScript usually talks to via AJAX), this is the easiest solution, including passing query-variables and session-vars.
STEP 1: Don't worry about start_session() or passing any query variables, just add what you need to the arrays ahead of time.
STEP 2: Capture the output buffer and simply include the PHP API file:
$_SESSION['user-id'] = ' works! ';
$_REQUEST['var'] = ' too ';
ob_start();
include '/var/www/sitename.com/framework/api/create.php';
$result = ob_get_contents();
ob_end_clean();
file_put_contents("/var/www/sitename.com/cron/curl.log", "[".date('Y-m-d H:i:s')."] Result: $result\n\n", FILE_APPEND);
/* OUTPUT in curl.log:
[2022-09-26 22:30:01] Result: works! / too
*/
/* create.php API
$user = $_SESSION['user-id']??' did not work ';
$req = $_REQUEST['var' ]??' novar ';
echo $user.'/'.$req;
*/
(obviously the CRON has to be on the same server as the website/api, otherwise you will have to use cURL with Cookie/Session/QueryVar-Arrays)
hi I have a small problem i need help with i have a web page that outputs live streams in json format with links looking like this
rtmp:\/\/server:port\/camera1.stream
now if I copy and past that link into notepad and change the \/ to / my self, the links plays fine in every media player I have and I can see the camera feed but when I use a php script to decode the json output the streams do not play at all when outputed by echo or when added to a genarated m3u8 file :
bellow is the code i use to get the page and json decode
$stream_id = $_GET["cam"];
// create curl resource
$ch = curl_init();
//set url
curl_setopt($ch, CURLOPT_URL, "http://ip:port/json");
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
//close curl resource to free up system resources
curl_close($ch);
$response = json_decode($output), true);
foreach ($response['cameras'] as $result) {
if($result['name'] == $stream_id){
echo $result['cam_stream'];
}
}
I'm using PHP's cURL and explode methods to extract the upvotes from a Reddit post page remotely.
It's quite slow, it takes a number of seconds between the button click and the return of the data, my question is, how can I speed it up? Where can I optimize this? Is it slow in the cURL getting the URL or is it slow exploding the page?
Here's how I'm locating the upvote div and getting its contents:
function between($src, $start, $end){
$txt = explode($start, $src);
$txt2 = explode($end, $txt[1]);
return trim($txt2[0]);
}
$title = between($data, '<div class="score unvoted">','</div>');
Here's the function I'm using to get the page data from Reddit.
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
It might be worth looking into a profiling tool like WebGrind to see where the slow occurs directly.
Chances are it is cURL that's slowing down your page, but without profiling you cannot tell for certain.
When I execute the following code it takes between 10-12 seconds to respond.
Is the problem with Twitter or with our server?
I really need to know as this is part of the code to display tweets on our website and a 12 second load time is just not acceptable!
function get_latest_tweets($username)
{
print "<font color=red>**". time()."**</font><br>";
$path = 'http://api.twitter.com/1/statuses/user_timeline/' . $username.'.json?include_rts=true&count=2';
$jason = file_get_contents($path);
print "<font color=red>**". time()."**</font><br>";
}
Thanks
When you put the URL into your browser (http://api.twitter.com/1/statuses/user_timeline/username.json?include_rts=true&count=2) how long does it take for the page to appear? If it's quick then you need to start the search at your server.
use curl instead of file_get_contents() to request, so that response will be compressed. Here is the curl function which iam using.
function curl_file_get_contents($url)
{
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL,$url); //The URL to fetch. This can also be set when initializing a session with curl_init().
curl_setopt($curl,CURLOPT_RETURNTRANSFER,TRUE); //TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.
curl_setopt($curl,CURLOPT_ENCODING , "gzip");
curl_setopt($curl, CURLOPT_FAILONERROR, TRUE); //To fail silently if the HTTP code returned is greater than or equal to 400.
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
$contents = curl_exec($curl);
curl_close($curl);
return $contents;
}
Can someone please tell me where is the error in this code?, I use a mobile iphone application to call a php script tha will send information to apple. Apple then will return a JSON object containing several values in an associative array.
I want to reach the 'status' value but every time I run the code in the phone, the php script sends me the complete apple's returned string. In the XCode debugger the received string looks like:
[DEBUG]... responseString :
{"receipt":{"item_id":"328348691",
"original_transaction_id":"1000000000081203",
"bvrs":"1.0", "product_id":"julia_01",
"purchase_date":"2009-10-05 23:47:00
Etc/GMT", "quantity":"1",
"bid":"com.latin3g.chicasexy1",
"original_purchase_date":"2009-10-05
23:47:00 Etc/GMT",
"transaction_id":"1000000000081203"},
"status":0}
but the only piece I care in the string is the "status" value.
I've already looked inside documentation but can't find the solution. I'm new in php but this getting too long. Here the script:
<?php
//The script takes arguments from phone's GET call
$receipt = json_encode(array("receipt-data" => $_GET["receipt"]));
//Apple's url
$url = "https://sandbox.itunes.apple.com/verifyReceipt";
//USe cURL to create a post request
//initialize cURL
$ch = curl_init();
// set the target url
curl_setopt($ch, CURLOPT_URL,$url);
// howmany parameter to post
curl_setopt($ch, CURLOPT_POST, 1);
// the receipt as parameter
curl_setopt($ch, CURLOPT_POSTFIELDS,$receipt);
$result = curl_exec ($ch);
//Here the code "breaks" and return the complete string (i've tested that)
//and apparently doesn't get to the json_decode function (i think something's wrong there, so code breaks here)
curl_close ($ch);
$response = json_decode($result);
echo $response->{'status'};
?>
Even if I don't put any echo at the end, the script still returns a complete string (odd to me)
Thank's in advance and apollogies if I insist again from another question
Try setting the RETURNTRANSFER option to 1 so you can capture the output from the requested URL as a string. It seems that the default behaviour of cURL is to output the result directly to the browser:
...
$ch = curl_init();
// set the target url
curl_setopt($ch, CURLOPT_URL,$url);
// howmany parameter to post
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // <---- Add this
// the receipt as parameter
curl_setopt($ch, CURLOPT_POSTFIELDS,$receipt);
...