I am creating a small Bitcoin payment gateway to pay 0.25 BTC and only need 1 confirmation. I have created a form (form.html) which shows a unique random address ($_POST['address']) so on the next page after you hit submit I need it to display a page and do some checks for me... but when I hit submit it just says "waiting for page to load" at the bottom of my browser and doesn't actually load the page up (which has HTML on it), I'm sure this is because of a for loop hogging the page but I'm not sure how to get around it.
My for loop
for ($i=0; $i <= 900; $i++) {
$conf = file_get_contents('https://blockchain.info/q/addressbalance/' . $_POST['address'] . '?confirmations=1');
$seen = file_get_contents('https://blockchain.info/q/addressfirstseen/' . $_POST['address']);
if ($seen != 0) {
if($conf >= 25000000) {
echo "Payment Complete <br><br>";
break;
} elseif ($conf != 0 && $conf < 25000000) {
echo "You Did Not Pay Enough Bitcoins<br><br>";
break;
}
}
sleep(30);
}
I'm pretty rusty with PHP and this is my first attempt in a while, if anyone could point me in the right direction to what I am doing incorrect that would be much appreciated.
Thank you for any time anyone spends on this.
you define i as a loop counter but you are not using it?!
most probably none of the break criteria is fulfilled and you are actually doing a big sleep 900 * 30 sec = 450 minutes
I'm absolutely sure that you don't need this.
not to mention that you have to change some vars in cnf, ini ... if you need a response after that long time
from what I can see, $seen is probably zero by default and/or $conf is < = 0
sleep
for delay in milliseconds, use
usleep
haven't used php for some years, but I believe sleep is in sec.
try not doing front-end checks with back-end language as the first comment under your post says but I can only guess what you are trying to achieve ...
Related
I'm programming my own "smart home" as a learning project.
My code is running fine. I'm looking for help to improve the efficiency and of the code and/or the setup of crontab + php code.
I'm monitoring the energy consumption of my washing machine with a WIFI energy meter. Target is to notify me once the washing machine is completed so I don't forget to clear it.
on my Pi I have a crontab like so:
*/20 7-22 * * * /usr/bin/php '/home/holger/html/plugs/washer.php'
which runs following php code (I simplified for better readability):
[...]/I call the function, of course, but this function does the main task
function loop($maschine, $watt_init, $trashhold){
$max = 75;//max loops to avoid endless runs
$i = 1;//start counter
$tackt = 3;//tact time to check energy consumption
//$trashhold = 4;//ab x Watt kein standby
if ($watt_init < 1 ) {//Machine is switched off if energy consumption < 1 Watt
die;//quit
}
elseif ($watt_init < 2 ) {//Machine is switched off or in standby if energy consumption < 1 Watt
die;//quit
}
else {//Any thing else: Machine is running
while ($i < $max) {//loop as long as max loops are not reached
$watt_current = json_combine(IPplug5);//getting current energy consumption from WIFI energy meter via JSON
sleep(60*$tackt);//sleep and continue every 60s x tact time
$i++;//increase counter +1
//compare actual consumption with defined trashhold
if ($watt_current[0] >= $trashhold) {//continue while energy consumption bigger then trashhold
continue;//repeat loop
}
elseif ($watt_current[0] < $trashhold) {//stop if energy consumption lower then trashhold
break;//stop loop
}
}
echo "Program done. please clear. Runtime: " . $i*$tackt. "Min."
//[...] message me to my telegram bot
}
}
The code is running fine and I'm getting the output I need.
My question is: Is there a better way to do that?
Currently I'm afraid to overload my Pi with too many open php sessions, therefore I'm starting the code only every 20min and also let the while loop sleep for 3 Min. But for improved accuracy I like to run the cronjob more often and also let the while loop sleep only for 30s.
My requirements are to stick to my PI and php code and not to use any available software like Home Assisant.io as it contradicts with my learning approach.
Any ideas or insights welcome.
Ideally it's a not the best approach to handling and measuring power consumption. It would be best if you created an API that accepts events like on/off or threshold hold limit extends from your IP devices. Further you can create logs and store them in databases.
Although, for your current problem here is one alternate solution.
Set your cron that runs every second.
function get_powerConsumption($machine, $watt_init, $threshold)
{
if ($watt_init < 2) {
exit();
}
$time = date("Y-m-d H:i");
$filename = $machine . '_power_consumption.log'; // expecting some machine identification name here. otherwise ignore prefix
$watt_current = json_combine(IPplug5);
if ($watt_current[0] >= $threshold) {
$data = array(
$time,
$watt_current[0]
);
file_put_contents($filename, json_encode($data) . "\n", FILE_APPEND);
} elseif ($watt_current[0] < $threshold) {
$data = array(
$time,
'stopped'
);
file_put_contents($filename, json_encode($data) . "\n", FILE_APPEND);
}
}
Create another cron to look up for stopped events logged in the file. if found process the calculation based on logged data like time and consumption. You can set this cron to run based on your need like every second or minute or after some interval.
Also, handle code to delete old logs, once stopped events found.
In my site there's a JS script, This script contact with external site to load some values related with captcha challenge, After this script loads variables and their values, This script will make a hidden input and this input has a name and id and token value!
The problem is that the script takes time to load, sometimes 6 to 10 seconds! depends on server speed! I made a php function, This function has the ability to check if that script loaded or not, Here is my code
The function check the value of this element $_POST["fc-token"];, If its value wasn't empty that means the script is already loaded
function check_s(){
$session_token = $_POST["fc-token"];
if(!empty($session_token)){
echo "Loaded";
}else{
$counter = 1;
while($counter !== 10){
sleep(1);
$session_token = $_POST["fc-token"];
if(!empty($session_token)){
$counter = 5;
break;
}else{
$counter = $counter + 1;
}
}
}
}
I don't know why this function stopped my whole site! everything won't load like js script and other scripts, And after 10 seconds the script will start loading! Idk why this function didn't allow anything to load!
So Is there a way to solve this matter?
I have a simple script that counts from 1 to 5000 with a for loop. It flushes output in real time to browser and shows a progress bar with %.
What I have: If I leave the page, the process interrupts. If I come back, it starts from 0.
What I want to achieve: If I leave the page, the process continues and, If I come back , it shows the right percentage.
Example: I run the process, it counts till 54, I leave the page for 10 seconds, when I come back it shows me 140 and continues to flush.
Is it possible?
I would suggest you to use server workers - scripts which are intended to run independently from webserver context.
The most common way of doing it - usage of message queues (RabbitMQ, Qless, etc). Event should be initiated by the script in web context, but the actual task should be executed by queue listener in a different context.
What you have asked seems quite simple to do with a session. (Purely assuming on the use case given). This is not running any process in the background, it just simply keep track of the time and show the progress. That's why I said "based on what you asked". If you want to keep track of any real background tasks, then I believe the case would be totally different, and you will have to change the wordings of your question as well ;)
Something like this would do.
<?php
session_start();
$s = &$_SESSION;
$sleep = 1; //seconds
//check if we have a value set in session before, if not set default = 0.
if(!isset($s['last'])){
$s['last'] = 0;
}
//check if we have a last time set in session before. if not set a default = curret time.
if(!isset($s['time'])){
$s['time'] = time();
}
//get the idle time of the user.
$idle = time() - $s['time'];
//start the loop..and set starting point.
$start = $s['last'] + ($idle / $sleep);
for( $i = $start; $i < 100; $i++){
echo $i . '<br />';
$s['last']++;
$s['time'] = time();
flush();
sleep($sleep);
}
Hope it helps!!
Suppose I have something like this:
$count = 0;
foreach($CourseDetails as $course_line) {
print "<tr><td>{$course_line['class_code']}</td>
<td>{$course_line['class_name']}</td>
<td>{$course_line['class_unit']}</td>
<td>{$course_line['class_description']}</td>
<td>{$course_line['class_instructors']}</td>";
$count = $count + 1
if ($count = 10);
$count = 0;
// code that stops script and makes a "Continue?" button pop up on the webpage under the already outputed details
// if the client presses the "Continue?" button, allow the script to continue (jump back into the foreach loop)
}
I'm trying to find a way to stop the script and then make a button saying "Continue?". If the client presses the button, I want the script to continue where it left off. Does PHP have any functions that allow this?
Short answer: no!
This is more of a workflow design issue. I would suggest creating a list of items to execute. Then try to execute them (as they are successfully processed, mark them as complete), if an error is hit, then stop execution and let the user know. If the user wishes to continue, reload the page, and continue executing the items that have not completed from your initial list.
You can't stop the script once the page has been loaded in the browser. You can only create an interrupt condition inside the script. The two ways for "memory" between pages are either passing an URL variable, e.g. start=20, or using $_SESSION variables to remember the last point of interrupt. Better pass the variable over URL so the pages are individually accessible.
Then, in your loop, simply evaluate whether the entries have a number above the last interrupt. The following presumes your courses are in an array with a numeric index, in which case the $count is redundant. If you're pulling them from a database, take a totally different approach...
$start = !empty($_GET['start']) ? $_GET['start'] : 0;
$offset = 10;
foreach($CourseDetails as $course_num => $course_line) {
if ($course_num < $start) continue; // These were already seen.
if ($course_num >= $start + $offset) {
// Interrupt and make a button that links to ?start=$start+$offset.
break;
}
// Here display stuff.
}
I don't very much find too much information over the internet about PHP CLI so I am having a hard time figuring out how to finish my code.
Basically, the application should continue checking the MYSQL database every 2 seconds without exiting, unless otherwise the user entered the letter 'q'.
I started it out by just printing the word 'pro' continuously before I implement MYSQL so my code looked like this:
<?php
fwrite(STDOUT, "This should print word 'pro' continuously\n");
fwrite(STDOUT, "\tto exit, simply press 'q' and enter\n");
do {
fwrite(STDOUT, "pro\n");
}while (fgetc(STDIN) != 'q');
?>
Pretty much when the user entered 'q', the app terminates, but the problem is it only prints out 'pro' once, and when I pressed enter.
fgetc() will block until there is data to read - in other words, when the script reaches the fgetc() call, the execution will halt until the user inputs something.
In order to work around this, you will need to check whether there is any data to read using stream_select(). You can also use stream_select() to limit the MySQL poll to every 2 seconds. A basic framework would look something like this:
<?php
// Do all your init work here, connect to DB etc
$tickerSecs = 2;
echo "Hello! I've started\n";
do {
// Do actual work here
echo "I'm polling the database\n";
// See stream_select() docs for an explanation of why this is necessary
$r = array(STDIN);
$w = $e = NULL;
if (stream_select($r, $w, $e, $tickerSecs) > 0) {
// The user input something
echo "You input something\n";
$char = fread(STDIN, 1);
if ($char == 'q') {
// The user pressed 'q'
echo "You told me to quit\n";
break;
} else {
echo "I don't understand '$char'\n";
}
}
} while (TRUE); // Loop forever
// Do shutdown work here
echo "I'm shutting down\n";
Note that it is likely that you will have to require your user to press q + enter rather than just q because of the nature of the way these things work - and I don't really understand why this is, maybe someone else can provide the missing piece here?
Rather than stopping when Q is pressed, you could use pcntl_signal() to register a handler for SIGQUIT (ie Ctrl-C)