Linux command populate file from php script output - php

I have a PHP script which generates some complex XML output. The XML is currently being output as a webpage but instead of a webpage I need it as a physical file on my server.
So, I wonder if there is a way to pipe the output of my PHP script into the Linux touch command so that my PHP output populates, or overrides, a file on my server?
I am currently trying the following code without success:
touch test | php xml_reports.php

You can actually run PHP from the command line.
php filename.php
So if your php file consisted of:
<?php
echo "Hello World";
?>
The output would be "Hello World" (without the quotes) in your terminal. So if you were writing an application in PHP, try and think about how you would approach it without the browser rendering your output. I hope that helps.
[edit]
You might also want to look into shell_exec. (http://php.net/manual/en/function.shell-exec.php)

Assuming I understand your question correctly, here is a solution. In this case however, rather than piping the PHP output, the PHP code itself outputs a copy of the file on the server. I'm not sure how vital it is that this is done through a linux pipe. Also note that this solution is copied from http://forums.codewalkers.com/showpost.php?p=40350&postcount=3.
1) at the very start of your script put this line :
ob_start();
2) at the very end of your script, put this:
$page = ob_get_contents();
ob_end_flush();
$fp = fopen("output.html","w");
fwrite($fp,$page);
fclose($fp);
And, bam, you should have the whole page in a file called output.html.
Now, one thing you need to be sure of is that the webserver server can
write the file output.html. That means you need to make sure the
webserver has the permissions to write in whatever directory you plan
to store that file in.
How does it work? Basically, it just buffers all output from your
script. Then, you store that buffer into a string. Then you send the
buffer to the browser. Then you store that string in a file...

Related

Catch when php file written to

