Running PHP batch scripts through web link with status updates - php

I have a process defined in a batch file that runs 3 php scripts, one after another in sequence, and I want to create a web front-end for the process. The process is triggered when someone uploads a file using a webform.
I want the ability to notify the user after each script in the batch file is run with some useful messages, but I am not quite sure what the right way to go about is.
I am thinking in terms of javascript that sends request to the 3 php files in sequence, with the php scripts echoing the status messages as they are executed. But I would rather have the three files executed in a single trigger from the client instead of having javascript calling the the three scripts separately.
Any ideas whats the best way to go about it?

You could create a single php file that runs the 3 php script and echoes their ouputs. By executing a server side request trough AJAX (I suggest jQuery framework) the outputs may be collected and the client side scripts can process and show the results to the user.

Store messages in the database or other centralized storage system. Use an ajax call to pull the newest messages.

Send an ajax call to a php file on your server. You don't specify how your php scripts are running, but what I would do is include other the other php files (which would have functions to process whatever they're supposed to do) and then call the functions from the main file. These functions should return some sort of success/error messages that you can collect in an array. So something like this:
$response[] = firstFileProcessing(); //your function names should be better
$response[] = secondFileProcessing();
$response[] = thirdFileProcessing();
When all the scripts are done processing, do:
echo json_encode(array("responses" => $response));
Then back in your success function for the ajax call, you'd do:
var res = jQuery.parseJSON(response_from_server);
//or if you told ajax to expect a json response,
//response_from_server would automatically be an object based on the json sent
and step through each one to see what php said.
alert(res.responses[0]); //the first file said this
Or you could make your $response from php much more detailed - an array of its own, with $response['success'] = TRUE, $response['msg'] = "Worked!", etc - any amount of data.

Related

Setting up a server-side script to continuously record streamed JSON data from an API in a database?

I am trying to set up a server-side connection to an API that continuously parses and records the API's JSON response in a MySQL database throughout the day. My site is set-up as a Wordpress site, and so any Wordpress specific solutions work too.
I know how to keep a connection open and print the responses as they come in using Python, for example. Something like this works:
import requests
import json
headers = {'Content-Type': 'application/json',
"Authorization": "Bearer api_key_here"}
baseurl = 'http://stream.url/here'
payload = { 'key_id' : 'key'}
r = requests.get(baseurl, params=payload, headers=headers, stream=True)
print(r.headers)
print('\n')
for line in r.iter_lines():
if line:
print(json.loads(line.decode("utf-8")))
The output from the above script trickles out line by line as it comes in from the API server.
For example, suppose I get a response like this every second:
{'type': 'TYPE', 'time': '2019-11-18T21:07:12.422789431Z', 'key1': [{'dat1': '1.10739', 'dat2': 10000000}], 'key2': [{'dat1': '1.10752', 'dat2': 10000000}]}
What I am trying to do now is to set up a server side script (preferably in PHP but I can work with other solutions too) that basically does this, except instead of printing the response, it records it into a database table, in real-time, throughout the day.
I don't have much experience setting up a server side script like this, so not sure where to start.
PHP really doesn't "listen" well. You really have two options:
Cronjob that calls a php script that checks the output and runs every few seconds.
Have your python script POST to somewhere instead of / in addition to print.

Automatically run a PHP script every time a user change a row in MySQL/WordPress database

