I am working in a project, where the script will run under Linux. It has many modules, which are written in C++. I need to call these modules from PHP.
My problem is as follows:
My module is one of the module in the software package.
Our software is having the PHP layers to take user input and store it in database, and also call the C++ engine when needed.
All modules are running and using some environment variable which was set by the base module.
There is one layer of PHP through we are getting the user inputs to our C++ engines.
I need to call an application (abc.out) from PHP and it will fill the database.
The problem is that I have to set one new environment variable before the application will work.
I am getting the old environment variable using getenv() then appending a path to it and setting again. I have used putenv() to set the new environment variable.
After setting the environment variable I am using the system() to call that application from PHP and it is working.
My doubt is whether this environment variable change will affect other modules those are running.
One thing is that if we use system() for multiple operations, I can set the environment variable and call my application both from the same system() call. Here my doubt is whether this will also affect the other application which are running, or only the particular application which being called with system().
That is system() is a creating a new session for each program what we call by it or not?
Thanks
Well, php is open source :-) You need to look in the file ext/standard/exec.c. system is implemented as a call to php_exec_ex, which via php_exec uses a macro called VCWD_POPEN, which on a Linux system uses a popen() system call.
So, each call to PHP system() on a Linux system will be executed through a fresh popen() system call, so yes, the separate calls are isolated. I didn't check for Windows.
Related
I’ve written a small database engine in C that works by reading commands you input in the console and it outputs the result.
Is there any way of me writting some PHP code that could send arguments to the console and recieve the output back to PHP without restarting the compiled program.
Is there a better way of doing this?
You say you want the PHP to send and receive messages to your program without restarting the compiled program.
So I don't think using shell_exec or proc_open will work how you want, since these commands both load a fresh instance of the compiled program.
Instead, I suggest you look into sockets, and how you would rewrite your database engine to use those instead of STDIN/STDOUT. Then you can use PHP's socket functions to communicate between your applications. And you'll have just one instance of your compiled program running in the background, even with multiple hits to your PHP script.
I want to execute a Python script from PHP and apparently there are two completely different methods to do it.
The first method is to install Python on Wampserver (which I am using). The method described here involves extra files (mod_wsgi) and some modification (httpd.conf). I tried this method and Wampserver started failing (localhost not available) which was resolved by removing mod_wsgi.
The second method is by simply using the shell_exec command (example) which executes the Python script without any problems. I was a little surprised at how easy it was to do it and I have no idea why it works. I assume that the shell used is that of the current server's. Does this mean that I can also use installed external libraries in that script (e.g. OpenCV / cv2)?
What are the differences between the two methods and why is method 1 so complicated?
I want to run some code in Apache at initialization before PHP requests are handled in the Apache child processes. This would have to happen in the Apache parent. It would setup some new global variables.
When the child runs, there would be these new variables there ready and waiting.
APC (and the like) are not an option since this code is kind of expensive to run.
I'm trying to avoid writing a PHP module.
Personally, I place php_value auto_prepend_file config.inc.php in .htaccess (or in httpd.conf) to get config.inc.php to run before any PHP scripts are executed to set up my global vars.
Note that this is run on every request, though, so if it's a large setup script, it will be expensive.
Also, this will not work if PHP is installed as CGI, in which case you'll need to set the auto_prepend_file setting in php.ini.
The best way to go would be as told by daiscog to use auto-prepend. If you need to set it within apache for some reason, you could pass them using environment variables:
Set them with apache as you like, https://httpd.apache.org/docs/2.2/env.html, and access them in PHP using $_ENV - while this wont obviously not work for "complex" php variables like arrays, you could use it to pass strings from apache to php.
Apache itself can not execute pre-loaded PHP code and set variables per parent. It's a compiled application and it only executes PHP code via the server api, it does not share much with PHP memory wise. That are basically two worlds.
However what works is a webserver that is build in PHP. Such a webserver can hold variables between HTTP requests. Infact all global variables. So your code must be compatbile with that pattern and cleanly shutdown the part that should get unloaded (the code will never get unloaded, only the global variables that get unset).
Such a webserver is appserver-in-php.
However I do not exactly understand how/why/for-what you want to prevent writing a PHP module (and which kind? compiled? In userspace?).
I'm trying to make a web app that will manage my Mercurial repositories for me.
I want it so that when I tell it to load repository X:
Connect to a MySQL server and make sure X exists.
Check if the user is allowed to access the repository.
If above is true, get the location of X from a mysql server.
Run a hgweb cgi script (python) containing the path of the repository.
Here is the problem, I want to: take the hgweb script, modify it, and run it.
But I do not want to: take the hgweb script, modify it, write it to a file and redirect there.
I am using Apache to run the httpd process.
Ryan Ballantyne has the right answer posted (I upvoted it). The backtick operator is the way to execute a shell script.
The simplest solution is probably to modify the hgweb script so that it doesn't "contain" the path to the repository, per se. Instead, pass it as a command-line argument. This means you don't have to worry about modifying and writing the hgweb script anywhere. All you'd have to do is:
//do stuff to get location of repository from MySQL into variable $x
//run shell script
$res = `python hgweb.py $x`;
You can run shell scripts from within PHP. There are various ways to do it, and complications with some hosts not providing the proper permissions, all of which are well-documented on php.net. That said, the simplest way is to simply enclose your command in backticks. So, to unzip a file, I could say:
`unzip /path/to/file`
SO, if your python script is such that it can be run from a command-line environment (or you could modify it so to run), this would seem to be the preferred method.
As far as you question, no, you're not likely to get php to execute a modified script without writing it somewhere, whether that's a file on the disk, a virtual file mapped to ram, or something similar.
It sounds like you might be trying to pound a railroad spike with a twig. If you're to the point where you're filtering access based on user permissions stored in MySQL, have you looked at existing HG solutions to make sure there isn't something more applicable than hgweb? It's really built for doing exactly one thing well, and this is a fair bit beyond it's normal realm.
I might suggest looking into apache's native authentication as a more convenient method for controlling access to repositories, then just serve the repo without modifying the script.
My question is whether or not Flex's fcsh can be called from within a PHP script. Here is the background:
I have been created a simple process that creates a simple quiz/tutorial by converting a text file into a .mxml file and compiling to a .swf file using the mxmlc compiler. This works well from the command line, but I wanted to make the process easier by creating a web-interface to do this. My initial attempts with PHP's exec() function have not worked. The Python scripts I use to create the .mxml file work fine (using exec()), but I have not been able to get the mxmlc compiler to work.
After searching on the Web and on this site, I believe that using fcsh (instead of mxmlc) may be the way to go. Using fcsh would certainly compile the .mxml file faster (after the first run), and I think that fcsh can be launched as a service that might be able to be called from PHP.
On the other hand, maybe I am approaching this the wrong way. Would it be better to write a Flex application that calls fcsh and avoid using PHP?
Edit: Using fcshctl as hasseg suggested in his answer below worked very well. Thanks Ali.
The problem with calling fcsh from within scripts is that it works as an interactive shell instead of taking command-line arguments, compiling, and returning an exit status. There are different ways to get around this, which I've listed in this blog post of mine, where I mainly talk about fcshctl (which is my own solution for this,) but at the bottom of the post I've also listed other similar solutions to get fcsh integrated into nonstandard build workflows.
There are a few other ways in php to execute an external script. They are exec(), passthru(), system(), and backticks i.e. the key to the left of the 1 key. Each one has a different purpose and return mechanism.
You may have to put the command that executes your executable into a script and call that script via one of these functions.
Is there a particular reason why you can't use mxmlc directly? It seems like it would be easier to call than fcsh. Just specify all your compiler options in a XML file run it like mxmlc -load-config path/to/config.xml. You can find an example of the XML configuration format in FLEX_HOME/frameworks/flex-config.xml.