Executing Python scripts in PHP: Different methods of execution? - php

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?

Related

Call python script from PHP - parallel requests problem

I call Python script via exec blocking function inside php file which is served by Nginx. It works as expected. Python script executes Selenium using webdriver Chrome and returns xml output.
The problem is when I create more requests (2 and more) in the same time. First request is processed (nginx, php, python) and the second waits for finish of the first. They are not parallel executed.
Python script executed directly from shell can be parallel executed without problems.
You have two option.
Multi-Threading
PHP does not support threads natively, but there is this solution. It is still experimental and it requires PHP 7.2+, but if you are already using PHP 7.2+ it will work like a charm.
Multi-Processing
You can make new processes by forking. You can read more about forking in PHP in this answer and more about it as a concept here.
Or you can also do it in the current way with exec(), but you have to put & at the end of the command, so the PHP might pass it to the console and it can run in the background and run the 2nd one.
There is a third way using MQ Engines, but I cannot help with that, but you can read about it too if you are interested. Hope something of these helps.
PHP isn't directly asyncronious, use the pcntl extencion and look at this

How to exit shell mode in system()

I have a php script which should use some preset system aliases. I.e. "alias ll=ls -l"
In terminal "ll" works but from php system("ll") outputs
sh: ll: command not found
How do I exit "sh" and execute my terminal commands?
P.S.: May be I missunderstood the basic linux components shell and bash. In this case, please correct me/the post
The PHP docs aren't clear about this, but presumably PHP's system is a reflection of Standard C's system(3), which hands the argument command to the command interpreter sh(1). If you want to avoid the shell, you'll need to use another feature of PHP besides system (like explicit fork/exec). That's context, but it won't help you solve your problem.
In your case it seems you just want the aliases in an rcfile. Scripts invoked by system calls aren't going to read your rcfile unless you take extraordinary steps to make that happen, and even if you do, it's going to be non-obvious to the maintenance programmer. I'd strongly advise you to put the alias in the script or command argument itself, or simply call the command explicitly (ls -al).
You can also manually source the rcfile from your script, or call system(csh -i 'yourcommands') to force csh to be invoked as an interactive shell (which should cause your rcfile to be read). I think this is a bad idea because it is effectively forcing the shell to behave inconsistently with its environment, but I'm including it here for completeness.
Most of the above I got from a quick read through the Startup and shutdown section of the csh manual on my Mac (Mavericks). There are other potential solutions there that I haven't laid out, as well.

From php how the system() function is working?

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.

PHP script execution and multithreaded environment (PHP5 Extension)

I need some clarification executing a "class" that is implemented as a PHP 5 module. The class has a few methods including constructor/destructor and in a PHP script I can use it as follows:
<?php
// --- construct
$c = new my_class("some argument");
// --- add data
foreach ($arr_of_elements as $k => $v) {
$c->add_element($v);
}
// --- execute algorithm
$c->execute();
// --- get result as xml format
$result = $c->get_result_as_xml();
// --- end of script (destruct)
?>
My question is: When a request is made is the above script executed in a single thread within the PHP module of the Apache2 server? In my opinion it should.
I am asking this, because I implemented a PHP5 extension in C that uses the Java JVM with some JNI code, so when above script is executed it attaches to the JVM with the class constructor, calls the methods (which are actually wrappers for my JNI Calls) and detaches from the JVM with the destructor.
Executing Apache in debugging mode (using -X), the and script runs like a charme, multiple runs (reloading) makes no problem at all, but Apache2/PHP in regular multi-process mode, after a few calls the JNI AttachCurrentThread to the JVM hangs. I try to track down that issue to find a solution.
Is there s possibility to get some information in which thread (id, or such) I am executing?
I need to make sure that the execution is a single thread execution.
I am using Apache2 with PHP 5.2.16 (compiled from source) on Ubuntu Lucid 10.04 LTS
If something is unclear, please let me know. Thanks for the info and help!
Andreas
If you've got apahce2 in the recommended for php prefork() configuration with modphp. Then each http request will be running in its own http process with a single php thread per process. I suspect you are running in one of the other modes.
If your not using prefork configuration a few of the php functions that wrap c libraries will start busting as they are not thread safe, including your custom java code mentioned above.
There are also a couple of fastcgi configurations that work slightly diffrently than modphp.

Calling fcsh from PHP 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.

Categories