There is a PHP script I would like to execute by a cron-job but it has to be executed every seconds or every 2 seconds.
(PHP file updates the cover photo of a page via opengraph)
So I decided to write a shell script which is below. But how does php act when executed by a shell script, is it works normally like requested from a browser or what happens ?
Does sessions works ?
#!/bin/bash
while true; do
/path/to/file.php
sleep 1
done;
echo "Stopped" | mail -s "Cron script has stopped." mymail#domain.com
The difference is that you won't have $_GET, $_POST and other http specific stuff available. Sessions also won't work (why would you need them?). You obviously won't be able to set cookies, headers and other such things.
Other than that you can pretty much ignore the fact that you are "in a shell".
See here for more details: http://www.php.net/manual/en/features.commandline.differences.php
Take all the browser aspects away from PHP and that's how it'll act. You get no sessions (unless you were to call it with cURL and store the cookie somwehre).
You get no $_GET or $_POST - instead you need to use $args - but if you're not passing in any variables this isn't really relevant to you.
You'll obviously need to ensure that you've given your script execute permission, otherwise, call it using /path/to/php /path/to/file.php.
Take a look at these resources, they should help you out.
http://www.php.net/manual/en/features.commandline.differences.php
http://www.php.net/manual/en/features.commandline.php
When you execute php from the command line (CLI) you enter another environement.
There are multiple differences
Some of them are
Configuration
When executing from command line, you run another php.ini file. (Usually /etc/php5/php.ini)
Permissions
On the web, you usually execute PHP with www-data user.
When executing from command line, script will be executed as the current user.
Arguments
You do not have access to $_GET, $_POST, $_FILES... superglobals anymore.
Instead, you have new superglobals so as $argv and $argc
Sessions
You do not have access to session nor $_COOKIES
Relative Paths
The path that the script uses is relative from where the command started
So, careful when using relative ./ path in your script
Eg:
$ pwd
/path/to/project/
$ cat app/script.php
<?php
echo getcwd(), PHP_EOL;
$ php app/script.php
/path/to/project
$ cd app
$ php script.php
/path/to/project/app
You can get the current directory by using getcwd
Related
So, guys, I have the following code:
<?php
$url = "http://example.com/filetorun.php";
$time = date('g:i A d.m.Y', $res['sometime']);
echo `echo "wget --spider {$url}" | at -M {$time}`;
?>
The main idea is to wget some url at the specific time to perform some useful operations for me.
What happens in the terminal?
When I run this bash code. It works well giving me the output like this:
warning: commands will be executed using /bin/sh
job 59 at Mon Jan 13 17:12:00 2020
What happens in /var/log/apache2/error.log when I run my php script?
It gets this output.
What's about atq?
I can see the job there only when I create it via the Terminal. When I create It from the php-script, I can not do that.
What have I tried to do?
I added users to /etc/at.allow and deleted them from /etc/at.deny
Not a lot of detail to go on, but I direct your attention to this requirement of at:
The value of the SHELL environment variable at the time of at invocation will determine which shell is used to execute the at job commands. If SHELL is unset when at is invoked, the user's login shell will be used; otherwise, if SHELL is set when at is invoked, it must contain the path of a shell interpreter executable that will be used to run the commands at the specified time.
Does your web server user have a login shell defined? getent passwd or grep /etc/passwd to determine. Regardless, I suggest setting the shell to use in the command itself, to prevent issues where someone chnahes the default shell of the invoking user.
If this is not the issue, we probably need more detail.
Is there any reason why I can not complied files in PHP's shell_exec/exec/system function?
Example of something that does work in command line and PHP's shell_exec function:
<?php
$data = shell_exec("ls");
echo $data;
?>
Example of something that does not work in PHP's shell_exec function but will work in command line (I can confirm that):
<?php
$data = shell_exec("./c-compiled-file argv1 argv2 argv3");
echo $data;
?>
Is there anything I can do on my server so this will work? I've looked everywhere and no solutions I found fixed the problem. The compiled file is in the same directory as the PHP script as well, it just won't execute it. Also if you're asking, yes I have tried this with SSH2 and it still will not execute.
Also PHP is not in safe mode and NO functions are disabled.
Some common glitches when executing external commands from PHP that work fine from shell:
Command uses relative paths but PHP is launched from an arbitrary location:
Use getcwd() / chdir() to get/set working directory
PHP and shell run with different user credentials. This is often the case when PHP runs through a web server.
PHP and shell run different commands. Many people call stuff like exec("foo $bar") and doesn't even check what "foo $bar" contains.
No error checking is done. The bare minimum is to capture and print standard output, standard error, status code and, of course, all PHP error messages including warnings and notices.
You can redirect stderr to sdtout
You can use a PHP function that allows to capture more information, such as exec()
The web server is disallowed to execute the command at operating system level.
Lookout for SELinux or similar tools.
Just a guess, but the binary you're trying to execute might not have the proper permissions. Prepeding it with ./ in the command line forces it to execute, but PHP probably strips that for security purposes. Try this:
chmod +x c-compiled-file
You want to use system in the second case, and not shell_exec.
system executes an external program and displays the output.
shell_exec executes a command via shell and returns the complete output as a string.
and for good measure:
exec simply executes an external program.
Furthermore you want to make sure your external program is executable and (though you have stated it, I'll restate this) has execute permissions for the user which is running the web server. You also want to make sure the directory your external program is running in has the ability to write to its directory or /tmp or whatever output directory you have set.
Finally you should always use absolute paths for executing things like this in cron or php or whatever... so don't use ./c-compiled-file argv1 argv2 argv3, but instead use /home/username/c-compiled-file argv1 argv2 argv3 or whatever the full path is.
I need to run a PHP script from command line and I need to set some environmental variables. Unfortunately, following does not work:
php -dAPPLICATION_ENV=staging script.php
What I'd like to accomplish is having APPLICATION_ENV variable set.
APPLICATION_ENV=staging php script.php
The variable will be available in the $_SERVER array:
echo $_SERVER['APPLICATION_ENV'];
There is no way to set environment variables from the command line specifically for the execution of a script by passing options to the PHP binary.
You have a few options:
Set the variable globally on the system.
Set the variable on the command line before calling the script. This will persist in the environment after your script has finished executing, which you may not want.
Wrap the PHP script in another script, allowing you to create a temporary variable that exists only for the duration of the script.
Use a command line option instead of an environment variable.
The last two options are probably the cleanest way to do this, in that the variable created only exists for the run time of your script.
The implementation of option 1 is system dependent.
The implementation of option 2 is also system dependent - on Windows you would do set APPLICATION_ENV=staging&& php script.php and on *nix it would be export APPLICATION_ENV='staging' && php script.php.
If you were to go for option 3 you might be tempted to go for a shell script, but this is not portable (you would need a batch file for Windows and a shell script for *nix environments. Instead, I'd suggest you write a simple PHP wrapper script, something like this:
<?php
putenv('APPLICATION_ENV=staging');
include('script.php');
This allows you to leave your target script unchanged and set the environment variable for the script's session only.
A more complex wrapper script could easily be created which would allow you to specify variables on the command line, and even dynamically specify the script which should be executed when these variables are set.
Option 4 can be implemented using the $argv variable:
<?php
$applicationEnv = $argv[1];
// rest of you script
...and call the script like:
php script.php staging
However, it occurs to me that you seem to be indicating to the script which environment is running in (staging, dev, live, etc) - in which case it might be simplest to set a server-wide variable, and rename it as necessary to prevent collision with variables that other applications may be setting. That way you can simply invoke the script and not need to worry about this. This is assuming that you staging environment runs on a different machine to the live (which it should be).
When you execute a PHP script from the command line, it inherits the environment variables defined in your shell. That means you can set an environment variable using the export command like so:
export APPLICATION_ENV='staging'
Here is an example for setting one envirnnomental variable :
ENV_VAR='var' php script.php
Just in case you want to set multiple variables
Try this :
ENV_VAR1=1 ENV_VAR2=2 ENV_VAR3=3 php script.php
You can set a variable in /etc/environment like FOO="bar" which is then accessible with getenv() in both CLI and web requests. You may need to relog for this change to take effect.
Try using putenv and pass the variables through parameters
php script.php APPLICATION_ENV=staging
And in the script.php code:
for($i=1;$i<count($argv);$i++){
putenv($argv[$i]);
}
I have the same situation and i use next code (it works for me):
export APPLICATION_ENV=staging && php script.php
Hope it will helpful for you too.
So I want to execute a bash command from PHP on my web server. I can do this using shell_exec. However, one of the commands I want to execute is curl. I use it to send a .wav file to another server and record its response. But when invoked from PHP, curl doesn't work.
I reduced the error to the following small example. I have a script named php_script.php which contains:
<?php
$ver=shell_exec("curl -F file=#uploads/2013-7-24-17-31-43-29097-flash.wav http://otherserver");
echo $ver
The curious thing is that when I run this php script from command line using php php_script.php, the result I get is
Status: 500 Internal Server Error
Content-type: text/html
However, if I run curl -F file=#uploads/2013-7-24-17-31-43-29097-flash.wav http://otherserver directly, I get the response I was expecting:
verdict = authentic
(Edit:) I should probably mention that if I put some bash code inside the shell_exec argument which does not contain curl, the bash command executes fine. For example, changing the line to $ver = shell_exec("echo hello > world"); puts the word "hello" into the file "world" (provided it exists and is writable). (End edit.)
Something is blocking the execution of curl when it is invoked from PHP. I thought this might be PHP's running in safe mode, but I found no indication of this in php.ini. (Is there a way to test this to make 100% sure?) What's blocking curl and, more importantly, how can I bypass or disable this block?
(And yes, I realize PHP has a curl library. However, I prefer to use commands I can run from the command line as well, for debugging purposes.)
cheers,
Alan
The reason is the administrative privileges when you run the command directly you are running it as root and thus the command gets executed. But, when you run the command through PHP it runs as an user. By, default user has not the privileges to run the shell_exec commands.
You have to change the settings of shell_exec through CPanel/Apache config file. But, it is not recommended to provide the shell_exec access to the user as it help hackers to attack on server and thus, proper care should be taken.
It would be more appropriate to use the curl library provided in PHP.
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.