Page 1 of 2

restarting apache within php script on linux

Posted: Sun Aug 20, 2006 8:48 am
by samtay
I need to restart Apache from an php script. I have been searching google for days now and can't find any information. Can anyone help?

Thanks
Sam Taylor

Posted: Sun Aug 20, 2006 10:28 am
by blackbeard
Try using the exec function.

Code: Select all

exec ("/etc/init.d/apache restart");
I'm not sure about the command to restart apache, you'll have to make sure that the path and command are right, but that should work.

Posted: Sun Aug 20, 2006 10:36 am
by mibocote
blackbeard wrote:Try using the exec function.

Code: Select all

exec ("/etc/init.d/apache restart");
I'm not sure about the command to restart apache, you'll have to make sure that the path and command are right, but that should work.
Won't work. First off, it is /etc/init.d/httpd. Second, /var/run/httpd.pid is owned and grouped by root (-rw-r--r--), meaning that the service can only be stopped/started by root. All apache child threads run as the user apache, so effectively no php script can restart apache.

To possible solution is to create a cron job run by root every minute that checks for the existance of a particular file and if it does exist it restarts httpd and deletes the file. Then you just create that file from php if you need apache restarted and wait at the most 1 minute.

Posted: Sun Aug 20, 2006 10:43 am
by samtay
Does anyone know of any other better way because of permissions?

Posted: Sun Aug 20, 2006 10:49 am
by RobertGonzalez
system() perhaps?

Posted: Sun Aug 20, 2006 10:55 am
by mibocote
Everah wrote:system() perhaps?
system() and exec() are almost exactly the same except in the manner they handle program output (system puts it in the buffer and trys to flush the buffer, exec puts it in an optional 2nd parameter passed byref).

Posted: Sun Aug 20, 2006 10:59 am
by RobertGonzalez
I was just throwing ideas out there. It seems (in my logic anyway) that using PHP to restart apache might have some undesired results. When Apache stops to restart, PHP will no longer be able to process because the server is not on for that small amount of time. Am I wrong about this?

Posted: Sun Aug 20, 2006 11:21 am
by mibocote
Maybe this wiil help. You have the httpd process, running as user 'root'. This process serves no pages, but rather spawns child processes as needed/configured running as the user 'apache'. These child threads are responsible for serving pages and running modules/CGIs. Therefore, when a php script makes a call to exec() or system(), the apache child process runs the command (probably through the C function system()). As an example, if I called exec('ls .'), the ls program would be started with the uid 'apache', therefore being able to do anything the 'apache' user can. To answer your question, Everah, it won't matter that all php scripts stop when the server is restarting because it is already doing the desired function, ie restarting.

I am not too familiar with php-cgi, but I think that in that case php runs as the owner of the file. I could be wrong, but this might be a solution as you could change the user of the php file that restarts apache to 'root', but I would never recommend this.

Posted: Sun Aug 20, 2006 12:02 pm
by samtay
mibocote wrote:To possible solution is to create a cron job run by root every minute that checks for the existance of a particular file and if it does exist it restarts httpd and deletes the file. Then you just create that file from php if you need apache restarted and wait at the most 1 minute.
The cron job idea sound good, does anyone have any examples?

Thanks
Sam

Posted: Sun Aug 20, 2006 12:10 pm
by Ambush Commander
Permissions will be the biggest issue here. The cron job would look like:

Code: Select all

#initialization goes here
*/1 * * * * root /home/user/checkApache.php
Although I'd recommend checking every ten minutes (*/10 * * * *), one minute seems like a lot.

The script would look like:

Code: Select all

<?php
if (!file_exists('restart.txt')) exit;
unlink('restart.txt');
shell_exec('/etc/init.d/httpd restart');
?>

Posted: Sun Aug 20, 2006 12:11 pm
by mibocote
The cronjob script:

Code: Select all

if [ -f testfile ]
then 
  /etc/init.d/httpd restart
 rm testfile
fi
Replace testfile with the absolute location of the file you will be generating from php.

Edit: I prefer Ambush Commander's solution, though I think he meant

Code: Select all

*/1 * * * * root php /home/user/checkApache.php

Posted: Sun Aug 20, 2006 12:12 pm
by Ambush Commander
Hey, don't forget to delete the file! ;-)

Posted: Sun Aug 20, 2006 12:37 pm
by samtay
would it be better by using an MySQL db instead of a file?

Posted: Sun Aug 20, 2006 12:54 pm
by Ambush Commander
In my opinion it's overkill.

Posted: Sun Aug 20, 2006 3:33 pm
by Jenk

Code: Select all

exec('sudo /etc/init.d/httpd restart');
access issue solved..