php execute php file
Php execute php file
There are three different ways of supplying the CLI SAPI with PHP code to be executed:
Tell PHP to execute a certain file.
Pass the PHP code to execute directly on the command line.
Special care has to be taken with regard to shell variable substitution and usage of quotes.
Provide the PHP code to execute via standard input ( stdin ).
This gives the powerful ability to create PHP code dynamically and feed it to the binary, as shown in this (fictional) example:
Example #1 Execute PHP script as shell script
Assuming this file is named test in the current directory, it is now possible to do the following:
Example #2 Script intended to be run from command line (script.php)
The script above includes the Unix shebang first line to indicate that this file should be run by PHP. We are working with a CLI version here, so no HTTP headers will be output.
Example #3 Batch file to run a command line PHP script (script.bat)
See also the Readline extension documentation for more functions which can be used to enhance command line applications in PHP.
On Windows it is recommended to run PHP under an actual user account. When running under a network service certain operations will fail, because «No mapping between account names and security IDs was done».
User Contributed Notes 7 notes
On Linux, the shebang (#!) line is parsed by the kernel into at most two parts.
For example:
1. is the standard way to start a script. (compare «#!/bin/bash».)
3. if you don’t need to use env, you can pass ONE parameter here. For example, to ignore the system’s PHP.ini, and go with the defaults, use «-n». (See «man php».)
4. or, you can set exactly one configuration variable. I recommend this one, because display_errors actually takes effect if it is set here. Otherwise, the only place you can enable it is system-wide in php.ini. If you try to use ini_set() in your script itself, it’s too late: if your script has a parse error, it will silently die.
Summary: use (2) for maximum portability, and (4) for maximum debugging.
Execute php file from another php
I want to call a PHP file that starts like
I call from the PHP like this:
Why doesn’t this correctly execute the name.php file?
5 Answers 5
It’s trying to run it as a shell script, which interprets your token as bash, which is a syntax error. Just use include() or one of its friends:
For example, in a.php put:
exec is shelling to the operating system, and unless the OS has some special way of knowing how to execute a file, then it’s going to default to treating it as a shell script or similar. In this case, it has no idea how to run your php file. If this script absolutely has to be executed from a shell, then either execute php passing the filename as a parameter, e.g
or use the punct at the top of your php script
Sounds like you’re trying to execute the PHP code directly in your shell. Your shell doesn’t speak PHP, so it interprets your PHP code as though it’s in your shell’s native language, as though you had literally run at the command line.
Shell scripts usually start with a «shebang» line that tells the shell what program to use to interpret the file. Begin your file like this:
Besides that, the string you’re passing to exec doesn’t make any sense. It starts with a slash all by itself, it uses too many periods in the path, and it has a stray right parenthesis.
Copy the contents of the command string and paste them at your command line. If it doesn’t run there, then exec probably won’t be able to run it, either.
Another option is to change the command you execute. Instead of running the script directly, run php and pass your script as an argument. Then you shouldn’t need the shebang line.
Executing php file from another php file uses too much CPU
I have read the other questions on SO with a similar title, but that’s not what this question is about. I know HOW to execute a PHP script from another PHP script. The problem is, when I do so, it uses far too much CPU. I would like to know how to reduce this.
I have a simple front-controller-like script called index.php. It processes GET requests from a client and depending on the «action» parameter passed, it sends the request to the appropriate file to handle it. For example, this is a client request:
index.php has an array that maps the «action» parameter to the appropriate file:
For testing purposes, I have created a PHP script that does nothing except measure CPU utilisation and dump it to a log file:
This produces a log file that looks like this:
Clearly, a PHP script shouldn’t take 9% of CPU to execute. For comparison, I’ve run the same script directly accessing it via a GET request:
0.1% is more like it. But why does calling this PHP script from another PHP script use so much CPU? Is it because I have to execute a «new instance» of PHP when I exec PHP, which has a lot of overhead? If so, is there a way to exec a PHP script using an «already running» instance of PHP? Or is there another way of doing this?
10% for each client, that’s only 10 concurrent clients. I don’t need the process to run faster (it executes in under 1ms), but it does need to use less CPU. Thanks for your other suggestions, but this is an already existing application with a large codebase which actually runs pretty well (apart from this issue). I’m not going to change the entire architecture to solve one problem.
2 Answers 2
And also, while PHP is a compiled language, for the newly forked process, you must run the opcode compiler to generate opcodes (instructions similar to Java bytecode) and then execute those. You can read all about it here. In the end you run the compiler twice, for each fork separately.
Is it worth 9% of your CPU? I have no idea. Maybe. Maybe not. Who knows.
Not only there’s overhead on executing new processes, but the execution environment will be completely different too. If you look into your php configuration there will be several php.ini files, one for each specific environment. This means that one environment could have different modules enabled or different configuration outright. It’s not uncommon to have cli scripts max_execution_time or memory_limit set to unlimited. This can affect resource usage on your server, but it’s also a pain to maintain.
And there’s this thing called shared memory. As @Alex mentions, scripts have to be compiled. If you have opcode cache enabled (which you should) the bytecode gets cached when compiled and this compilation process can be skipped if the resulting bytecode it’s there already. For this to work you need to have a persistent running process that can keep this memory around. If you are creating a new process it can’t access this shared area and has to do the compilation all by itself.
calling exec on a php file and passing parameters?
I am wanting to call a php file using exec.
When I call it I want to be able to pass a variable through (an id).
I can call echo exec(«php /var/www/unity/src/emailer.php»); fine, but the moment I add anything like echo exec(«php /var/www/unity/src/emailer.php?id=123»); the exec call fails.
5 Answers 5
To see this in action, write this one-liner to a file:
Then invoke it from the command-line with arguments:
try echo exec(«php /var/www/unity/src/emailer.php 123»); in your script then read in the commandline parameters.
this adapted script shows 2 ways of passing parameters to a php script from a php exec command: CALLING SCRIPT
dont forget to verify execution permissions and to create a log01.txt file with write permissions (your apache user will usually be www-data).
got the size right, wilburargv element 1: 12
choose whatever solution you prefer for passing your parameters, all you need to do is access the argv array and retrieve them in the order that they are passed (file name is the 0 element).
If you want to pass a GET parameter to it, then it’s mandatory to provide a php-cgi binary for invocation:
I know this is an old thread but it helped me solve a problem so I want to offer an expanded solution. I have a php program that is normally called through the web interface and takes a long list of parameters. I wanted to run it in the background with a cron job using shell_exec() and pass a long list of parameters to it. The parameter values change on each run.
Calling program code:
Works great and requires minimal changes to the called program. Hope someone finds it of value.
Program execution Functions
Notes
Open files with lock (especially open sessions) should be closed before executing a program in the background.
See Also
These functions are also closely related to the backtick operator.
Table of Contents
User Contributed Notes 46 notes
exec(«php script.php parameters 2>dev/null >&- /dev/null &»);
Where.
— php is the path to your php script executer (php has to be specifically complied to be to do this)
— script.php is the script
— parameters are none or more parameters
— 2>dev/null redirects the stderr to a file
— &- switches off the stdout
— >dev/null redirects all other output to the file dev/null
— & direct script to run in background
What I found odd is that the script I was execing would run fine in the bg when executed from the command line, but not from the browser until I closed the stdin and stdout.
at LAST! tenacity pays off, days trying every little thing!
I didn’t want batch files. I’m trying to use PHP to get rid of batch files.
I didn’t want to call a file to parse the parameters to call a shell to call a file. I’ve got «systems» right now with batches tiered three and five deep.
I just wanted to run stuff.
CALL, tested on WinXP, will be testing on more OSes right away, in PHP4 and 5, with exec, system, works with popen, and passthru.
here is my lame sample function.
// all of the below are working in Win XP Pro
passthru ($shellcommand);
exec ($shellcommand);
system ($shellcommand);
shell_exec ($shellcommand);
$proc= popen ($shellcommand, «r»); //$proc contains output
LONG PATH NAMES WITH SPACES IN THEM ON WINDOWS!
all in a big long concatenated command line with multiple quoted-filename parameters
shell scripting bliss!
The only syntax I found to work for the command portion of an an exec() call on a Win2K devel platform is:
$cmd = «\»path-to-exe\» args file-name»;
where ‘path-to-exe’ has escaped double quotes, args are in the standard format, and ‘file-name’ has any backslashes escaped.
Note that the backslashes are escaped in the uploaded_file name, but not in the path to call the Winzip executable. Go figure!
To clarify even more about what has been said in the last few posts:
«exec», «backticks», «system» and so on will fail on Windows 2003 by default.
You must modify the security on cmd.exe to give the user account IUSR-computername the necessary permissions which are at least read & execute.
The note is about usage of exec() under windows.
Here is where i’m at right now (also TRYING to use exec() and passthru() on windows XP sp2):
$cmd = ‘»C:\my path with spaces\targetapp.exe» C:\mypathnospaces\targetfile.xxx’;
exec($cmd);
The above works.
________
Or, you can put your script into your directory C:\my path with spaces\, and work with php directly from there:
$cmd = ‘targetapp.exe «C:\my other path with spaces\targetfile.xxx»‘;
exec($cmd);
The above also works, provided of course your script has the correct working directory.
________
But. In your cmd.exe, you can issue:
«C:\my path with spaces\targetapp.exe» «C:\my other path with spaces\targetfile.xxx»
Although the above works perfectly in the cmd, the following php script does NOT work on my system:
$cmd = ‘»C:\my path with spaces\targetapp.exe» «C:\my other path with spaces\targetfile.xxx»‘;
exec($cmd,&$content);
As far as my few tryings go, the root of the problem lies in the fact that the command to execute has two passages enclosed inside double quotes. Another command which I’ve had working in the cmd but NOT with php is:
Maybe someone has a solution; I don’t (other than using chdir).
Note on XP users: XP-Home edition does not allow to set rights directly on files and folders. You should use cacls command-line utility to do this.
cacls c:\windows\system32\cmd.exe /E /G IUSR_ADMIN2003:F
gives IIS user full access to cmd.exe (potential security hole!), so PHP can fork and execute external programs.
To fork a process I use the following code
( STDOUT ); //Close all output or it WON’T work
fclose ( STDIN );
fclose ( STDERR );
if( pcntl_fork ()) <
exit; //Return to the caller
>
//Code to run in the background
AFICT, the standard Unix Apache configuration causes an rare problem when running a job in the background. The MaxRequestsPerChild directive causes the child to terminate after 1000 requests, any background processes associated with the child will die with the child unless they are started with the «nohup» command. Thus, the proper way to start a job in the background is to use:
exec(‘nohup my-command > /dev/null 2>&1 &’)
Just a simple note to help people get rid of some headaches.
Make sure you use «\ » ( \ space) for the Linux\unix path and just » » space for fopen. These are both very basic things that you wouldn’t normally think to cause a problem, but when you try to pass slashes to fopen it either breaks or even better works incorrectly =D. And vise versa for any programs that use «\ » for spaces in file paths/names.
*Note this is alot of sudo code, and there are faster more effecient ways of doing the same operations, but I thought this might help those who were going crazy over filepaths =D.
Well, I had this issue when I wanted to start an indefinitely running PERL script from PHP. Somehow I could not make the PHP script to return after executing the PERL script. So finally I came to following solution:
PHP file
——————-
( «perl /home/chatserver.pl > /dev/null» );
?>
——————-
This script will be run over HTTP.
Hopefully it helps someone 🙂
Margus
If you plan to start programs on the server that show message boxes (things that require OK from the server-side), or remain (like notepad.exe), and the exec-command seems to go into an deadly loop, then MAYBE your program has started, but you can’t see it. Because the web server runs as an system process, and it isn’t allowed to interact with the desktop.
To solve a part of the problem (to see the programs you execute), in the control panel in Windows, goto Administration->Services, right-click the server-service, goto Properties and on the second tab (login?) and check the box about allowing the service to interact with the desktop. Click OK. Restart the webserver, and MAKE SURE it is restarted for real (i.e. look in the task manager so the service goes _down_), otherwise the desktop-option won’t take.
Next phase would be to stop PHP from waiting for the processes to complete (this is what makes PHP «loop»). I solved this by creating a small Delphi-application that took the path to the file I wanted to execute and executed it by the WinExec API, which just starts the childprogram but doesn’t wait for it to complete = the program completes and the PHP.exe completes the script. Problem solved!
Delphi-snippet:
WinExec(PChar( ),SW_SHOW); // replace with the program path.
I was stuck for about an hour and a half last night trying to get Perl to pass back values to my PHP script after running an exec() command.
Of course, this wasn’t working and I finally figured it out with the help of a friend (Shawn = superstar): you need to echo the exec() command in order to get the values back into PHP.
In case you ever had to chain from php to another program (e.g. with a cgi php that only gives part of the output, or with php-gtk), here is a little C program that kills his parent (php, for instance), then launches a program given in argument.
Just following up my previous post, in reply to lancelot—du-lac at hotmail dot fr:
The behaviour described was fixed in PHP 5.3 in the following commit:
To replicate the fix in your own code, so it also runs on PHP 5.2, instead of:
= «. any shell command, maybe with multiple quotes. » ;
Within Linux, when calling the php interpreter directly from popen, or other program execution function to execute a script, it appears as though the script perpetually fails and re-executes.
[One solution is] to ensure the executing script has a valid shebang, and execute permissions. This allows you to execute the script directly
I found this comment on this page:
Instead of nslookup I believe this would apply to most programs from the \system32\ directory.
. but only under the listed preconditions:
1: nslookup.exe is placed (copied) in the directory \php\safedir\
2: the directory \php\safedir\ is included in the system PATH environement variable
3: the file cmd.exe is placed in \php\ as listed by other notes above
4: the directory «c:\php\safedir\» is set in the php.ini setting
safe_mode_exec_dir = «c:\php\safedir\»
.. maybe set in php-activescript.ini as well, depending on your system setup.
5: nslookup is referenced by the full path as otherwise the file from \windows\system32\ will be called. This happend to me with empty result due to missing rights!
Hope this helps somebody saving some time and headaches.
[end of quote]
This is just to complicated. Only two things are needed:
1. Specific permissions for the IUSR account for read & execute to the cmd.exe in C:\Windows\System32 directory
2. Specific permissions for the IUSR account for read & execute to the command that’s needed (example: nslookup.exe in C:\Widnows\System23 directory)
With just this two conditions the exec works fine
(This is for an IIS server running on a windows platform)