PHP script execution and multithreaded environment (PHP5 Extension) - php

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.

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

MATLAB with PHP [duplicate]

As the title indicates, I have MATLAB code for isolated spoken words recognition, and I want to be able to integrate this project with another one made with PHP for some purpose.
I have not used to deal with such problem before. In other words, it's the first time for me when I need to integrate PHP and MATLAB, so I really don't know where to start and how.
I have read a couple of articles, but I couldn't make it valid.
I have PHP 5.4.9, MATLAB R2012A and Windows 7.
The MATLAB project files can be seen on GitHub.
You have a few options here:
If MATLAB installed on the server where the PHP application would be deployed (not your current development environment), you can invoke it directly just like any other program (matlab -r "...") using whatever is the equivalent of EXECUTE command in PHP. Here are some resources (make sure to also checkout the linked questions as well):
How to call MATLAB from command-line and print to stdout before exiting
Running a cmd file without GUI popping up
Pass Parameters _ Shell Script - Octave Script
Others have commented on how to pass input/output between PHP and your MATLAB script. For example, you could design your MATLAB function to receive the path of WAV file as input, process it and save any resulting image to disk:
function myFunc(filename)
[y,Fs] = audioread(filename);
img = my_process_func(y, FS);
imwrite(img, 'out.png');
end
Which is invoked from PHP as:
% Of course you have to make sure "myFunc" is available on the MATLAB path.
% Think: "addpath(..)" or just "cd(..)" into the directory first
matlab -wait -nodisplay -r "myFunc('audio.wav'); quit;"
You could then read the output image in the PHP application.
If not, what deployment-related toolboxes do you have available? MATLAB Compiler and related toolboxes like MATLAB Builder NE and MATLAB Builder JA.
Those will compile your program into an executable/.NET Assembly/JAR file respectively, and all of them require the freely available MCR Runtime to be installed. In other words, the executables do not need to have a full MATLAB installation on the target machine, only the MCR runtime.
You would run the executable in the same manner as before.
Another product is the MATLAB Coder, which converts your MATLAB code into C++ program. When compiled, it can run without any external requirement.
A new product by MathWorks is MATLAB Production Server. Personally I know nothing about it :)
Yet another option is to use TCP/IP to communicate between PHP and MATLAB. A server would be run on the MATLAB side, using socket programming written as C MEX-file or a Java class. See:
MATLAB Mex Socket Wrapper Library
Writing Java's pw.println(), etc. in MATLAB
The client being your PHP application. The idea is to have MATLAB listening for connections, reading whatever input is given by a client, eval it, and return the result. This is more involved than the other options, as you have to deal with serialization and other things like concurrency. The advantage is that MATLAB can be run on a separate server, even on multiple servers on the cloud (see this post).
So first, decide what approach best suits your project, then it would be easier to answer specific questions... Just always consult the documentation first, MATLAB toolboxes are very well documented and usually include many examples. Here are a couple more resources specific to MATLAB Compiler products family:
Webinar: Application Deployment with MATLAB
PDF File: MATLAB Application Deployment - Web Example Guide
Note that they concentrate on ASP.NET and Java JSP/servlet applications. In your case, the PHP application would communicate with a middle tier running a web service built using one of the above two options (or simply design a CGI-like site running plain executables built using the MATLAB Compiler as explained earlier).
To help the OP with running system commands from a PHP webpage, my post here is relevant (copied below).
We do exactly this all the time. I call them voodoo pages. Here's some working code:
<?php
$command="uptime"; $output; $retval; $errors="";
exec ($command, &$output, &$retval);
echo $output[0] . "\n";
unset($output);
?>
And the output to the webpage served:
13:40:19 up 22 days, 23:14, 0 users, load average: 0.04, 0.02, 0.00
And the additional note I added in the comments below:
Relative vs absolute paths may be a pain... $command might need to be /usr/bin/uptime or another could be /usr/bin/ls /home/chris/ftp. Normally, scripts' working directory is where they live in the file system. MATLAB is a windows program, yes? My experience is you will need absolute paths for the program and any files passed as arguments, example: $command="c:\\matlab\\matlab.exe c:\\www\\somefile.wav" And then single quotes required for silly NTFS names, TAB command line completion works well for examples. Or use proper 8.3 name with the ~ in it.
My answer would be in two parts:
How do I run a MATLAB script from the terminal?
I will give some example about running a MATLAB script from the terminal:
matlab -nojvm -nodesktop -r "run <the-script>.m"
matlab -nojvm -nodesktop -r "<the-script>"
matlab -nojvm -nodesktop -r "run <the/path>/<the-script>.m"
matlab in Windows must be in your environment path. How-to.
If you need to compile your script to Java:
java -jar yourjarfile.jar
How do I execute the terminal command from PHP?
I think the previous answers are good, and there isn't any need to repeat them.
More notes:
Watch for your security. You might be XSS'ed easily.
Abstract your code and improve it to save parameters and output to the database. Run your code in
Parallels or queue manager. You might create a REST service.
Unit test.
Use Linux. It's much more powerful.
One quick hack would be to compile your MATLAB code into an executable file then use PHP's shell_exec().
The difficult part would be adapting your MATLAB code (sorry, I didn't read it) in such a way that:
It will receive its input in command-line-interface style (as char strings);
It will output its results as text to standard output (file id #1 in MATLAB).
Then all it takes is to parse the MATLAB output back into PHP...

Executing Python scripts in PHP: Different methods of execution?

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?

Is the exit status in PHP only useful when running from the command line?

I was just reading the docs for PHP's exit construct.
It says you can pass an integer (0-254) which will become the exit code...
exit(5);
Is this only useful when running from PHP under CLI? Can Apache use the error code for anything? Will PHP running normally always use exit code 0?
Thanks
While hardly an authoritative answer, I'm not aware of any purpose that it (passing an integer to exit) serves outside the CLI environment. Web servers traditionally just report the HTTP status code, and there's not any reason for them to look elsewhere for status codes.
You could take a look at PHP's source in the sapi directory. For example, in php_cli.c, you'll see exit(exit_status); near the end of the file. I assume the generic cgi interface uses it too. I doubt any of the web server interfaces use it.

Execute another PHP file without waiting for it to finish its execution

I have StartServer.php file that basically starts a server if it is not already started. Everything works perfect except that the StartServer.php will hang forever waiting for the shell_exec()'d file Server.php to finish its execution that it never does.
Is there a way to execute a PHP file and just forget about it -- and not wait for its execution to finish?
Edit: It has to work on Windows and Linux.
This should help you - Asynchronous shell exec in PHP
Basically, you shell_exec("php Server.php > /dev/null 2>/dev/null &")
You'll need something like the pcntl functions. Only problem is that this is a non-windows extension, and not suitable to run inside a web server. The only other possibility I can think of is to use the exec function and fork the current process manually (as suggested in dekomotes's answer), doing OS detection to figure out the command needed. Note that this approach isn't much different to using the pcntl functions (in Linux, at least) - the ampersand character causes the second script to be run inside different process. Multi-threaded / multi-process programming isn't well supported in PHP, particularly when running inside a web server.
I think it's traditional to let the server detach itself form the parent process, ie to "daemonize" itself, rather than having the script starting the server detach itself. Check the server you're starting to see if it has a daemon-option.
If you've written the server yourself, in PHP, you need to detach it. It looks somehting like this:
posix_setsid(); //Start a new session
if(pcntl_fork()) {exit();} //Fork process and kill the old one
I think this works on Windows too. (Not tested.)

Categories