PHP from Cron job doesn't run a simple Javascript code :( - javascript

I'm running an API to retrieve information. I have to call this API via php 5 times, but each time I have to wait 60 seconds.
So the PHP File is running for like 6 minutes and gets timed-out. I tried extending the time limit but that doesn't work so I thought of another solution.
Since I have to run this PHP anyway on CRON job, here is the setup:
-- A.php is run every 10 minutes scheduled in Cron manager. This now runs the header("B.PHP?round=1") command and loads B.PHP
---- B.PHP runs, does what it needs to, now uses javascript setInterval waits 60 seconds and loads (window.location.href ="B.PHP?round=2" again with new parameter (to run 2nd or 3rd etc api token).
THE problem is, it never does load the B.PHP again for second round. I tried doing ajax query xmlhttp all type of JS script to load a page.....NOTHING! It seems to either ignore the javascript completely, or just ignores applying the JS code that loads b.php with new parameter
I really don't want to use the sleep(60) method (well it times out anyway). and I have to use Cron job and I know javascript is the only way to make the script just chill during a wait without causing timedout.
Any solutions at all? Please guys..be gentle I'm a biiit new at this stuff and know nothing about linux/ubunto :(
ps: The B.php I have the entire URL still doesn't work. I HAVE To call a PHP file from the cron manager.
I KNOW javascript is only on client side, but, the JS code is...loading a file on the server .. ? Ugh...I don't know what to do :/

As you said correctly, JavaScript is only client side.
Also, cron jobs usually only request a given URL but do not do anything with that result. And they obviously do not execute javascript.
You need to place the whole logic into your PHP code and use cronjobs to "trigger" your script(s).
Cronjob 1: Running every 10 minutes: start.php
Cronjob 2: Running every 60 Seconds (maybe make it a little more, if your API has a limit of exactly 60 seconds): process.php
Since you are using only PHP, you need to store your variable somewhere on your server. This could either be a database or a file on your filesystem. You can find a more detailed explanation on how to persist a variable here:
PHP store a single variable on the server?. (In my example I use a file as storage)
prosess.php:
// number of times the script should be executed
$maxRounds = 5;
// load $round from your storage
$round = file_get_contents('store.txt');
if ($round < $maxRounds) {
// increase round number for the next call
// you may want to add some checks to determine if the current round was successful before increasing the value
// depending on how log your round takes, it might be wise to add another variable (eg "working") to the store, so that multiple calls to the process file do not overlap
file_put_contents('store.txt', $round + 1);
// execute your code using the $round argument
doRound($round);
}
else {
// already done all rounds
}
start.php
// reset the $round variable
file_put_contents('store.txt', 0);
Keep in mind that this code is not production ready, but it should point you in the right direction :)

Related

Create content which updates asynchronously PHP

I'm trying to create a trading bot with PHP.
I would like to get the value of the currency and update it even without refreshing the page.
In order to do this I should execute this call every 5-10 seconds.
Is that correct?
$summ = $d->getMarketSummary("USDT-BTC");
Is there a way to do this asynchronously? Even if user doesn't reload the whole page.
I've heard of AJAX, but it's Javascript.
Thank you in advance.
You've heard it correctly, you need to do this in JavaScript, with AJAX. There are two parts for this:
1) You need to make an API in PHP, a route that will only respond with the data you want. So a page that when called:
<?php
$summ = $d->getMarketSummary("USDT-BTC");
echo $summ;
?>
And mapped to a url, let's say /data.
2) You need to make a JS in your page that calls that newly created route every-so-often; for that your need to use ajax (xmlhttprequest or Fetch API), and use the setInterval function to call it regularly and update the data in your page accordingly.
If you can't use javascript (AJAX) for this task, your only way is to create a CRON job that fires that PHP script every minute. Unfortunatelly, CRON jobs can't be configured to execute every X seconds, but you can fire it all minutes of the day.

How to refresh a specific div of a page in PHP?

