I am trying to get PHP to search a text file for a string. I know the string exists in the text, PHP can display all the text, and yet strpos returns false.
Here is my code:
<?php
$pyscript = "testscript.py";
//$path = "C:\\Users\\eneidhart\\Documents\\Python Scripts\\";
$process_path = "C:\\Users\\eneidhart\\Documents\\ProcessList.txt";
//$processcmd = "WMIC /OUTPUT: $process PROCESS get Caption,Commandline,Processid";
$process_file = fopen($process_path, "r") or die("Unable to open file!");
$processes = fread($process_file);
if (strpos($processes, $pyscript) !== FALSE) {
echo "$pyscript found";
} elseif (strpos($processes, $pyscript) === FALSE) {
echo "$pyscript NOT found :(";
} else {
echo "UHHHHHHHH...";
}
echo "<br />";
while (!feof($process_file)) {
echo fgets($process_file)."<br />";
}
fclose($processfile);
echo "End";
?>
The while loop will print out every line of the text file, including
python.exe python testscript.py
but strpos still can't seem to find "testscript.py" anywhere in it.
The final goal of this script is not necessarily to read that text file, but to check whether or not a particular python script is currently running. (I'm working on Windows 7, by the way.) The text file was generated using the commented out $processcmd and I've tried having PHP return the output of that command like this:
$result = `$processcmd`;
but no value was returned. Something about the format of this output seems to be disagreeing with PHP, which would explain why strpos isn't working, but this is the only command I know of that will show me which python script is running, rather than just showing me that python.exe is running. Is there a way to get this text readable, or even just a different way of getting PHP to recognize that a python script is running?
Thanks in advance!
EDIT:
I think I found the source of the problem. I created my own text file (test.txt) which only contained the string I was searching for, and used file_get_contents as was suggested, and that worked, though it did not work for the original text file. Turns out that the command listed under $processcmd creates a text file with Unicode encoding, not ANSI (which my test.txt was encoded in). Is it possible for that command to create a text file with a different encoding, or even simpler, tell PHP to use Unicode, not ANSI?
You can use the functions preg_grep() and file():
$process_path = "C:\\Users\\eneidhart\\Documents\\ProcessList.txt";
$results = preg_grep('/\btestscript.py\b/', file($process_path));
if(count($results)) {
echo "string was found";
}
You should follow the advice given in the first comment and use either:
file_get_contents($process_path);
or
fread($process_file, filesize($process_path));
If that fix is not enough and there is actually a problem on strpos (which shouldn't be the case), you can use:
preg_match("/.*testscript\.py.*/", $processes)
NB: Really try to use strpos and not preg_match as it's not advised by the documentation.
Well, I found the answer. Thanks to those of you who suggested using file_get_contents(), as I would not have gotten here without that advice. Turns out that WMIC outputs Unicode, and PHP did not like reading that. The solution was another command which converts Unicode to ANSI:
cmd.exe /a /c TYPE unicode_file.txt > ansi_file.txt
I hope this helps, for those of you out there trying to check if a particular python script is working, or if you're just trying to work with WMIC.
Related
I have a php script that reads text files. I use fgetc() to get every character one by one. I open file to read from with fopen(),and then I use file descriptor returned from fopen() as a first argument to fgetc(). I tried to do the same thing with reading from STDIN. I wanted to run the script in a terminal, give it the whole text (that was in a text file before) and press enter. I thought that the script would read it and will run as if it read from a text file, but it doesn't work. It only works when a type every single character alone and press enter after it. Why is that? Is there a possibility to make the script behave the way I wanted? That I can give it the whole text to the terminal at once? Should I use different functions or something?
$inputFile = fopen($path, "w");
while(($char = fgetc($inputFile)) !== false){
dosomething();
}
What I'm trying to do is to replace $inputFile in fgetc()with STDIN.
See http://php.net/manual/en/features.commandline.io-streams.php, second comment
Note, without the stream_set_blocking() call, fgetcsv() hangs on STDIN, awaiting input from the user, which isn't useful as we're looking for a piped file. If it isn't here already, it isn't going to be.
<?php
stream_set_blocking(STDIN, 0);
$csv_ar = fgetcsv(STDIN);
I think it's the same for fgetc. After all it
string fgetc ( resource $handle ) Gets a character from the given file pointer.
Emphasis mine.
See http://php.net/manual/en/function.fgetc.php
...
i've got this snazzy python code:
import subprocess
value = subprocess.Popen(["php","./php/php_runner.php"],stdout=subprocess.PIPE);
the problem is, i have no idea how to check if the php_runner, well, ran. Currently, it has the following salient sections:
if (count($argv) != 4){
die("four arguments are needed\n");
}
and
$returnValue = call_to_another_php_class();
return $returnValue;
So what i want is this:
How do i get the return value, whatever it may be, using python?
You probably are going to tell me to use "PIPE" in the answer, but the (to me, incomprehensible) python docs (http://docs.python.org/library/subprocess.html) state:
Do not use stdout=PIPE or stderr=PIPE with this function. As the pipes are not being read in >the current process, the child process may block if it generates enough output to a pipe to fill up >the OS pipe buffer.
So what do i use then, because while I don't really know what they're barking on about, i sit up and take note about notes in grey boxes. Pity they didn't spell out what i'm meant to do - but, well, what am i meant to do?
the "returnValue" that my php code returns, is that what python is going to pickup as the return value from the function? If not, how do i return that value?
cheers!
UPDATE
Thanks to the given answer, here's the changes i made:
edited /etc/php5/cli/conf.d/mcrypt.ini (actually, this is just a change for ubuntu 10.04, and I changed the first line to begin with a ; instead of a #. That stopped an annoying "we don't like #" error that kept popping up)
in my php, I changed the code to read:
if (count($argv) != 4){
fwrite(STDERR, "four arguments are needed\n");
exit(1); // A response code other than 0 is a failure
}
this puts my error value as an error. the die() command wasn't doing that for me.
changed the python to read:
value = subprocess.Popen(["php","./php/php_runner.php"],stdout=subprocess.PIPE,
stderr=subprocess.PIPE);
print value.communicate();
Yeah, realistically, i'd do an if on value.communicate()[1], becase that is where the errors are.
$returnValue = call_to_another_php_class();
if ($returnValue == 1){ //hah, php has a good return value as 1.
//no problem
} else {
fwrite(STDERR,get_error_from_php_class());
exit(1);
}
booyah!
Since you're using the Popen constructor rather than the call functions, those notes about PIPE don't apply to you.
Use .communicate() as documented to wait for the program to finish and get the output.
I want to convert a pdf file to an image with PHP, but i can't get the command worked. PHP returns a 4. I don't have any kind of idea what that can be.
I am using the next code:
$tmp = system("convert -version", $value);
var_dump($value);
Someone an idea?
try
exec("convert -version 2>&1", $out, $ret);
print_r($out);
it should tell you what's wrong
It looks like the -version flag is telling the convert software (looks like imagemagick) to respond with the major version number of that software. It looks like it is working correctly. You probably need to pass it the right flags to operate properly. I suggest reading the documentation to see what flags are required to convert PDFs.
try using some of the other system functions in PHP to get more detailed output.
exec("convert -version", $output, $value);
print_r($output);
The exec function above will give you all the output from the command in the $output parameter, as an array.
The return status (which will be held in the $value parameter in the exec call above or the system call in your original code) gives you the return value of the executed shell command.
In general, this will be zero for success, with non-zero integer return values indicating different kinds of error. So it appears there's something wrong with the command as you have it (possibly -version is not recognised: often you need a double hyphen before long-hand command-line options).
Incidentally, you may also find that the passthru function is more suited to your needs. If your convert program generates binary image data corresponding to the converted PDF, you can use passthru to send that image data directly to the browser (after setting the appropriate headers of course)
err... aren't you vardumping the wrong result? (I would var dump $tmp, not $value.)
I think the code should read:
$tmp = system("convert -version", $value);
var_dump($tmp);
I am rather new to using the command line and php. That being said I have been trying to figure out how to use ImageMagick with the exec() function. I have this currently,
$command="/usr/local/lib/ImageMagick convert images/a.pdf images/a.png";
if(exec($command)){
echo 'yes';
}
else{
echo 'no';
}
Which is returning 'no'. I believe I am missing something about how to execute convert from the correct directory. Is my $command set up properly? (I was given the path to ImageMagick from my web host, Lunarpages).
I have read through some of the other questions regarding ImageMagick but I haven't found much to help me set up my command.
Thanks for any help,
Levi
What your command is currently attempting to do is execute a program named /usr/local/lib/ImageMagick which I am guessing is not what you were intending. If that is the path to ImageMagick and you want to use the convert utility you need to modify your command to the following:
/usr/local/lib/ImageMagick/convert images/a.pdf images/a.png
At which point it should work without any issues! You may want to dig further into what the convert command can do for you!
use the exec() the correct way as your exec returns a string by default and the execution results is passed back via one of it's parameters as such :
$command="/usr/local/lib/ImageMagick/convert images/a.pdf images/a.png";
exec($command,$output,$result);
if ($result == true ){
echo 'yes';
}
else{
echo 'no, here's what happened with command output';
print_r($output);
}
refer to http://php.net/manual/en/function.exec.php
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.