I would like to know if its possible to force PHP to execute as a file rather than being overwritten?
I have set the sendmail -X option for logging which will happily log to a file. When I set it to point to a PHP file it appended to the actual file. Is there anyway (I'm using Ubuntu) to effectively run the file rather than it being written to?
The file currently reads (which I would like to execute):
<?php
$pointer = fopen('php://stdin', 'r');
file_put_contents('/home/www/dev1/log.log',$pointer);
?>
If you are using Bash, you can try process substituion:
sendmail other-args -X >(php your-php-file.php)
This will pass the contents to your PHP file's stdin directly.
However, use stream_copy_to_stream, because if you use stream_get_contents or other one-time functions like that, nothing will be written until the process closes.

Octave script through php windows

I am trying to run an octave script through PHP. I already googled and found some results but none of them are working for me. I tried with exec() and system(). I even created a batch file which calls 'octave myScript.m" and called this bat file using system() of PHP but it doesnt seem to work. In the browser page I am just seeing 'C:/FOLDER_PATH>octave myScript.m". The octave script simply creates a new file and writes some text to it. When i directly run the bat file (by double-clicking on it), the file is getting created properly. I also added folder path to octaverc file but it doesnt seem to work. I need to do some image processing in octave for which I already wrote the script. I need to invoke this script on a client request and send the result to back the client. I am checking the invocation process through a sample script which as I mentioned earlier creates a new file. What am I doing wrong?
My php code is this:
$cmd = "cmd /c C:\PATH_TO_BAT_FILE\myBat.bat";
exec($cmd,$output);
system($cmd);
echo implode ("\n",$output);
Note that my path contains double backslashes to avoid escape sequence characters
My bat file is this
octave temp.m
My octave code(temp.m) is this
fid = fopen("helloScript.txt",'w');
fprintf(fid,"Hello world!");
fclose(fid);
Ouput on the webpage is this:
C:\PATH_TO_BAT_FILE>octave temp.m C:\PATH_TO_BAT_FILE>octave temp.m
I can see in the task manager that a new process is getting created whenever I run the PHP script in browser (I am guessing that it is cmd).
Also, when i change my bat file to
echo hello
I am able to see the following in my browser page
C:\PATH_TO_BAT_FILE>echo hello hello C:\PATH_TO_BAT_FILE>echo hello hello
So this could mean that the bat file is getting executed properly. But when I replace the bat file script with 'octave MY_FILE.m' I am not able to see the output. It may mean that my octave is not configured properly? or is there something I am missing?
Any help would be appreciated.
Thanks
If you are going to run the batch file to create it in php then the php command should be like this.
exec('cmd.exe /c C:\path\to\test.bat');
This is embarassing but I solved it by giving full path. In the bat file I specified the complete path of the octave.exe (C:\Software\PATH_TO_OCTAVE.EXE) and the complete path of the '.m' file.
In my php, I just used exec()

Make output of cli based PHP script viewable from web without piping to a file?

I have a command line PHP script that runs constantly (infinite loop) on my server in a 'screen' session. The PHP script outputs various lines of data using echo.
What I would like to do is create a PHP web script to interface the command line script so that I can view the echo output without having to SSH into the server.
I had considered writing/piping all of the echo statements to a text file, and then having the web script read the text file. The problem here is that the text file will grow to several megabytes in the space of only a few minutes.
Does anyone know of a more elegant solution?
I think expect_popen will work for you, if you have it available.
Another option is to used named pipes - no disk usage, the reading end has output available as it comes.
The CLI script can write to a file like so:
file_put_contents( '/var/log/cli-log-'.date('YmdHi').'.log', $data );
Thereby a new log file being created every minute to keep the file size down. You can then clean up the directory at that point, deleting previous log files or moving them or whatever you want to do.
Then the web script can read from the current log file like so:
$log = file_get_contents( '/var/log/cli-log-'.date('YmdHi').'.log' );
As Elias Van Ootegem suggested, I would definitely recommend a cron instead of an constantly running script.
If you want to view the data from a web script you can do a few things....one is write the data to a log file or a database so you can pull it out later....I would consider limiting what you output if you there is so much data (if that is a possiblity).
I have a lot of crons email me data, not sure if that would work for you but I figured I would mention it.
The most elegant suggestion I can think of is to run the commands using exec in a web script which will directly output to the browse if you use : http://php.net/manual/en/function.flush.php

Passing a valid path to Python from PHP

I have a Python program that parses files, takes a path as and argument and parses all files in the given path and all sub directories - using os.walk(path). I want to call this from my php Web App, so the user can specify a path, which is then passed as an argument to the parser. (Passing a path is ok because its all on an internal network).
I can call the parser fine and pass the arguments ok using popen(), but the path that the Python program receives is always invalid. I have had the php script output the command it is sending to the browser. If I copy and paste that command into a command window, the parser works fine.
I know the path the php script passes is invalid from the result of os.path.exists(path) in the Python script
This is the code to call the Python program:
$path = $_REQUEST['location'];
echo "Path given is: ".$path;
$command = 'python C:\Workspaces\parsers\src\main\main.py '. intval($mode).' "'.$path.'"';
echo "<p>".$command."</p>";
$parser = popen($command, 'r');
if ($parser){
echo "<p>Ran the program</p>";
while (!feof($parser)){
$read = fgets($parser);
if (!$read)
echo "<p>Reached end of file</p>";
else
echo "<p>".$read."</p>";
}
}
The command echoed in the browser is like:
python C:\Workspaces\parsers\src\main\main.py 2 "I:\Dir1\Dir2\Dir3"
Where the 2 is just another argument to the script and $_REQUEST['location'] is defined from an input text box in a form on the calling page.
This is on a Windows system, so I am assuming this has something to do with the backslashes in the path.
Basically, I am unsure as to how all the backslashes are being handled. I would like to understand how strings containing backslashes are sent to the php page, and how they are sent again using popen(). I think the result being printed to the browser is not the raw command string, and I can't be sure how many backslashes are really in the command being issued by popen().
If anyone has any ideas I'd really appreciate it.
Edit:
So in the Python program the path is used as follows:
nfiles=0
print 'Parsing all files in directory tree '+path+"<br />"
start = time.time()
if not os.path.exists(path):
print "<p>Path is NOT REAL!!!</p>"
else:
print "<p>Path IS real!</p>"
for root, dirs, files in os.walk(path):
for f in files:
file = os.path.join(root,f)
print file
nfiles+=1
...Code to run parser...
print nfiles, "Files parsed<br />"
This is echoed back to the browser from the $read variable.
Output of that is:
Parsing all files in directory tree I:\Dir1\Dir2\Dir3
Path is NOT REAL!!!
0 Files parsed
This is identical to the output if the command is run from the command line (the command being copied from the browser and pasted into the cmd window). EXCEPT, when run that way the path IS real, and all the files are parsed. (and in the command window the html markup shows too)
The web server and parsers are hosted on my local machine.
Check to see what user the PHP server is running as. If I:\ is a network drive, don't expect those to be mapped under that user. Use a UNC path instead.
Things to try:
a different path (we know C:\Workspaces\parsers\src\main\ works, why don't you try that?)

How do I escape a PHP script to an external editor and return afterwards?

Specifically I have a PHP command-line script that at a certain point requires input from the user. I would like to be able to execute an external editor (such as vi), and wait for the editor to finish execution before resuming the script.
My basic idea was to use a temporary file to do the editing in, and to retrieve the contents of the file afterwards. Something along the lines of:
$filename = '/tmp/script_' . time() . '.tmp';
get_user_input ($filename);
$input = file_get_contents ($filename);
unlink ($filename);
I suspect that this isn't possible from a PHP command-line script, however I'm hoping that there's some sort of shell scripting trick that can be employed to achieve the same effect.
Suggestions for how this can be achieved in other scripting languages are also more than welcome.
You can redirect the editor's output to the terminal:
system("vim > `tty`");
I just tried this and it works fine in windows, so you can probably replicate with vi or whatever app you want on Linux.
The key is that exec() hangs the php process while notepad (in this case) is running.
<?php
exec('notepad c:\test');
echo file_get_contents('c:\test');
?>
$ php -r test.php
Edit: As your attempt shows and bstark pointed out, my notepad test fires up a new window so all is fine, but any editor that runs in console mode fails because it has no terminal to attach to.
That being said, I tried on a Linux box with exec('nano test'); echo file_get_contents('test'); and it doesn't fail as badly as vi, it just runs without displaying anything. I could type some stuff, press "ctrl-X, y" to close and save the file, and then the php script continued and displayed what I had written. Anyway.. I found the proper solution, so new answer coming in.
I don't know if it's at all possible to connect vi to the terminal php is running on, but the quick and easy solution is not to use a screen editor on the same terminal.
You can either use a line editor such as ed (you probably don't want that) or open a new window, like system("xterm -e vi") (replace xterm with the name of your terminal app).
Edited to add: In perl, system("vi") just works, because perl doesn't do the kind of fancy pipelining/buffering php does.
So it seems your idea of writing a file lead us to try crazy things while there is an easy solution :)
<?php
$out = fopen('php://stdout', 'w+');
$in = fopen('php://stdin', 'r+');
fwrite($out, "foo?\n");
$var = fread($in, 1024);
echo strtoupper($var);
The fread() call will hang the php process until it receives something (1024 bytes or end of line I think), producing this :
$ php test.php
foo?
bar <= my input
BAR
system('vi');
http://www.php.net/system

Categories