php command line change text output - php

I want to know is it possible to change some output for special php cli base application to change some value on terminal not echo new one. for example this is cli application.
#!/usr/bin/env php
<?php
$percent = 0;
for ($i = 0; $i <= 100; $i++) {
echo $percent . "\n";
sleep(1);
$percent++;
}
/**
0
1
...
*/
It's a simple app to show the user the percentage. So we must update it after each loop in this example, rather than append it. I want to change percent not show new one.

use \r instead of \n. \r is a carriage return, it will jump back to the beginning of the line without a newline.
$percent = 0;
for ($i = 0; $i <= 100; $i++) {
echo $percent . "\r";
sleep(1);
$percent++;
}
This is working on Windows, Linux and MacOS

Something like this should work for what you need (tested and verified on a Linux (CentOS) machine):
for ($percent = 0; $percent <= 100; $percent++) {
echo $percent;
sleep(1);
// Print one or more backspaces, erasing current character(s)
echo str_repeat("\x08", strlen($percent));
}

This actually depends on your terminal (emulator) type, not on the language used. Have a few tries using the backspace character (0x08) to 'erase' the current content, then output the new content.

Related

How to print current index or for loop in PHP?

The below PHP code returns 12345678910...... at a stretch.
for ($i=0; $i<1000; $i++) {
sleep(1);
echo $i;
}
How can I get it to print only the current loop number instead of printing all numbers together?
This can be easily done in php cli using the backspace character "\x08"
<?php
$length = 0;
for ($i=0; $i<1000; $i++)
{
// delete as much character as the length of the previous number
echo str_repeat("\x08", $length);
sleep(1);
echo $i;
// get the length of the number, so you know how much you have to delete
$length = strlen((string)$i);
}
This is my suggested answer (applicable to browser)
a) I believe the OP wants to have the output generated to the browser interface
b) To generate the output of the count during the 1-second sleep, we need to flush the output before each sleep
c) In a browser interface, it is not possible to generate a backspace, so let's do a javascript trick to update the div
<div id=output1></div>
<?php
$index=0;
while($index < 1000) {
ob_start();
echo "<script>document.getElementById('output1').innerHTML=" . $index . "</script>";
ob_end_flush();
#ob_flush();
flush();
sleep(1);
$index++;
}
?>

Carriage return PHP multi line

I'd like to do a multi line carriage return with php for the command line.
Is this possible?
I know already how to achieve it with one line print("\r") but it like to know how to do this on multiple lines.
The printed data should look like this:
$output = "
Total time passed: 34, \n
Total tests: 14/523
";
print($output . "\r");
It works for a single line so that there is not a new line added every time it is printed in the loop.
When i use it with a PHP_EOL, or \n i'm getting new lines all the time. I just want two lines to show up while updating it.
You can do this using ANSI escape
char [F
As example:
for ($i = 1; $i < 5; $i++) {
$prevLineChar = "\e[F";
sleep(1);
echo "$i\nof 5\n" . $prevLineChar . $prevLineChar;
}
You are looking for PHP_EOL, one for each carriage return. See here: https://stackoverflow.com/a/128564/2429318 for a nice friendly description.
It is one of the Core Predefined Constants in PHP
PHP_EOL (string)
The correct 'End Of Line' symbol for this platform. Available since PHP 5.0.2
You could write something like:
print("\n\n\n\n\n");
but what if you want to print a dynamic number of new lines :)
try this function:
function new_lines($n) {
for($i = 0; $i < $n; $i++) { echo PHP_EOL; }
}
call it like so :
//print 100 new lines
new_lines(100);

Display Real-Time Values

Say I have the following:
for ($i = 0; $i < 10; $i++) {
echo $i;
sleep(1);
}
Now, this will display:
0123456789
However, it will take 9 seconds to load, and will not display real-time.
How would I display it so it would be:
0(1 second)2(1 second)3(...)
My second question involves overwriting the current data on the page.
For example, say I have the same code as above. However, I want to display each number as itself. So the page would be:
0
Then after 1 second
1
And so on.
for ($i = 0; $i < 10; $i++) {
echo $i."\n";
$timeFirst = strtotime(date());
sleep(1);
$timeSecond = strtotime(date());
echo ($timeSecond - $timeFirst)." second(s) \n";
}
You can only do it with Client side script such as javascript. DOM loads only after the complete execution of your server side script.
There is no way you can execute each command and render the output to the web browser, unless you are doing it at CLI or doing it via Client Side.
Try this
for ($i = 0; $i < 10; $i++) {
echo $i;
flush();
ob_end_flush();
sleep(1);
}

Run A PHP function only 30% of Time

I need help creating PHP code to echo and run a function only 30% of the time.
Currently I have code below but it doesn't seem to work.
if (mt_rand(1, 3) == 2)
{
echo '';
theFunctionIWantCalled();
}
Are you trying to echo what the function returns? That would be
if(mt_rand(1,100) <= 30)
{
echo function();
}
What you currently have echoes a blank statement, then executes a function. I also changed the random statement. Since this is only pseudo-random and not true randomness, more options will give you a better chance of hitting it 30% of the time.
If you intended to echo a blank statement, then execute a function,
if(mt_rand(1,100) <= 30)
{
echo '';
function();
}
would be correct. Once again, I've changed the if-statement to make it more evenly distributed. To help insure a more even distribution, you could even do
if(mt_rand(1,10000) <= 3000)
since we aren't dealing with true randomness here. It's entirely possible that the algorithm is choosing one number more than others. As was mentioned in the comments of this question, since the algorithm is random, it could be choosing the same number over, and over, and over again. However, in practice, having more numbers to choose from will most likely result in an even distribution. Having only 3 numbers to choose from can skew the results.
Since you are using rand you can't guarantee it will be called 30% of the time. Where you could instead use modulus which will effectively give you 1/3 of the time, not sure how important this is for you but...
$max = 27;
for($i = 1; $i < $max; $i++){
if($i % 3 == 0){
call_function_here();
}
}
Since modulus does not work with floats you can use fmod, this code should be fairly close you can substitute the total iterations and percent...
$total = 50;
$percent = 0.50;
$calls = $total * $percent;
$interval = $total / $calls;
$called = 0;
$notcalled = 0;
for($i = 0; $i <= $total; $i++){
if(fmod($i, $interval) < 1){
$called++;
echo "Called" . "\n";
}else{
$notcalled++;
echo "Not Called" . "\n";
}
}
echo "Called: " . $called . "\n";
echo "Not Called: " . $notcalled . "\n";

ncurses not deleting character

Alright, I'm working on a (supposed-to-be) simple counting script using ncurses. Everytime it increments the number, I need it to delete the previous number before adding another number, so that it updates rather than appends.
Here is my code:
<?php
ncurses_init();
$i = 0;
$nStr = "Number: ";
ncurses_addstr($nStr);
ncurses_refresh();
for ($i=0; $i < 100; $i++)
{
$iLen = strlen($i);
for ($j=0; $j < $iLen; $j++)
{
ncurses_delch();
}
ncurses_addstr($i);
ncurses_refresh();
sleep(2);
}
ncurses_end();
?>
Currently when I run it, it outputs like this: Number: 01234[...]
Anyone see where my problem is and how I can fix it?
ncurses_delch() forward-deletes. If you want to move the cusor back one column then output \b instead.

Categories