PHP via CLI throws error however works fine from browser - php

This particular PHP file works perfectly when executed via the browser. However, I'd like it to run on task scheduler in Windows so I set the scheduler to launch php.exe and point it to the correct file.
Task scheduler is basically doing the same thing as if I type it directly into the CLI I believe. Now, it seems to have worked a few times but now it repeatedly fails even when I manually call the task via CLI.
The relevant code is:
include_once("simple_html_dom.php");
$results = ....Some CURL Commands to retrieve data....
$html = str_get_html($results);
foreach($html->find('tr') as $tr)
{
....do stuff....
}
In CLI it says
Fatal error: Call to a member function find() on a non-object in C:\php\report.php on line...
Why does CLI find fault here and browser does not? Again, this has worked once or twice on CLI so it might some kind of time-out setting.

When you run the script on CLI, did you check if file_get_html() is returning FALSE?
If that is the case, maybe the script can't reach the resource from the terminal using curl for some reason (e.g.: proxy settings).
Make sure to check that case on what you get from that function with something like:
$html = str_get_html($results);
if ($html !== FALSE) {
// treat the success case.
}

All your answers led me to figure out the problem. I investigated the permissions angle but that didn't solve it. There is another 'include' file I have called common_functions.php which I also include. Permissions on that also didn't solve the problem.
However, the curl function is actually located in common_functions. Upon investigating that file, it contains references to cookies.txt where the path was not absolute. I had not setup my environment variables correctly so CLI could not find the cookie which made the Curl function fail.....I corrected and it works now.
Lesson learned. Thank you all for the clues you provided.

Related

getting Could not open input file when trying to call php script from shell_exec

I am trying to build a small custom task scheduler. Basically the idea is I have cron run my process script, which looks in the database and finds any scheduled tasks that are ready to run, and runs them. So I think the best way to do this would be to try to launch the tasks "in the background" by way of shell_exec and using > /dev/null, which I understand makes it so the initial script (the process script) doesn't wait for the task scripts to complete.
So first, if there is a better way to achieve this, I'm open to suggestions. Though note I am on php 5.3 so there may be some options in 5.4 and up that I don't have access to :(
However here's the question at hand:
I am testing on WAMP on my windows machine and I am trying to make a call that looks like this:
shell_exec("php $path$base_url$querystring > output_test.txt 2>&1 &");
$path is the full windows path to the script
$base_url is the base url of the script I am calling
$querystring is of course the query string being passed to the task script
I am also outputting to output_test.txt which creates such file in same directory, where I get the following error:
Could not open input file:
C:\xampp\htdocs\email\batch_email_send_u2u.php?dealer=7
Yes I realize the path references an xampp installation, but that is not the issue - all the wamp files are executing from there and everything else has worked like this for years - it was just set up this way to support a legacy setup.
It seems to me shell_exec is locating and running php, it's just that it can't open the referenced script. Can't figure out why.
Also I need to eventually get this working on a real linux server so any advice on how to make that happen would be greatly appreciated!
Found a solution! Special thanks to dan08 for getting me set on the right path.
Ultimately I found the answer in this thread: Pass variable to php script running from command line
I ended up using the argv[] array as described in that post and with a little tweak to the script I'm calling it works like a champ now.

How do I know when the task from command line is finished?

This is really important as I could not find anything I am looking for in Google.
How do I know when the application (or is it more appropriate to call it a task?) executed by a command line is done? How does the PHP know if the task of copying several files are done if I do like this:
exec("cp -R /test/ /var/test/test");
Does the PHP script continue to go to next code even while the command is still running in background to make copies? Or does PHP script wait until the copy is finished? And how does a command line application notify the script when it's done (if it does)? There must be some kind of interaction going on.
php's exec returns a string so yes. Your webpage will freeze until the command is done.
For example this simple code
<?PHP
echo exec("sleep 5; echo HI;");
?>
When executed it will appear as the page is loading for 5 seconds, then it will display:
HI;
How does the PHP know if the task of copying several files are done if I do like this?
Php does not know, it simply just run the command and does not care if it worked or not but returns the string produced from this command. Thats why it better to use PHP's copy command because it returns TRUE/FALSE upon statistics. Or create a bash/sh script that will return 0/FALSE or 1/TRUE to determine if command was successful if you are going this route. Then you can PHP as such:
<?PHP
$answer = exec("yourScript folder folder2");
if ($answer=="1") {
//Plan A Worked
} else {
//Plan A FAILED try PlanB
}
?>
It waits until the exec call returns, whatever it returns.
However it might be that the exit call returns although the command it has started has not yet finished. That might be the case if you detach from the control, for example by explicitly specifying a "&" at the end of the command.

Bizarre file_get_contents() behavior with plain-text files & no extension?

I've been working on a local app over the last few days and I've noticed that one of my 'exec()' functions to call an external program didn't fire correctly. Upon further investigation it was obvious that the program did execute, but it quit prematurely as an important line utilizing 'file_get_contents()' didn't retrieve the contents of the file specified.
The file is a plaintext file without an extension. I'm guessing that 'file_get_contents()' is treating the file as a directory since there is no extension? It's strange because if I manually execute the same program from a web browser, everything works perfectly.
Here's an example line for clarity -
while(file_get_contents('plaintextfile') == "something"){
/// Do This
}
The above works just fine when I visit /program.php from a web browser, but when calling it like this it gives me a file/folder not found error for 'plaintextfile'.
exec('php /program.php', $output);
foreach($output as $output){
print $output . "<br>";
}
Thanks in advance to anyone who can shed some light on this situation. I'm really puzzled by this...
PHP as executed from the browser and executed by the command line (in the exec() call) may use different php.ini configurations, and may have different file search paths. The best course of action is to supply the full path to plaintextfile.
if(!file_get_contents('/path/to/plaintextfile')){
// file couldn't be read
}

Problem with passthru on server

I have a problem trying to run passthru function in my php code (Joomla module). the code is following (this is only a snippet)
ob_start();
passthru("/usr/bin/whois 85.70.231.130 | /usr/bin/grep 'address:'",$code);
$whoisData = ob_get_contents();
ob_end_clean();
$whoisData = str_replace("address:", "", $whoisData);
$whoisArray = split("\n",$whoisData);
echo trim($whoisArray[1]);
when I run this on my localhost, it echoes what it should, but when I run this code on the production server, it echoes nothing and the $code variable contains 127 (command not found). I tryied add absolute paths to these commands into the passthru function, but it didn't helped. Interesting is, that when I run the code right from terminal via ssh and php command, it runs well, but when it's called from application context it doesn't. Does anybody know what I should to do?thanks
SOME EDITS..
safe_mode is on
webserver does not see into /usr/bin and /bin/ folders so what is the best way how to run these commands from php?
usr/bin/grep doesn't look like a valid path to a command.
The missing / at the beginning of the path to the second command might explain the command not found error... even if the first whois command is found.
Have you looked to see if your webserver / php is running chrooted?
print_r(glob('/*'));
if (file_exists('/usr/bin/grep') && file_exists('/usr/bin/whois')) {
print "maybe its a permissions thing?\n";
} else {
print "can't see executables required\n";
}
should give you a clue.
So I have already solved my problem with phpwhois library. I seems like with my server configuration is it unlikely that these functions will be working well. So thanks for your help:)

