PHP request on self - php

I experience problem with PHP request on self. In example I will use file_get_contents() but same happen for exec('wkhtmltopdf [*SELF*]') or curl()
lets name my server example.com
apache2 installed
FastCGI (multiple PHP versions 5.3, 5.4, 5.5, 5.6, 7.0)
now I have 2 dummy scripts
1st script
//get-html.php
file_get_contents('http://example.org/index.html')
2nd script
//get-php.php
file_get_contents('http://example.org/index.php')
Testing
1) command-line: php get-html.php // Success
2) browser: example.org/get-html.php // Success
1) command-line: php get-php.php // Success
2) browser: example.org/get-php.php // Timeout
What I tried next
create subdomain like subdomain.example.org/index.php to have differet PHP version for get-php.php and for index.php
amend /etc/hosts
request on other sites (like google.com) // Success
session_write_close() before file_get_contents() and session_start() right after does not work also
So my suspect is mod_fastcgi. It seems like the apache is not able to run 2 instances of this to handle PHP requests which comes from itself. As running script from command line works as expected.
Does anybody have any advice?

I did not set PHP_FCGI_CHILDREN what is in default 1.
When I called in PHP script another PHP script from my server over apache it failed as it was not able to create another PHP FCGI instance.

Related

How to use PHP to execute AutoHotKey script on Windows Server 2016?

I have a Windows Server 2016 VPS with Plesk and PHP 7.1x.
I am trying to execute a simple AutoHotKey script from PHP using the following command:
<?php shell_exec('start /B "C:\Program Files\AutoHotkey\AutoHotkey.exe" C:\inetpub\vhosts\mydomain.com\App_Data\myahkscript.ahk'); ?>
This is the only line on the page. I have tried different ahk scripts, the current one simply creates a MsgBox.
When I execute my php page, on VPS Task Manager I see three processes created with the expected USR: cmd.exe, conhost.exe and php-cgi.exe. However, my PHP page just sits waiting on the server and nothing actually happens on the server.
I have also tried the same line except replacing shell_exec with exec. This seems to make no difference. I have tried without start /b with both commands. In that case the PHP page completes but no new processes are started.
I cannot find any errors in any logs: Mod_Security, Plesk Firewall, IIS.
Any ideas?
EDIT:
I tried my command from the VPS command prompt and immediately slapped in the face with the obvious issue of the space in 'Program Files'. I quoted the string as shown above and the command works. This eliminated the hang when running from PHP. However, the command still does nothing when executed from the web page.
EDIT:
Based on suggestions from the referenced post 'debugging exec()':
var_dump: string(0)""
$output: Array()
$return_val: 1
One point was that I would probably not be able to invoke GUI applications. That puts a damper on the idea.

Unix sockets doesn't work with PHP on Apache

I wrote a following short script in PHP:
<?
$s = socket_create(AF_UNIX,SOCK_STREAM,0);
socket_connect($s,"/tmp/tmpsock");
socket_write($s,"test");
socket_close($s);
>
I user this code to connect to a simple server that prints everything it receives onto terminal output.
The script works fine when I opened it from terminal using php index.php, however I want it to be a part of a webapp, and I try to run it on apache2 server opening the index.php page in web browser (on server of course). The script doesn't work then - the socket_connect function returns nothing, the error description is "Success()" and the message doesn't appear on server.
I use Ubuntu 16.04, Apache 2.4 and PHP 7.0

PHP proc_open & exec timeout but cli works fine

