I'm working with the PHP CLI on windows at the moment to write some small desktop command-line apps.
I wanted to know if and how it may be possible to:
Clear the screen (cls would be the normal command but exec() won't work with it)
Change the color, change the color of parts of the output (seen this in programs before)
Make the command line horizontally bigger - things quickly get unreadable
Is any of the above possible from inside a PHP script?
On Windows, in the standard CLI prompt, you cannot output in colour (as in the answer by Spudley).
You can change the size of the window as a user by right-clicking the command window's title bar and selecting Properties, then ammending values in the Layout tab. I do not think it is possible to ammend the width of the CLI within PHP.
You can check the width of the CLI window on Windows using the function I wrote here
See the PHP manual page for working with the commandline
To directly answer each of your bullet points:
There is a comment on that page which gives a function that can clear the screen. I'll quote it here for you:
<?php
function clearscreen($out = TRUE) {
$clearscreen = chr(27)."[H".chr(27)."[2J";
if ($out) print $clearscreen;
else return $clearscreen;
}
?>
There's also another comment which explains how to change the colours. Again, I'll quote it:
<?php
echo "\033[31m".$myvar; // red foreground
echo "\033[41m".$myvar; // red background
?>
and to reset:
<?php
echo "\033[0m";
?>
You should read through the rest of that page for a whole load more suggestions on how to manipulate the CLI.
The only part of your question that leave unanswered is the third bullet point. Sadly, I don't believe you'll be able to do this, and I don't think it's possible to horizontally resize the Windows command line window.
Hope that helps.
I created a small backup script with PHP, and from what I can remember, you can print backspace characters to remove content. Not really ideal though.
Just google'd it: http://www.php.net/manual/en/features.commandline.php#77142
As far as the third question goes, I suggest you witch the default command line to Console 2. It is a great replacement that not only lets you use any width you like (as long as it fits your screen), but also supports command history, tabs, and some UI sugar.
The provided code will not work under Windows because PHP under windows does something to the command window. I am not sure what PHP does but I wrote a simple Freebasic program with only two lines:
cls
end
I then compiled it and ran it under a regular command line window. It cleared the screen without any kind of a problem. I then did the following in PHP:
<?php
echo "This is a test\n";
system( "cls.exe" );
exec( "cls.exe" );
passthru( "cls.exe" );
?>
When I ran the program it did nothing more than just the "This is a test" line. Thus, there is some kind of suppression going on with PHP that looks for and stops any kind of escape sequence from occurring. Until this is fixed in PHP - you will never be able to do a cls, nor use curses, ncurses, or any other library. What has to be done is to integrate something like FreeBasic's windowing methods as some kind of a class (or maybe just a C set of routines) that will open a new window via THAT language's methodologies and use them to do the text window. Then all of the escape sequences will work. Until then - they won't.
What I find weird about this is that PHP was originally written in Perl and Perl will do ncurses on Windows without any problems. Perl will also allow all escape sequences to work. So there is just something being done on the Windows compile that is causing this problem.
Related
I have been using PHP for a while now with my Apache2 web server on my raspberry pi. It works great, but I get tired of always having to think "how do I X in PHP" or "what was the function name for this in PHP".
I am under the strong impression that there should be something equivalent in which I can replace the <?php ?> code with python code, but my search results have been confusing at best.
I am essentially looking for something where I can write whatever python code I want in an HTML script and have it interpreted and executed and its output inserted into the page when it is requested.
For example, to make a table of users from a list in python.
<table><tr><td>User list</td></tr>
<?python
import json
library=json.load(open(some_json_file,'r'));
for user in library:
print "<tr><td>"+user+"</td></tr>"
?>
</table>
I'm under the impression that chameleon can do this with its code blocks as described here,(https://chameleon.readthedocs.io/en/latest/reference.html) but as I look deeper, I get the impression it doesn't work like I am thinking it should. This is the impression I have gotten from all of the template engines I have looked at, as well as WSGI
Are there good drop in python alternatives for PHP? Or are there ways to cleanly wrap semi complex python code into my php in way that doesn't involve writing an additional python script that is called by PHP? I've tried exec() with python -c; but this was less than ideal having to escape all the ' and " characters...
update
The below code works just fine, but can become very slow if run multiple times in a script (takes about 0.4 seconds each time on a raspberry pi3). I have written a program in python that runs in the background and handles requests from php, and runs about 15x faster. I'm now maintaining it here on github.
Original Answer
After messing around I was able to come up with something mostly suitable for what I am trying to do. Inside my php I create a function that executes python scripts.
<?php
function py($s){
exec("python -c '$s'",$arr);
foreach($arr as $v){
echo $v."\n";}
}
?>
Then I use php Heredoc(equivalent to python """ , means I don't have to escape every single double quote) to fill the function:
<?php
py(<<<python
print "Hello world<br>"
s="ello world"
for x in s:
print x+"<br>"
python
);
?>
outputs >>>
Hello world
e
l
l
o
w
o
r
l
d
the only real downside I am experiencing at this point is that this method precludes me from using single quotes anywhere in my python script... :(. I'll get over it.
EDIT
I added a few more tweaks to make this even more useful. The new function is below:
<?php
function py($s,$return=false){
$s=str_replace("'","'\''",$s);
$h=<<<head
def cleanup():
for x in globals().keys():
if not x.startswith("_"):
del globals()[x]
import dill
try:
dill.load_session("pyworking.pkl")
except:
pass
head;
$f=<<<foot
import dill
dill.dump_session("pyworking.pkl")
foot;
if ($return==false){
echo shell_exec("python -c '$h$s$f'");
}
else {
return shell_exec("python -c '$h$s$f'");
}
}
?>
this allows you to use single quotes in the script and invoke the py() function multiple times in the same script and your variables and modules will follow you. At the end of the script you just call the clean up (or using php clear the pyworking.pkl file) and wipe the environment clean.
I also put this function in a file and in my pyp.ini I used the auto_prepend_file=my/file/location to automatically include it, so no need to load it before hand.
Overall I am very happy with this method, especially since I can read php variables inside my python script. Passing objects is as simple as:
<?php
$data_en=json_encode($data);
py(<<<p
import json
data=$data_en
#do something with data
p
);
?>
this would be perfect if I could think of a way to assign values to php variables inside the script, but its not a bad workaround if you want a fusion of php and python or just a way to do everything in python without writing a python webserver (which i have also done).
I am trying to set up omni completion for PHP in vim 7.3 with ctags 5.9~svn20110310 on Ubuntu 12.04.1 (LTS) but I am running into a very strange issue where completion provides radically different predictions for instances of the same class.
I have the following two files:
// Foo.php
class Foo {
public function do_stuff() {
echo 'Working...';
}
}
// index.php
require 'Foo.php';
$f = new Foo();
$f->[cursor position 1]
$g = new Foo();
$g->[cursor position 2]
When the cursor is in position 1 and I press CTRL+X CTRL+O it comples the line with do_stuff( as we would expect. But when I press CTRL+X CTRL+O in the second position I get a list of predictions that starts with key, next, rewind. What am I doing wrong?
Edit: With regard to your specific issue, if you have an old version of phpcomplete.vim, it's possible that you can only properly complete off a variable either by marking it with a special phpdoc tag (see this question) or by regenerating your tags file after declaring the variable.
In all probability, you are doing nothing wrong; the PHP support in ctags is extremely basic and not very rigorous, which unfortunately means the Vim support is lacking, too. A quick look at the ctags module illustrates the problem:
ctags/php.c
That's it. Just a couple of relatively basic regular expressions. That parser stuff at the bottom is not used any longer, and tragically hasn't been for a very long time.
Compounding the issue is the fact that the standard omnicomplete function for PHP in Vim is hackish at best; suffice it to say that it involves switching between all the open windows as part of its completion process (a practise explicitly condemned by Vim documentation). Take a look for yourself:
phpcomplete.vim/autoload/phpcomplete.vim
I have struggled with terrible PHP completion in Vim for a long time now and have determined that nothing short of a complete overhaul will produce a satisfactory result. I've joined the ctags dev mailing list, and I plan to improve the PHP support there before moving on to making Vim's omnicompletion thereof work as properly as it can in an interpreted language. For now, unfortunately, the solution is to wait until the support is better, or fix it yourself.
I have a program on my linux server that asks the same series of questions each time it executes and then provides several lines of output. My goal is to automate the input and output with a php script.
The program is not designed to accept input on the command line. Instead, the program asks question 1 and waits for an answer from the keyboard, then the program asks question 2 and waits for an answer from the keyboard, etc.
I know how to capture the output in an array by writing:
$out = array();
exec("my/path/program",$out);
But how do I handle the input?
Assume the program asks 3 questions and valid answers are: left 120 n
What is the easiest way using php to pass that input to the program?
Can I do it somehow on the exec line?
I’m not a php noob but simply have never needed to do this before.
Alas, my googling is going in circles.
First up, just to let you know that you're trying to reinvent the wheel. What you're really looking for is expect(1), which is a command-line utility intended to do exactly what you want without involving PHP.
However, if you really want to write your own PHP code you need to use proc_open. Here are some good code examples on reading from STDOUT and writing to STDIN of the child process using proc_open:
http://www.php.net/manual/en/function.proc-open.php#79665
How to pass variables as stdin into command line from PHP
http://camposer-techie.blogspot.com/2010/08/ejecutando-comandos-sobre-un-programa.html (this one is in Spanish, sorry, but the code is good)
Finally, there is also an Expect PECL module for PHP.
Hope this helps.
Just add the arguments to the exec line.
exec("/path/to/programname $arg1 $arg2 $arg3");
... but don't forget to apply escapeshellarg() on every argument! Otherwise, you're vulnerable to injected malicious code.
$out = array();
//add elements/parameters/input to array
string $execpath = "my/path/program ";
foreach($out as $parameter) {
$execpath += $parameter;
//$execpath += "-"+$execpath; use this if you need to add a '-' in front of your parameters.
}
exec($execpath);
I'm trying to debug a plugin-bloated Wordpress installation; so I've added a very simple homebrew logger that records all the callbacks, which are basically listed in a single, ultimately 250+ row multidimensional array in Wordpress (I can't use print_r() because I need to catch them right before they are called).
My logger line is $logger->log("\t" . $callback . "\n");
The logger produces a dandy text file in normal situations, but at two points during this particular task it is adding something which causes my log file to no longer be encoded properly. Gedit (I'm on Ubuntu) won't open the file, claiming to not understand the encoding. In vim, the culprit corrupt callback (which I could not find in the debugger, looking at the array) is about in the middle and printed as ^#lambda_546 and at the end of file there's this cute guy ^M. The ^M and ^# are blue in my vim, which has no color theme set for .txt files. I don't know what it means.
I tried adding an is_string($callback) condition, but I get the same results.
Any ideas?
^# is a NUL character (\0) and ^M is a CR (\r). No idea why they're being generated though. You'd have to muck through the source and database to find out. geany should be able to open the file easily enough though.
Seems these cute guys are a result of your callback formatting for windows.
Mystery over. One of the callbacks was an anonymous function. Investigating the PHP create_function documentation, I saw that a commenter had noted that the created function has a name like so: chr(0) . lambda_n. Thanks PHP.
As for the \r. Well, that is more embarrassing. My logger reused some older code that I previously written which did end lines in \r\n.
I have spent several hours trying to find a means of writing a cross platform password prompt in php that hides the password that is input by the user. While this is easily accomplished in Unix environments through the use of stty -echo, I have tried various means of passthru() and system() calls to make windows do the same thing to no avail.
I have tried:
passthru('set /p pass=Password: ');
system('echo %pass% > out.txt');
$pass = file_get_contents('out.txt', 'r');
This seems to hang on the passthru('set /p pass=Password: '); line without allowing me to input any text and must be killed with a Ctrl-c.
I have also tried various methods of fgetc and fgets and printing backspace characters to hide the input since this works in other languages. However, PHP does not appear to be able to interact with text prior to a carriage return.
I would really like to find a way to make this work, is this an impossible task or is this something that can be done?
Note that I am aware that I could wrap the php script in a batch file and pass the password as a command line argument, but that doesn't work for me in this case.
There doesn't seem to be an IOCTL or STTY extension for PHP. I found the following trick here:
<?php
echo 'Password: ';
$pwd = preg_replace('/\r?\n$/', '', `stty -echo; head -n1 ; stty echo`);
echo "\n";
echo "Your password was: {$pwd}.\n";
?>
Here's a Windows solution, using the COM extension for PHP. I tested this on Windows XP with PHP 5.2.6.
<?php
$pwObj = new Com('ScriptPW.Password');
print "Password: ";
$passwd = $pwObj->getPassword();
echo "Your password is $passwd\n";
?>
I think you cannot do that in PHP with the standard library but you can do better :
Catch the first letter, then display a *. Catch the second one, then display two *...
Ergonomically, this is handy because the user can see what he have entered. Security is not at risk because if somebody can see the password one letter by one letter, he can see the guy typing it on the keyboard anyway. But it still prevent somebody from seeing it by accident in one time.