Why has my PHP system() command stopped returning output to my scripts ... i used to work!

I have a PHP script that calls a .bat file using system(). The output is written to the screen and I derive some values from parsing this output. This is running on windows 2003 IIS server. PHP v5.2.0
Specifically I am using this script to launch an Amazon EC2 instance and assign an IP address to it. It has worked great for me so far but recently the problem started.
Here is the code
$resultBatTemp = system("cmd /C C:\Inetpub\ec2\my_batch_file_to_launch_instance.bat");
$resultBat = (string)$resultBatTemp;
$instanceId = substr($resultBat, 9, 10);
...
Once I have this instace Id I can run another batch file that calls associates an ip address with this instance. It would appear that the instance does get launched but I never get the output on the screen.
For some reason this has all stopped working, the page freezes and never refreshes. I also need to completely exit safari or mozilla otherwise all pages from the website fail to load. Only when I relaunch the browser can i view the website again. I've connected to the webserver that hosts these scripts and checked PHP error log but nothing shows there. I've opened a DOS prompt and entered the code from the bat file that way and it connects to amazon and launches the instance fine. Ive isolated this bit of code and removed the system command and the rest of the script runs fine, so it appears that the hold up is with outputting the results of the bat file.
Recently I have purchased a new domain name for the site so this script is running from this domain. Might this cause the problem?
thanks
------------------------------------------------UPDATE-----------------------------------------------
Well hope this helps someone, I didnt find out what was wrong but created a new PHP file with a simple system command that called a .bat file, and a non-existent .bat file expecting to get an error back but nothing - just the usual hang for ages. So I restarted IIS and this fixed the problem. Dont know what was wrong but that did the trick.
Maybe first check what the system() call returns. According to documentation it will return FALSE in case of failure. Also, including your my_batch_file_to_launch_instance.bat in the question might help in solving it.
Try using the passthru function
Also make sure that all your commands are safe use escapeshellarg() or escapeshellcmd() to ensure that users cannot trick the system into executing arbitrary commands.

Categories