I have been trying to integrate PHP in APACHE TOMCAT 6 by following second answer for the QUESTION RUN PHP APP IN TOMCAT 6. I am facing troubles with the configuration.
First I got Exception java.lang.UnsatisfiedLinkError: no php5srvlt in java.library.path. which I resolved by placing php5srvlt.jar, generated in step 12, in tomcat\lib.
After that I am facing
java.lang.UnsatisfiedLinkError: net.php.servlet.send(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Z)V
net.php.servlet.send(Native Method)
net.php.servlet.service(servlet.java:190)
net.php.servlet.service(servlet.java:214)
javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
Exception.
I tried to find solutions for this but could only get close to this QUESTION. But, I do not want to do the whole thing once again, because I have tried several times. I tried with TOMCAT 8.0.15, but failed. Now, just to go in sink with the instructions I have installed TOMCAT 6 and trying to integrate PHP.
I am placing log file for the request made for tomcat/webapps/PHP/test.php.
LOCALHOST.YYYY-MM-DD.log
Dec 29, 2014 12:15:46 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet php threw exception
java.lang.UnsatisfiedLinkError: net.php.servlet.send(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Z)V
at net.php.servlet.send(Native Method)
at net.php.servlet.service(servlet.java:190)
at net.php.servlet.service(servlet.java:214)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:879)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:617)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1778)
at java.lang.Thread.run(Thread.java:744)
TEST.PHP
<?php
echo "HELLO WORLD";
?>
EDIT
I mistook that I was getting problem 1 because i did not have php5srvlt.jar in tomcat/lib. But, in fact, problem 1 appears when i request the page for the first time after starting the server. and later on I see problem 2.
I've learned from here that php and pecl version must be same, but still I get the same error even after working with same version numbers 5.2.5
The error message indicates that you're missing .dll-files necessary for such a .. fragile contraption.
The UnsatisfiedLinkError is thrown when an application attempts to load a native library like .so in Linux, .dll on Windows or .dylib in Mac and that library does not exist.
But please - reconsider what you're actually doing. There is (almost) no good reason for running a PHP context inside Tomcat.
I've written a simple PHP script which instantiates a COM object for an out-of-process (i.e. exe file) COM component and uses it to call a COM method that the component exposes. This COM method very simply quadruples the number passed as the first argument, returning the result in the second argument (passed by reference). The script shown below works successfully on my local development machine on WampServer 2.0 (Apache 2.2.11 / PHP 5.3.1). The COM component is a Win32 executable built using Delphi.
<?php
// ensure no time limit is imposed
set_time_limit(0);
// show all errors, warnings and notices whilst developing
error_reporting(E_ALL);
$numIn = 3;
$numOut = new VARIANT(1, VT_I4);
echo '----- BEFORE ---------' . '<br>';
echo 'NumIn: ' . $numIn . '<br>';
echo 'NumOut: ' . $numOut . '<br>';
echo '----------------------' . '<br>';
$oleapp = new COM("OleAutomationFeasibilityModel.Automation") or die ("Could not initialise feasibility model object.");
echo '<br />COM object created version = ' . $oleapp->Version . '<br /><br />';
$oleapp->CalculateWithVariants($numIn, $numOut);
unset($oleapp);
echo '----- AFTER ---------' . '<br>';
echo 'NumIn: ' . $numIn . '<br>';
echo 'NumOut: ' . $numOut . '<br>';
echo '----------------------' . '<br>';
?>
Note: as I understand it, one can only pass a parameter by reference to a COM method using a VARIANT type, as common data types like integers and strings won't work (see http://www.php.net/manual/en/ref.com.php#45038).
I then created and deployed an Azure Web Role (Cloud Service) with a startup script that registers the COM component successfully i.e. the appropriate registry keys appeared in the registry. To further confirm that the COM component could be interacted with, I used RDP to connect to the cloud service instance and installed Microsoft Access Runtime 2010 as I have an Access application that provides a GUI to test the methods of the COM component. I was able to run this application and successfully interacted with the COM component, using it to pass an integer to the CalculateWithVariants method and the expected quadrupled result was returned. So, I've established that the COM component is installed and can be interacted with on the Azure cloud service instance.
Next I included the above PHP script in the Web Role and deployed it on Azure. Unfortunately, calling the script from a browser results in an HTTP Error 500 (Internal Server Error) and I'm struggling to find out why. If I comment out all lines referencing $oleapp, I still get the same error. If I additionally comment out the line that instantiates a variant object, no error occurs. If I reinstate the line which instantiates the COM object and the line below it, I receive no error message but the only text echoed is from the lines preceding the COM object creation line i.e. the call to the Version method fails. So it appears to be struggling with the variant object creation and the COM object creation.
I'm a bit stuck in terms of how to resolve this issue. I would therefore be very grateful if anyone has any pointers as to a way forward.
UPDATE 1
I decided to try a different course of action on the Azure platform by...
creating an Azure Virtual Machine with a Windows Server 2008 R2 OS
installing WampServer 2.2E (Apache 2.2.22 / PHP 5.3.13 / MySQL
5.5.24) in the VM as a quick and easy way to test whether this approach would work
copying the above PHP script into the WampServer "www directory"
launching WampServer
selecting the "Put Online" option from the WampServer Menu (accessed by left-clicking the WampServer icon in the Windows Taskbar Notification area)
creating an "Inbound Rule" for the VM firewall to allow connections to port 80
...and thankfully the script ran successfully!
Ideally, I would still like to get this working as an Azure cloud service as it shouldn't be necessary for me to maintain the PHP installation in a full VM.
UPDATE 2
I tried restarting the cloud service, then remotely connecting to an instance of the cloud service and looking in the Application Event Viewer. I saw that WMI logged 1 error during startup:
Event filter with query "SELECT * FROM __InstanceModificationEvent WITHIN 60
WHERE TargetInstance ISA "Win32_Processor" AND TargetInstance.LoadPercentage > 99"
could not be reactivated in namespace "//./root/CIMV2" because of error 0x80041003
Events cannot be delivered through this filter until the problem is corrected.
I then ran the above script a couple of times and rechecked the Application Event Viewer but nothing had been logged.
I also checked the IIS logs and the Azure log, startup-tasks-log and startup-tasks-error-log files to no avail.
After giving up on solving this last year. I made another concerted effort to resolve it this week and succeeded!
I basically needed to (a) enable the php_com_dotnet.dll to allow use of COM and VARIANT classes, and (b) grant default Local Activation permission to IIS_IUSRS to allow access to the COM component. I've listed the detailed steps I took below...
Add a folder called php in the web role's bin folder
As of PHP 5.3.15 / 5.4.5, in order to use the COM and VARIANT
classes, the php_com_dotnet.dll needs to be enabled inside of
php.ini. Previous versions of PHP enabled these extensions by
default (source: http://www.php.net/manual/en/com.installation.php). In
the php folder, create a php.ini file containing only the following
lines...
[COM_DOT_NET]
extension=php_com_dotnet.dll
Create a SetDCOMPermission.reg file in the bin folder which contains the following content, to grant default Local Activation permission to IIS_IUSRS...
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OLE]
"DefaultLaunchPermission"=hex(3):01,00,04,80,74,00,00,00,84,00,00,00,00,00,\
00,00,14,00,00,00,02,00,60,00,04,00,00,00,00,00,14,00,1F,00,00,00,01,01,00,\
00,00,00,00,05,12,00,00,00,00,00,18,00,1F,00,00,00,01,02,00,00,00,00,00,05,\
20,00,00,00,20,02,00,00,00,00,18,00,0B,00,00,00,01,02,00,00,00,00,00,05,20,\
00,00,00,38,02,00,00,00,00,14,00,1F,00,00,00,01,01,00,00,00,00,00,05,04,00,\
00,00,01,02,00,00,00,00,00,05,20,00,00,00,20,02,00,00,01,02,00,00,00,00,00,\
05,20,00,00,00,20,02,00,00
I don't know if the above registry change will work for everyone, so the process I used is documented here (it essentially involved using a program called RegFromApp to record the changes made to the registry when granting default Local Activation permissions for IIS_IUSRS in COM Security and to save the registry changes as a .reg file into the web role's bin folder).
Copy and paste the out-of-process COM component (OleAutomationFeasibilityModel.exe file) into the bin folder
Create a RegisterOleAutomationFeasibilityModel.cmd file in the bin folder to register the COM component and set the necessary permissions to launch it...
chcp 1252>NUL
OleAutomationFeasibilityModel.exe /regserver
regedit.exe /s SetDCOMPermission.reg
exit /b 0
In the ServiceDefinition.csdef file, insert a reference to the .cmd file immediately before the closing Startup tag...
<Task commandLine="RegisterOleAutomationFeasibilityModel.cmd" executionContext="elevated" />
Publish the web role
Hope that helps someone in a similar situation!
I have a php web application that needs to access a PI-Datasource using an application-library written for windows on dll form to fetch the data. Due to the non-polimorphism of PHP we are using a wrapper written in C#-Dotnet in order to use the polimorphism library.
PHP->Wrapper->Lib->PI-System
The problem: PHP crashes, without leaving a log, on the creation of the com object (almost always on every second request). My thought was that probably something in the existing php code could be wrong that causes this fatal-error and after a lot of debugging and trying I simplified the code to this:
$connection = new Com('Something.SomethingClass');
with the variable $connection not being used NEVER! and still every 2nd time I get php-crash (documented in windows error log with an 1000-Error and an 1001-Information)
>Faulting application name: php-cgi.exe, version: 5.4.11.0, time stamp: 0x511a30ec
>Faulting module name: KERNELBASE.dll, version: 6.1.7601.17932, time stamp: 0x503275ba
>Exception code: 0xc0000005
>Fault offset: 0x0000d3cf
>Faulting process id: 0x14d0
>Faulting application start time: 0x01ce89dd0ae23748
>Faulting application path: C:\Program Files\Zend\ZendServer\bin\php-cgi.exe
>Faulting module path: C:\Windows\system32\KERNELBASE.dll
So i tried to generate even more com objects..
$connArray = array();
for($i = 0; $i < 50 ; $i++){
Core_System_Log::getInstance()->logWithoutMessageId('Before: ' . $i ,Core_System_Log::DEBUG);
$connArray[i] = new Com('Something.SomethingClass');
Core_System_Log::getInstance()->logWithoutMessageId('After: ' . $i, Core_System_Log::DEBUG);
}
All 50 were generated with no problem, and again every 2nd time i tried i got a php fatal error.
I tried to used all 50 of them, and they all read values from the PI-System with no problem.
I tried to unset the variables and call also the gc, call the destructor from C#, check the constructor from C# (which just makes an object of the library and had no exception, the object was normally created and still php crashed) but the problem did not disappear.
So, is there any idea? am i doing something wrong (how can it be wrong when every 2nd time it is properly reading the values)?
Environments Tested:
OS:Windows Server 2008 R2 64Bit / Windows 7 Prof SP1 32/64Bit
PHP: 5.3.9/ 5.3.14 / 5.3.21 / 5.4.11
WS: Apache and IIS (few different versions)
UPDATE: The problem was finally in the C# code. There was a call to GC which did not allow the COM object to be closed/deleted correctly having as a result C# to hang (again with no exception) and "triggering" the php fatal error.
Thanks for the responses.
If returns crashed without logging into file it look that in code contains sign #.
Example:
#some_function()
This will call function, but if has any errors it will not showing to you, just skipping. Due to some errors PHP can be stopped.
But, can you try upgrade PHP to 5.5 on Windows server?
If you know in which of lines of code throws an error and want to skip, just put isset()
If isset($somevar) or isset(function()) returns true that means are not errors, but if you don't want to stop a function on errors put isset() on a line of code where errors occurred.
I'm not sure how looks class and function inside PHP->Wrapper->Lib->PI-System code so I can tell fully corrected answer.
UPDATE: The problem was finally in the C# code. There was a call to GC which did not allow the COM object to be closed/deleted correctly having as a result C# to hang. The object was somewhere kept in Ram and the second time the wrapper was called it just hanged/exited (again with no exception) which "triggered" the php fatal error.
I'm building a new aplication that needs some com components, but everytime that i try the code
$obj = new com("Excel.Application") or die("Unable to create com object");
or
$obj = new com("zkemkeeper.ZKEM.1") or die("Unable to create com object");
or
$obj = new com("Bullzip.PDFPrinterSettings") or die("Unable to create com object");
I always get a reponse like this
Fatal error: Uncaught exception 'com_exception' with message 'Failed to create COM object `X.X':
Access is denied. ' in C:\inetpub\wwwroot\XXXX\XXXX.php:X
Stack trace:
#0 C:\inetpub\wwwroot\XXXX\XXXX.php(X): com->com('Excel.Applicati...')
#1 {main} thrown in C:\inetpub\wwwroot\XXXX\XXXX.php on line X
Already verified directory, dcom, application, etc settings to allow the use of those components, alreay registered and installed the needed apps, and so on, but at the end i can't get this thing running.
The components are installed and "visible" to applications, already tried with java, vb, c# and those coms works fine, but with php are not working.
Specification of servers are this
PHP 5.4.9
IIS 7.5.7600
Windows 7 Ultimate 64bit/Windows Server 2008
R2 64bit (tried on both servers)
any ideas?
UPDATE, finally some com components are working like excel and bullzip, zkemkeeper still not working, can't find any usefull information about that dll, all i have found is a solution editing registry an adding guid and clsid to wow6432 but didn't worked for me, somebody have used that component? (i mean zkemkeeper)