Cronjob doens't understand the code to execute? - php

I have set up a cronjob which updates a bunch of contracts in a certain system. When I run the PHP-script in a browser it all works fine, but when the cronjob has to do the trick it fails. I'm kinda stuck on this one since I don't have a lot of experience with cronjobs (heck.. I can only set them up in DirectAdmin).
My PHP scripts has some includes to some classes, these includes work properly (i've tested it by sending mails to myself line by line). When the base-classes are included I have a class which handles autoloading. When I do something like Class::GetInstance() it fails.
My cronjob looks like:
* * * * * /usr/local/bin/php /home/username/domains/domain/public_html/path/to/script.php
What can I do to fix this? Perhaps not run it via php, but by a browser or something? I'm sorry if this is a stupid question, but I don't know this ;)

Remeber that when PHP is executed on CLI with /usr/local/bin/php you do not have the $_SERVER variable setted properly! I had that problem too because my script had to use $_SERVER['DOCUMENT_ROOT']. As said, try to run it in a normal shell to see if it works. Alternatively you can change your cronjob command to:
wget -q http://yourdomain.com/path/to/script.php
Usually this works well because it is just identical to fetch that URL from a normal browser.
wget man page here: http://linux.die.net/man/1/wget

You can't always call the php file directly that expects to be called via HTTP. Judging from path, it's a part of website, which is normally executed by browser, hence I'ld set the cronjob up to not to be directly called by php-cli, but rather by doing a curl request to the website's URL.

"it fails" is not the problem description one can call a suffucient one.
add this line in your crontab file
MAILTO=your#mail
and run your jobs.
You will get the script output and be able either to correct your code or ask a sensible question.
You may also redirect stdout and stderr to a log file

Related

set up Cron job to run PHP script

I know this question has been asked before, but none of the answers are working for me.
I'm trying to run a simple PHP script every night at midnight. I created a file called "autoDelete.php" that contains just this code:
<?php
include 'my-database-connection.php';
mysql_query("DELETE FROM meetings WHERE indexDate < NOW()");
?>
I know this script is working because if I navigate to it in a browser, it does what it should.
I then set up the Cron job (via GoDaddy cPanel) to run every minute, with a command to run the script using this:
* * * * /usr/bin/php -q /home/username/public_html/autoDelete.php
However, this is not working. I suspect this has something to do with whatever precedes the "/home" in the command.
Some things to check:
1) cron jobs' default "working directory" is the home directory of the user ID they're running under. That'd most likely be /home/username in this case. That means if you have any relative-pathed include/require commands, they're going to be relative to /home/username, NOT /home/username/public_html. Make SURE that all necessary files are accessible.
2) You're simply assuming the query call succeeded. That's exactly the wrong the thing to do. Calls to external resources (DBs in particular) have exactly ONE way to succeed, and a near infinite number of ways to fail. ALWAYS check for failure, and treat success as a pleasant surprise.
Combining these two (failing to include your connection script, and failing to check for failure), and you end up with what you've got: "nothing" happening. At least try something like
mysql_query(...) or die(mysql_error());
^^^^^^^^^^^^^^^^^^^^^^
The error message will become your script's output, and get emailed to the controlling account's mailbox.
I've had issues in the past with running PHP scripts in a cron job when trying to invoke the PHP binary directly. My solution was to use wget in the cron job since the script was servable by Apache anyway (0 0 * * * wget url/of/script.php). Apache already has the right PHP environment set up so might as well just ask it to handle the job.

Execute a php command from another php file

I having a simple problem, I guess.
I am working on an iPhone app which I can send ASIHTTPRequest to my php server (with go daddy). The php script then gets the command and run like:
$this->pdo->beginTransaction();
//do some other simple works
exec ('/usr/local/bin/php -f /path/to/my/script/test.php') ;
$this->pdo->commit();
which is suppose to run another php file within my own server (dedicated)!!! But it does NOT do anything. It does work with curl_exec() though, but I want to use another method which I can put it to work in the background server.
My planning was that I want to send too many APNS (notification) but instead of waiting for the whole list to be done, it is better to get back and let the work done in the background!! How can I do that.
When I got connected using SSH command line. I can easily call "test.php" and it works so fine. But I can not do the same thing from the above php code.
Any help is appreciated.
Use PHP Include? That will run the script.
Put something like this inside an IF Statement.
include 'YourPage.php';
My first thought is that GoDaddy might not allow exec() to be run for security purposes.

Getting cron job error because of <?php tag