I'm building a small web app to feed one website from a row of a database in another website (a WordPress based website).
Essentially I have three files: one called outputjson.php that will generate a JSON file called results.json (that live in my WordPress website) and in another website I will make an AJAX request for that file in order to display an announcers section for a radio station (with pictures of the announcer, socials, time).
My problem is that I have to manually initiate the process but I would like to do it automatically, every time anyone will update my database, I want that my file will listen to the event and run the PHP script.
So far my code is:
outputjson.php
<?php
global $wpdb;
if(!isset($wpdb))
{
require_once('wp-config.php');
require_once('wp-includes/wp-db.php');
}
$result = $wpdb->get_results ( "SELECT * FROM " . $table_prefix . "radio_announcer_on_air" );
$fp = fopen('results.json', 'w');
fwrite($fp, json_encode($result, JSON_UNESCAPED_SLASHES));
fclose($fp);
?>
Which will generate a file like:
results.json
[
{
"announcer_id":"19",
"announcer_time_start":"07:00:00",
"announcer_time_end":"08:59:59",
"announcer_photo":"image.jpg",
"announcer_name":"Name",
"announcer_facebook":"",
"announcer_twitter":"",
"announcer_rss":"",
"announcer_mail":"",
"announcer_weekday":"7"
}
]
My last file will live on another server and will make the magic:
announcers.js
$(function(){
$.ajax({
url: "http://otherwebsite.com/results.json",
type: "GET",
dataType: "JSON",
cache: false,
success: function(markers) {
//Do something
}
Any suggestion? I could even consider running this script every day for example, since running it every time someone is going to change my database row (the event) sounds very complicated, at least for my knowledge that I've got so far.
The great thing about consuming a JSON endpoint in a browser is that it does not have to come from a static file.
Consider your results.json example. If this is a static file, then your web server (usually Apache) will detect the json extension and send the appropriate MIME type header to identify its type to the browser. For JSON, that is:
application/json
So, as long as we do the same in PHP, an AJAX call in JavaScript won't notice the difference. In outputjson.php, just add this at the start:
header('Content-Type: application/json');
This is necessary since the web server will see that the file extension is php and will not know what MIME type that corresponds to (since a PHP script can generate a file of any type). Thus, we have to do that manually.
To wire it into your JavaScript, simply point the url parameter to your PHP script:
url: "http://otherwebsite.com/outputjson.php",
I mentioned in the comments that a file could be called something.json.php. To clarify, this naming style is just a convention, and does not actually get the web server to set any headers automatically - you still have to do that in your PHP script. However, the naming makes it very easy for developers and site users to see (in a URL bar or file explorer) what type of content the file generates.
New script
So, your updated script will be something like this:
<?php
header('Content-Type: application/json');
global $wpdb;
require_once 'wp-config.php';
require_once 'wp-includes/wp-db.php';
$result = $wpdb->get_results(
"SELECT * FROM {$table_prefix}radio_announcer_on_air"
);
echo json_encode($result);
?>
Notice that it no longer has to write to a file - it should just output the data to the browser. I removed JSON_UNESCAPED_SLASHES since I did not understand the purpose of that - put it back if you are sure you need it, but the PHP defaults are usually good.
I've removed the if statement as well, since there is no way for the global database variable to be set until the WP libraries are loaded.
Addendum
It would be worth considering how often this endpoint is to be consumed by AJAX, and how much of a load it puts on your database. If it were to contain more than a few hundred rows, you might want to think about pagination, since AJAX operations handling large amounts of data can slow the browser down.
However, it is wise to get it working first, and then you can optimise from there if it proves necessary.

how can i do multithreading in php

i am trying to rewrite my code to support multithreading ,it is a simple code but i can't figure out how to do it,basically what it do is
request the first webpage with curl --> to get a unique id
use the unique id to request another page --> to get a session
use the session to request another page --->sleep() then do it again
now this is what a single thread do,but i want to create a lot of threads in the same time
what i did is ,create 3 sperate files
the first one create 10 sessions and save them in a txt file with other parameters (session1|unique_id1|paramter1|anotherparameter1)
the second file contain this code
$sessions = file('sessions.txt');
$WshShell = new COM("WScript.Shell");
foreach($sessions as $kk => $session) {
if (!empty($session)) {
$oExec = $WshShell - > Run("php requests.php $kk", 0, false);
}
}
it open the txt file,and foreach line it open the requests file with the line number in argv
and in the third file,it take the line number ,and open the sessions file ,retreive the paramater of the session and send requests with that session
so this is how i did my multithreading,but i feel like i wrote a php code with rocks
now i want to rewrite it without having to open 10 sperate php process
There really isn't a native way to do threading in PHP. The approach you took works, but I would approach it differently. It's possible to fork processes in PHP. This I've done and works well.
One approach is to use some messaging system like RabbitMQ and distribute the work that way. Basically an Actor or Pub-sub model.
Another approach that might work well for you would be "pthreads". http://php.net/manual/en/book.pthreads.php
I've not tried this method myself so I cannot give you details as to how well it does or doesn't work.
Hope this helps!

Manipulate PHP-Files before they are parsed

I have managed to write a small, compilable extension for php, that prints "test" on every ZEND_RINIT.
I tested it with an php-file that loads multiple other files, which again load others [...]. The problem is, that the extension just prints "test" once, so I assume it does not fire each time a new file is loaded, how can i get my extension to do so?
Also the event is fired before the file is loaded, that is what i want, but therefore zend_get_executed_filename() is empty and I am not able to get the file content...
My final goal is to validate each file before executing the script. I planned on doing so by validating a file signature that is appended to the file.
Pseudocode Validation:
decrypt(signature, rsa.pub) = sha(filecontent)
Pseudocode Signing:
signature = encrypt(sha(filecontent), rsa.priv)
file += signature
Or is there an even better way to validate the files (i want them to be signed) before executing the script in them?
Thanks in advance!
ZEND_RINIT is called on request startup, that is when you execute your php-file. It will never be called again during execution of your PHP file. Only on next startup.
You have to find a way to hook into all of the file load functions of PHP.

setInterval doesn't seem to re-execute php script

what i'm trying to do is get a variable to update every 5 seconds doing this:
setInterval(document.getElementById("listeners").innerHTML =
"<?php include('../includes/shoutcaststuff.php');
echo $dnas_data['CURRENTLISTENERS']; ?>",5000);
but what happens is the inner html is set but doesn't update every 5 seconds like it should.
my guess is that the php only executes once, but i have no idea if that's the case or not.
and i'm aware i should make a function to do the stuff inside setInterval... i'll clean up the code once i figure out how to make it work.
thanks in advance.
ok... ajax was 'the best' answer since no more than 2 people would be logged in at a time here so server requests isn't such a big deal.
here's how i got it to work:
function lCount(){
$.get("../includes/shoutcaststuff.php",{Count: "TRUE"}, function(data){
document.getElementById('listeners').innerHTML = data;
});
}
setInterval(lCount,5000);
and added this to the end of the php:
if(isset($_GET["Count"])){
echo $dnas_data['CURRENTLISTENERS'];
}
now it works fine.
thanks for the suggestions guys :)
<?php include('../includes/shoutcaststuff.php');
echo $dnas_data['CURRENTLISTENERS']; ?>
This code only executes once when the page is built. For the rest of the times this javascript is called whatever is first echoed will be the value.
Instead of using a static value here, you are going to need to use an ajax request (or a websocket if you want to use html5). The request will then hit your server once every 5 seconds. Keep in mind that this can cause undue load on your server.
Ratchet is a commonly used PHP WebSocket implementation that allows for data to be sent to the client using push technology. This is probably more preferable than using your polling approach.
PHP code is run on the server generating the HTML/JS. Use ajax if you need to run php code once the page has loaded.
Take a look at this for example;
Using this:
setInterval(document.getElementById("listeners").innerHTML =
"<?php echo "1";?>",5000);
Will output this to the browser:
setInterval(document.getElementById("listeners").innerHTML =
"1",5000);

Categories