I'm currently using the Symfony Process component, which relies on the proc_open function of PHP. I need to launch a command to wkhtmltopdf, which has this form :
/usr/local/bin/wkhtmltopdf --window-status "___RENDER_PDF___" --orientation "portrait" --run-script "window.basilOptions = {storages: ['memory'] }; document.body.addEventListener('status:app:rendered', function () { window.status = '___RENDER_PDF___'; });" "http://localhost/p/lps#poll/lpsp002" "/tmp/pdf_d6fbWO"`
When I run this command directly on my shell, it works just fine and takes about 6 seconds to be executed. But when I'm using PHP with the Process Component, it goes into a timeout... And when using the exec or proc_open functions, it runs indefinitely. The default timeout for the Process Component is 60 seconds (even extending it doesn't have any effect).
I tried this on PHP 5.4 and PHP 5.5, but the result seems to be same.
Any ideas why this command runs just fine on the shell but not through PHP ? Tested on MAMP and not MAMP environments (on 5.4 and 5.5 versions). It works on Ubuntu 14.04 with PHP 5.5 though.
I thought that maybe, when getting through PHP and MAMP, the process could be completed but still hangs as was reported with this bug ? I'll update when i'll have some more information, to see if the PDF is indeed generated or not.
Thanks.
The problem could be caused by session locking - current PHP page thread locks session for writing, so another page on the same server waits for session to be unlocked (on sessions_start() function) to process request (dumping into PDF). This creates dead lock, because session by default starts with write lock for other threads.
To prevent this session deadlock, close session for write by adding session_write_close(); before command and if you need write to session again just after PDF is rendered add session_start(); after PDF rendering

PHP + PhantomJS Rasterize

I'm using PhantomJS 64 bit in my PHP application to dynamically capture an HTML page to be emailed to the user.
phantomjs rasterize.js "http://..." /path_to_images/image.png
This method works fine when I run the above on the command line but when the PHP script runs the command using exec it fails with no output and returns exit code 11.
If I switch it to use the 32 bit phantomJS binary, the command succeeds but fails to load the google JSAPI on the page since with error Reference Error: can't find variable google. This is a problem because not all of the page content is loaded and captured as an image. The JSAPI is included using HTTPS. If I switch to HTTP, the reference error is gone but the rendered image comes out all black.
I tested the command as the same user that php is running as.
To sum it up:
command> phantomjs_64 rasterize.js "http://..." /path_to_images/image.png
OK
exec('phantomjs_64 rasterize.js "http://..." /path_to_images/image.png');
No Output, Exit Code 11
command> phantomjs rasterize.js "http://..." /path_to_images/image.png
exec('phantomjs rasterize.js "http://..." /path_to_images/image.png');
Incomplete Output
Does anyone know why the default phantomJS rasterize.js script would fail when running on PHP or have a workaround for this?
UPDATE: This great article by Arlo Carreon points out how to make this work on HostGator shared hosting (this was my problem). Simply add 2>&1 at the end of the command to redirect the output. The 64 bit version still does not work but this fixes the 32 bit version.
It turns out that this only happens when the PHP script is requested through the Apache web server. The workaround is to create a database entry for users that need to receive the email and setup a cron to execute the PHP script that calls PhantomJS for each user entry in the DB. When the cron is set to run at the smallest interval the user perceives that the email was generated and sent immediately.

Run PHP script in background on Apache start/restart(Windows Server)

I've installed Apache 2.4 with PHP 5.4 on Windows Server 2008 following instructions from this manual:
Apache installing manual.
Apache runs as a service now.
My application requires a php websocket script to run in the background. I'm running it manually with:
php myscript.php
The question is: Is there a way to start a background script automatically on system(apache) restart?
I found the following topic, but I didn't know where I could find an apache startup script for Windows.
Any help will be much appriciated.
I come up with a solution :)
Create an environment variable pointing to your Apache directory
APACHE_HOME = C:/PATH/TO_APACHE
Rename %APACHE_HOME%\bin\httpd.exe to %APACHE_HOME%\bin\httpdVendor.exe
Create a batch file and put the following code :
php myscript.php
%APACHE_HOME%\bin\httpdVendor.exe -k runservice
exit 0
Download/Install the free software BatToExeConverter (next, next, ...)
Open the installed converter and open your freshly created batch file
Click on the button Build EXE (let the default configuration)
Save the file : %APACHE_HOME%\bin\httpd.exe
Start your Apache Server
Tested on : Windows 7, Apache 2.4, Advanced Bat to Exe Converter 2.92
Use built in Windows Task Scheduler which triggers .bat script, which calls curl with defined url.
Download curl from http://curl.haxx.se/download.html and extract curl.exe on any directory, but we will use c:\backgroundtasks
Adjust script below to your needs:
cd c:\
cd c:\backgroundtasks
curl http://localhost/path/to/script.php
exit
Configure Task Scheduler to run as basic task:
General tab - as system account (to run when you are not logged in server)
Triggers tab - adjust frequency
Settings tab - at bottom set If the task is already running... to Stop the existing instance
The best method here would be to use Windows services dependencies.
Make a php-websocket-server.cmd file with any necessary environment settings (e.g. changing to a directory, setting PATH, etc...) with the last line:
php myscript.php
Install the Windows Server Resource Kit Tools, to get srvany and instsrv to create a user defined service. Note the install path as you'll need it in the next step.
Open a cmd shell and run:
<path_to_resource_kit>\instsrv PHPWebSocketServer <path_to_resource_kit>\srvany.exe
Next, create a file php-websocket-server.reg containing the following (update for your environment):
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PHPWebSocketServer\Parameters]
"Application"="c:\\path\\to\\php-websocket-server.cmd"
Import it by double-clicking or regedit /s php-websocket-server.reg
Back in your cmd shell:
sc config Apache2.4 depend= PHPWebSocketServer
to make the Apache2.4* service depend on your php service. Now, when Apache is started, the php service will be brought up first. And likewise, if you stop the php service Apache will stop along with it.
*the howto indicates that the service is named "Apache2.4" but you may want to verify in your installation.
When running as service, you won't have the startup script.
Execute some service implementation that allows running other programs as services, and then make the new service (which is running your script) a dependency of the Apache service. However, this will not restart the script when apache restarts.
One possible solution using SrvStart, and another using ServiceEx.
Perhaps don't install Apache as a service, and then edit the startup/restart script, and use the above method to run Apache as service (instead of using Apache's own installer).
Create bat file,e eg 'myphp.bat' containing path/php myscript.php. Include the correct path to php if it's not path'd.
create a bat file, eg runmyphp.bat containing
AT 00:00 /every:M,T,W,Th,F "cmd /c /path/myphp.bat", again including the correct path.
Then use explorer to drag runmyphp into the startup folder, so it will always run on system startup.
Google 'windows at command' or 'windows cron' to get all the correct syntax for the 'at' command, but you can currently find a detailed explanation here.
I found another answer C:\wamp\scripts\wampserver.lib.php this file is run every time when your wamp starts
include your file path include_once("file_path"); to this file and its done . this is perfect solution which you want
Enjoy!!!!!!!!!
Although the solution of Halayem Anis is very creative, I think its important to note that you can never be sure that a PHP script keeps running in the background. So if you choose to start your script on "Apache start", then you probably end op resetting Apache quite often, simple to reboot your script.
I assume that's even how you came to this question, as on a normal server you never have to touch the Apache reset button. It starts on system start and then it just runs. If that was the case, you could simple run your php myscript.php command on start up.
Considering there is no way to make sure the script keeps running, I would use a different approach, where I check if it is running and if not, restart it.
So the first step is to make it possible to track if the script is running. I would go for the simple approach where your myscript.php writes a single byte to a file every 5seconds or so. This way I can use the last modified time on the file to see if it is still running, because last modified time + 5 seconds < now == not running.
You could also store the last access time in a database every 5 seconds or so. Might be slightly faster then accessing files if you have a lot of traffic.
The second part is to have each request check if the script is running. For this two work I would use the PHP.ini to prepend a php script on every request. You can do it with the auto_append_file option.
This prepend script would work like this:
<?php
$filename = 'checkonline.txt';
$cmd = "php myscript.php";
if (filemtime($filename)+5<time()) {
//run in background without freezing php
//based on code posted on PHP exec manual, linked below
if (substr(php_uname(), 0, 7) == "Windows"){
pclose(popen("start /B ". $cmd, "r"));
}
else {
exec($cmd . " > /dev/null &");
}
}
?>
Make sure to check how filemtime and exec work and what you need to keep in mind. They work slightly different on Windows/*nix.
Wrap-up all your required processes in a batch file and use RunAsService
With some tweaking, you can ensure that your service starts before Apache.

Categories