I am making an online game using PHP and JavaScript, I have more knowledge in PHP than I do in JavaScript, though I am new in both languages, so keep that in mind.
So what I was trying to make in PHP / JavaScript and of course HTML was to refresh only the div or the area of code that I need, and I can't make the page reload every time that it gets new information or data because when the PHP is ran and done then I can't have anything else running, unless I was to use a loop though that sounds a bit sketchy and not sure if that's the method. I have tried: (PHP)
header("reload: 1");
Though that only refreshed the page, that is what I want to happen when I get data not always to be happening, so for example the program would get the information that someone is ready then it would send the client to another page as asll as the other client.
Though I would just like an explination if it is possible to only refresh a specific area when told to by example getting MySQL data.
function refresh_box()
{
$("#myDiv").load('path your PHP file');
setTimeout(refresh_box, 60000);
}
$(document).ready(function(){
refresh_box();
});
this setTimeout call your function for every 1 minute and load content dynamically in mydiv.

PHP Killing Old Script Execution on Retry

Alright, I have been trying to work on this issue for days, and have found no fix. I've asked about 4-5 different questions pertaining to my issue, but have found no solution.
file.php on example1.com:
I have a JavaScript function on this page that sends a POST request to a PHP file on example2.com (a DIFFERENT domain).
function buttonFunction() {
$.post("http://example2.com/core/runner.php",{username:username, password:pword, coins:coins}, function(data) {
// Stuff
});
}
This function dynamically loads the result of runner.php into a div on the page.
Now if the user leaves the page in the middle of execution (the result hasn't been generated yet) and then he/she refreshes the page, and then decides to run the function again, then two PHP proccesses would be running from the same user at the same time (that is, if the old one was still running).
Now I need a fix, whether that be in the PHP file on example2.com or within the JavaScript on example1.com that can abort/stop the previous PHP request before starting a new one.
What I've Tried:
#1
I've tried this, but unfortunately cross-domain cookies is practically impossible:
PHP session files saved, but no cookies and session not read
The goal was to store the PHP pid in a SESSION variable, and on every run, to check if the old proccess with that pid was still running (by grabbing the pid from the SESSION variable), if so, then I would kill that processes and change the value of the SESSION variable to the new pid.
#2
I've also tried to run a loop to check if the connection has been aborted while the main script runs. However, that also did not work:
PHP run loop and script at same time
#3
I also thought about doing something like this:
window.onbeforeunload = function(event) {
http.abort();
};
So it would abort the request before the user left/refreshed the page/browser. However, I was unsure about the reliability of this (Safe Way to Send POST Request via Javascript).
As pointed up by the other user, using files are the best way for doing this. My logic would be something like this:
When the runner.php runs:
First check if a file named username+number exists
If exists then delete that file, and create a new file named username + (number+1)
If does not exist then create a file named username+1
Store this number (i.e. 1 or number+1) in a variable
Do whatever processing is required
Before sending out the response back, check if the file named (username+ your number in var) exists
If yes, send out the response
If no, it means that another (later) process is running (only for that user because we name the file with username) and that process has deleted your current process's file, so just terminate without doing anything.
Of course this might not be the optimal solution, but should work for your use case.
Check the file functions in PHP, there are no complicated magic code required for this.
When You execute Your script runner.php for the first time You can create a file and lock it until script ends, so when there is another request to that script You can check if file is locked - and then You have information if You can run script again, example:
$fo = fopen('lock.txt', 'r+');
if (flock($fo, LOCK_EX))
{
// File was not locked, You have locked it successfully right now, do your logic
flock($fo, LOCK_UN); // unlock file afer script logic
}
else
{
// File is locked right now, don't run script
}
After that You can send message to user that he can try later (cause first script is running) instead of killing first script.
I think this is design problem when it comes to killing script, it doesn't look well. What about data when You kill script in middle of its execution? This can lead to some serious issues.

Is it bad idea to make an AJAX post call every 2 secs?

If I make an AJAX $.post call (with jQuery) to a php file for updating a certain parameter/number, does it considered bad practise, dangerous or similar?
$.post(file.php, {var:var}, function(data){
// something
}, json);
It would be a single user on a single page updating a number by clicking on an object. For example if user A is updating a certain number by clicking on an object user B should see this update immediately without reloading the page.
It depends on 3 main factors:
How many users will you have at any given time?
How much data is being sent per request on average?
Given 1 and 2, is your sever set up to handle that kind of action?
I have a webapp that's set up to handle up to 10-20k users simultaneously, makes a request each time the user changes a value on their page (could be more than 1 req per second), and it sends roughly 1000 bytes on each request. I get an average of 10ms response time, however that's with node js. Originally I started the project in PHP but it turned out to be too slow for my needs.
I don't think web-sockets is the right tool for what you're doing, since you don't need the server to send to the client, and a constant connection can be much more expensive than sending a request every few seconds.
Just be sure to do lots of testing and then you can make judgements on whether it'll work out or not for your specific needs.
tl;dr - It's not a good idea if your server can't handle it. Otherwise, there's nothing wrong with it.
Another solution could be, to cache user actions in local storage/variables, and send them all at once every 10-15 seconds or so, then clear the cache, when sending was successful.
In this case you should also validate the data in local storage to prevent tampering.

Javascript ajax wait until file is changed

I'm programming an website to control my Raspberry Pi robot. I'm driving two stepper motor using .py script I call it:
sudo ./GPS.py forward 100 30
Fist argument is way to go, second is how many steps to do, and the last is delay between steps.
The script open location.txt file (it looks like "100/50/18") and take coordinations x=100, y=50 and Alpha=18 degress. Then make a move, calculate new coordination and write it into this file.
Read part at the top of script:
fo = open("location.txt", "r")
data = fo.read()
fo.close()
coordinates= data.split("/")
temp1 = coordinates[0]
temp2 = coordinates[1]
temp3 = coordinates[2]
Alpha= float(temp3)
X = float(temp1)
Y = float(temp2)
Then it make all requested moves and calculations, and then at the end save new X,Y,Alpha back to file:
fo =open("location.txt", "w")
fo.write(str(X)+"/"+str(Y)+"/"+str(Alpha))
fo.close
Allright, this works perfect in Putty, but now I wanted to drive my robot through website, so I've made website to control it.
But now I have a problem. Now I have site like this:
HTTP --> Javascript --> PHP --> .PY script to move robot.
This works, but I have no idea how refresh X,Y,Alpha coordinates from location.txt on my website. I have an idea:
Javascript run .PY and wait it finishes, then JS open .txt and get data and finally set new coordinates to my webpage. But I don't know how to do it. This waiting to .PY finishes is killing me.
Thanks for your help!
Yacked2
PS.
I have apache installed on my Raspberry Pi, and I can donwload my .py script though webpage and I can open .txt file.
The classic web way of doing this would be to poll from the client until you are told of a change.
E.g.
Tweak your file so that it contains a date+time updated.
Implement a PHP script to open the file and serve the contents as a JSON object (with the date updated, X, Y and Alpha as properties)
On load of the page, load the location and store all 4 components.
When you send a move instruction to the server, start to poll for a change - periodically reload the JSON object until you have one with a changed date updated. You can then stop polling.
This updated location should then be stored and used to update your page.
Set a maximum number of times to poll and abort with error if you reach the maximum.
Let's say your main page contains
<div id="locationInfo" />
And you have implemented the PHP script getLocationInfo.php that returns a JSON object like this:
{ date_updated: "13-11-2013 15:45:98",
x_position: 105,
y_position: 120,
alpha: 123 }
In the main page you can have a script using jQuery that will (for example, something along the lines of - but more complex than)
$.get( "getLocationInfo.php", function( data ) {
var html = 'Location: ' + data.x_position + ', ' + data.y_position + ' #' + data.alpha
$( "#locationInfo" ).html( html );
});
All that's really missing from the above is the bit that repeatedly polls and aborts when date_updated has changed.
There is a simple example of polling described here by #johnny-craig: jQuery, simple polling example
In those examples you just need an exit condition for once you have the data you need (recognised by a change in date_updated)
It'll probably work, be pretty simple to implement, but suffers from the amount of duff requests being made from the web page. Though bear in mind the web has worked for a LONG time doing this kind of thing.
Alternatively, you can get all HTML5 about it and read up on websockets. Using websockets you can instigate the update from the server side, rather than the client side. There's less polling required and the response time on the client should be better.
Here's something that'll give you the basics:
http://www.html5rocks.com/en/tutorials/websockets/basics/

Categories