I've set up a cron job to run. It executes a php file which is named cronj.php
But it doesn't work and cron job notification I get is:
/root/website/myworld/blabla/cronj.php: line 1: ?php: No such file or directory
And line 1 in that file is simply a php tag <?php I don't know how
Cron is executing the file as if it was a shell script. Normally you would put in a shebang line (like #!/usr/bin/env php) at the top of the file so that the shell knows how to invoke it, but PHP doesn't like it - as it outputs everything outside its tags. Thus, instead of this:
0 3 * * * /mypath/myscript.php ...
try this:
0 3 * * * /usr/bin/env php /mypath/myscript.php ...
or use #Ravenex's trick.
EDIT I was just rightly admonished for assuming PHP behaves in a consistent way. Apparently, shebang does work in PHP. My apologies to #chess007.
We use cron to run nightly tasks in a php facebook game. We do it by using curl like this:
/usr/bin/curl http://www.ourdomain.com/page.php
If I remember right we had some issues using localhost to try to avoid external lookups. Also we tried using php command line execution, which mostly worked but caused a few strange bugs.
Try to call the web url (http://.....).
It's apparently not parsing it as an PHP script.
Edit:
Please show use the cronjob you used, to verify my hunch was right.
Use this to set your cron and also give email address in your cron setting Cpanel so that you get an email when cron runs successfully
wget -O - http://YOURSITE/cron.php

Can't run shell script from php web script

I am trying to run a shell script from a php script.
I have complete control of the environment (unix on mac), I should have all the permissions, etc. set correctly.
The web script is in /htdocs/
The shell script can be executed from anywhere so when I go to /htdocs/ in the shell, I can easily run it like this:
$ my_shellscript
.. but when my php script (which is located in htdocs) tries to call it:
shell_exec('my_shellscript');
I get nothing.
I have proven the script can be called from that location and I have temporarily granted full access to try to get it working somehow. I am going crazy, please help.
If you know of some other way of triggering a shell script via the web that would be fine.
Thanks in advance.
well i got few weeks same problem, the solution is to check if the apace has the permission to execute your script. You could also try to run the script in php cli.
Since it is a shellscript, it needs to be invoked with the path prefix. My guess is you need to do this:
shell_exec('./my_shellscript');
First thing: make sure php isn't running in Safe Mode
Next thing: Try running it with the exec() function and using the full path (e.g. /var/www/htdocs/my_shellscript)
Try doing
echo shell_exec('my_shellscript 2>&1');
which will capture the script's stderr output and print it out. If something inside the script is failing, this output would otherwise be lost when not being run interactively.

How can I troubleshoot why my PHP script won't work in cron when it does from the command line?

I've got a script that calls two functions, A and B, from the same class. A creates an Amazon virtual server and B destroys one, both via shell_exec()'s of Amazon's command line tools. The script, doActions.php, pulls actions from a queue. If the action is "create" it creates an instance; when the action is "destroy" it kills one.
The script works fine to execute both A and B when I execute it from the command line: php script.php.
When I put it on a cron, it runs but only successfully runs the B function. It deletes destroys instances but won't create them.
The point of failure is clearly function B. It chokes at the first and most important shell_exec, returning and echoing nothing.
echo $string = shell_exec('/home/user/public_html/domain.com/private/ec2-api-tools/bin/ec2-run-instances ami-23b6534a -k gsg-keypair -z us-east-1a');
Unless you know something specific about the way Amazon's command line tools work, please suggest to me reasons why a shell_exec might work in one case and not the other.
Another shell_exec in the same place behaves as expected:
echo $string = shell_exec ('echo overflow');
My guess is that it has to do something with permissions. But when I have it run shell_exec('whoami') it return "root," and when I su and run the command it works fine. I'm having a hard time thinking of creative ways to troubleshoot why my PHP script won't work in cron when it does from the command line. Can you suggest some?
When something runs from the command line but refuses to do so within cron, it's often an environment issue (path or some other environment variable that's needed by the code you're running).
For a start you should modify the script to output the current environment (shell_exec('env')?) at the very top and examine the output from the command line and cron.
Hopefully, there will be something obvious such as AMAZON_EC2_VITAL_VAR but, if not, you should move the cron environment towards your command line one, one variable at a time, until it starts working.
A quick test to ascertain this. From your command line, do:
env >/tmp/pax_env.sh
Then run your PHP script from a shell script which first executes:
. /tmp/pax_env.sh
so that the environments are identical.
And keep in mind that su on its own doesn't give you the same environment as you'd get from logging in directly as a specific user (su - does, I think). You may want to check the behaviour for when you log in as root directly.
Re your comment:
Yes, I do believe you've got it. I'm likely going to mark your answer as correct but need you to suffer through a few addendums about your clever solution. First of all, what's the best way to execute the pax_env.sh script? Does shell_exec() work?
Never let it be said I didn't work for my money :-) No. The shell_exec will almost certainly be running a sub-shell so the variables would be set in that sub-shell but would not affect the PHP parent process.
My advice, if you wanted all those variables set, would be to create a shell-script consisting of all the commands in /tmp/pax_env.sh (probably prefixing each with export) followed by the command you currently have running in cron, something along the lines of:
export PATH=.:/usr/bin
export PS1=Urk:
export PS2=MoreUrk:
/home/user/pax/scriptB.php
Then run that script from cron rather than /home/user/pax/scriptB.php directly. That will ensure the environment is set up before your PHP code is called.
Astute readers will have noticed the phrase "if you wanted all those variables set" above. I don't personally think it's a good idea to dump all your command line variables into the shell script for the cron job. I'd prefer to actually find out which ones are needed and only include those. That lessens the pollution your cron job has to run under. For example, it's unlikely that the PS1/PS2 prompt variables will be required for your PHP script.
If it works, you can set all the environment variables - I just prefer the absolute minimum so I don't have to worry too much when things change.
A way of finding out what's needed is to comment out one export at a time until your script breaks again. Then you know that variable is needed. Once it works with the maximum amount of export statements commented out, you can just delete those commented export statements altogether and what remains, however improbable, must be okay (with apologies to Sir Arthur Conan Doyle).

Categories