A script to turn xdebug On works but I cannot figure out out to create a shortcut to run it. If I open administrator PowerShell in C:\Users\George\Desktop\Development\Config Files, the command .\PHPxDebugOn will restart Apache with the modified php.ini. (There's also a PHPxDebugOff.ps1 to turn xdebug off.) Clicking on the shortcut (with Run as administrator ON) just flashes a black screen but no change to Apache.
script:
$iniFile = "C:\Users\George\Desktop\Development\Config Files\php.ini"
$xFile = "C:\Users\George\Desktop\Development\Config Files\xdebug.ini"
$phpIniFile = "C:\PHP\php.ini"
get-content $iniFile, $xFile | set-content $phpIniFile
C:\Apache24\bin\httpd -k restart
shortcut target:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -file "&C:\Users\George\Desktop\Development\Config Files\PHPxDebugOn.ps1"
The problem is in the shortcut target.
Removing the & symbol should resolve the script not running, provided the path is correct.
PowerShell exits without attempting to run the script if the target file in the shortcut is invalid in any manner. Unless everything in the command can be evaluated/parsed/retrieved, the default behavior is to stop everything and report the error. That explains why the window disappeared, even with the -NoExit parameter specified. PowerShell does present the error in the brief moment that window is visible. Screen refresh rates and processor speeds being what they are, screenshots were a bit of a challenge to catch.
Sample 1:%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -file "&C:\scripts\hello.ps1"
Sample 2:%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -file "C:\scripts\hello.ps2"
Sample 3(successful):%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -file "C:\scripts\hello.ps1"
Notes:
Repro environment: Windows 7 Enterprise with Powershell 5.0 April 2015 preview
The .ps2 file extension may be valid on some systems
You can skip loading PowerShell profiles by using the -NoProfile parameter
File must be the last parameter in the command, because all characters typed after the File parameter name are interpreted as the script file path followed by the script parameters
Seeing as my comment is, according to the OP, a better approach to the problem, I'll post it here as an answer:
What I'd do is create a second virtual host that points to the same source, but loads separate php.ini files to enable xdebug on that vhost. That way, you can simply use http://local.project.dev and http://local.project.debug to run the same code with xdebug enabled. This way, you don't have to restart apache each time you want to use xdebug to step through the code.
Related
Does anybody know how to debug CLI PHP scripts from the CLI?!? I don't want to debug a PHP web page - I don't have a PHP web page. I don't want to debug a remote script either - I'm running/debugging right here on this system. I don't want to (at this time) try to get some IDE (Eclipse, PhpStorm or whatever) to debug a CLI PHP rather I just want to debug some PHP CLI script at the Linux command line itself. In Perl this would be simply perl -d <script.pl> <options>. Debugging a script, to me, is not figuring out compile errors or other simple things. To me it's setting break points, running code, examine the contents of variables and being able to arbitrarily execute or eval ('<php code>') at the debugger.
Sure later I'd like to configure this into my IDE of choice (at this time this is Eclipse) but I have not managed to get that working. Debugging from the CLI a PHP CLI script would be a good start for me.
Thanks.
I don't know why I'm limited to a character count when posting a comment. Perhaps I can add more text here.
Here's what I have tried in order to use xdebug and/or Zend debugger with Eclipse:
Base Eclipse version Mars.1 Release 4.5.
Eclipse PDT UI Plugin version 3.7.0.2015112
Tried installing xdebug using pecl install xdebug. Says I need to add "zend_extension=xdebug.so" to php.ini. Really? Which php.ini? I have several:
Andromeda:sudo find / -xdev -name php.ini
/etc/php5/cli/php.ini
/etc/php5/apache2/php.in
/opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php53/php.ini
/opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php5/php.ini
/opt/eclipse/plugins/com.zend.php.debug.debugger.php56.linux.x86_64_13.0.1.v20151112-2045/resources/php56/php.ini
Andromeda:
I put the zend_extension thing in both /etc/php5/cli/php.ini and /etc/php5/apache2/php.ini. Made a phpinfo.php page and I see Xdebug in there (yea!). Configure a Debug Configuration in Eclipse to use xdebug and try to debug:
Launching renameUser has encountered a problem. An internal error occurred during "Launching renameUser" java.lang.NullPointerException.
Oh goodie...
I had also installed the Zend Debugger and added the following to those same two php.ini files:
zend_extension=/usr/lib/php5/20121212/ZendDebugger.so
zend_debugger.allow_hosts=127.0.0.1/32, 192.168.0.0/16
zend_debugger.expose_remotely=always
Changed debug configuration to use Zend Debugger and attempted to debug. Received:
Error launching 'renameUser' The debug session could not be started. Please make sure that the debugger is properly configured as a php.ini directive.
Restarted Eclipse and now the debugger attempts to run but simply terminates with a 255 exit value attempting to run /opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php5/php-cgi. Why it's runnign php-cgi is beyond me. I said this was a CLI not a CGI. In any event I get the following when trying to run this from the command line:
Andromeda:/opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php5/php-cgi
/opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/php5/php-cgi: error while loading shared libraries: libiconv.so.2: cannot open shared object file: No such file or directory
Found a libiconv.so.2 in /opt/eclipse/plugins/org.zend.php.debug.debugger.linux.x86_64_5.3.18.v20110322/resources/lib and set LD_LIBRARY_PATH to include that but this just fails to launch the debugger at all stating to make sure that the debugger is properly configured as a php.ini directive... UGH!
Other odd stuff:
When Eclipse starts up it fails to open my RSE based project thus displaying edit buffers from the last run as empty
Eclipse will no longer exit! Select File: Exit. Nothing happens. Click on the X in the title bar - nothing happens. Now I have to kill it to close it!
When debugging on the command line you need to tell PHP you want to debug also
http://xdebug.org/docs/remote
says
export XDEBUG_CONFIG="idekey=session_name"
php myscript.php
assuming xdebug is enabled (it doesnt matter which .ini file its in, but there is a standard place per OS for this, usually in a conf.d folder called xdebug.ini which is auto included)
This allows you to debug a cmdline script.
Personally I use Vim with Vdebug extention (xdebug for vim) to debug and nothing other than a command line is needed
What worked for me was using dephpugger. I found the steps to get CLI debugging working here:
https://hackernoon.com/how-debug-php-applications-with-dephpugger-98cc234d917c
I had previously installed xdebug and tried out exussum's answer.
The steps I followed are included here for completeness.
Install dephpugger:
composer global require “tacnoman/dephpugger”:”dev-master”
Put dephpugger on the path:
export PATH=$PATH:$HOME/.composer/vendor/bin
make sure to include in the php file at the breakpoint:
xdebug_break();
open up 2 terminal instances. In one run:
dephpugger debug
In the other run
dephpugger cli /path/file.php
replacing /path/file.php with the path to your file. if you need command line arguments to the php script put the path and arguments in quotes. It still seems a little hacky. I think the real trick is to write in a language that has a better debugger built in.
exussums answer works for me.
In addition I have the following in /etc/php/7.0/cli/conf.d/20-xdebug.ini
zend_extension=xdebug.so
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_enable=true
#xdebug.remote_enable=false
And I had to do this: https://github.com/vim-vdebug/vdebug/issues/363
Being able to set break points in a PHP script requires some kind of debugger extension being loaded, either XDebug or Zend Debugger.
And then you need some kind of interface to this debugger to make your wishes about break points known. I am unfamiliar with the Perl debugging, but I haven't heard about any PHP CLI based debugging - it is always taking place in an IDE that is able to handle the debugging protocol of one of the extensions.
Of course there is the good old var_dump();die('hi'); debugging, but this does not include continuing code execution after the script ended. ;)
I have added this line PATH DEFAULT=${PATH}:~/bin/ to the ~/.pam_environment
This allows me to call ffmpeg from command line without path which is obviously in ~/bin/ dir so everything works fine as long as im ussing command line.
But if try to run the exact same command from php all i get is sh: ffmpeg: not found
And the code is
shell_exec("ffmpeg 2>&1");
So from my very little experiance with linux (in this case Ubuntu to be specific) i guess apache has no access to pam_environment or ~/bin
What can i do to make this work?
look at the output of phpinfo(), it has a section with all environment variables it sees. then look at your webserver configuration, maybe it's sanitizing the environment, or maybe the init script which starts your webserver does it.
and is the account the webserver is running under using PAM at all?
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.
I am having difficulty with the PHP exec() function. It seems to not be calling certain functions. For instance, the code echo exec('ls'); produces no output whatsoever (it should, there are files in the directory). That main reason this is a problem for me is that I'm trying execute a .jar from a PHP exec() call.
As far as I know I'm calling the java program properly, but I'm not getting any of the output. The .jar can be executed from the command line on the server. (For the record, it's an apache server).
My php for the .jar execute looks like this:
$output = array();
exec('java -jar testJava.jar', $output);
print_r($output);
All I get for output from this exec() call is Array().
I have had success with exec() executing 'whoami' and 'pwd'. I can't figure out why some functions are working and some aren't. I'm not the most experienced person with PHP either, so I'm not too sure how to diagnose the issue. Any and all help would be appreciated.
The reason why you are not able to execute ls is because of permissions.
If you are running the web server as user A , then you can only ls only those directories which have permissions for user A.
You can either change the permission of the directory or you can change the user under which the server is running by changing the httpd.conf file(i am assuming that you are using apache).
If you are changing the permissions of the directory, then make sure that you change permissions of parent directories also.
To change the web server user, follow following steps:
Open the following file:
vi /etc/httpd/conf/httpd.conf
Search for
User apache
Group apache
Change the user and group name. After changing the user and group, restart the server using following command.
/sbin/service httpd restart
Then you will be able to execute all commands which can be run by that user.
EDIT:
The 'User' should be a non-root user in httpd.conf. Apache by default doesnot serve pages when run as root. You have to set user as a non-root user or else you will get error.
If you want to force apache to run as root, then you have to set a environment variable as below:
env CFLAGS=-DBIG_SECURITY_HOLE
Then you have to rebuild apache before you can run it as root.
I have found the issue - SELinux was blocking PHP from accessing certain functions. Putting SELinux into permissive mode has fixed the issues (although, I'd rather not have to leave SELinux in permissive mode; I'd rather find a way of allowing certain functions if I can).
I have a solution:
command runs from console, but not from php via exec/system/passthru.
The issue is the path to command. It works with the absolute path to command
So that:
wkhtmltopdf "htm1Eufn7.htm" "pdfIZrNcb.pdf"
becomes:
/usr/local/bin/wkhtmltopdf "htm1Eufn7.htm" "pdfIZrNcb.pdf"
And now, it's works from php via exec
Where command binary you can see via whereis wkhtmltopdf
Tore my hair out trying to work out why PHP exec works from command line but not from Apache. At the end, I found the following permissions:
***getsebool -a | grep httpd*** ---->
**httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off**
USE: setsebool -P httpd_ssi_exec 1
SEE: https://linux.die.net/man/8/httpd_selinux
Your problem is not an execution issue but the syntax of the exec command. The second argument is always returned as an array and contains a single line of the output in each index. The return value of the exec function will contain the final line of the commands output. To show the output you can use:
foreach($output as $line) echo "$line\n";
See http://php.net/manual/en/function.exec.php for details. You can also get the command's exit value with a third argument.
When I call /usr/local/bin/pdftk from PHP in Apache (via shell_exec(), exec(), system(), etc.), it returns the SYNOPSIS message as expected.
When I call /usr/local/bin/pdftk input.pdf fill_form input.fdf output output.pdf flatten via shell_exec(), nothing returns.
When I copy and paste the exact same string to the same path in the shell (as the apache user), the output.pdf file is generated as expected.
Moving the pdftk command into a PHP shell script (shebang is #!/usr/bin/php) and executing it with php script.php works perfectly.
Calling that shell script (with its stderr redirected to stdout) from PHP in Apache (via shell_exec(script.php);) results in this line:
sh: line 1: 32547 Segmentation fault /usr/local/bin/pdftk input.pdf fill_form input.fdf output output.pdf flatten 2>&1
Whenever I run the script from the command line (via PHP or directly), it works fine. Whenever I run the script through PHP via Apache, it either fails without any notification or gives the SegFault listed above.
It's PHP 4.3.9 on RHEL4. Please don't shoot me. I've set memory to 512M with ini_set() and made sure that the apache user had read/write to all paths (with fopen()) and by logging in as apache ...
Just went and checked /var/log/messages to find this:
Oct 4 21:17:58 discovery kernel: audit(1286241478.692:1764638):
avc: denied { read } for pid=32627 comm="pdftk" name="zero"
dev=tmpfs ino=2161 scontext=root:system_r:httpd_sys_script_t
tcontext=system_u:object_r:zero_device_t tclass=chr_file
NOTE: Disabling SELinux "fixed" the problem. Has this moved into a ServerFault question? Can anybody give me the 30 second SELinux access controls primer here?
php-cli & php-cgi (or the module, depends on what your server uses) are different binaries. They don't even have to share the same version to live happily side by side on your server. They also may not share the same configuration. Increasing memory usually does nothing to help Segfaults. Points to check:
Are they the same version?
Do they have the same settings (consult the *.ini locations loaded in the phpinfo(); output, and possibly the whole output itself), if not: try what happens if you alter the one for your webserver to the one for the cli as far as possible.
Segfaults occur more in extensions then in the core afaik, and sometimes seemingly unrelated. Try to disable unneeded extensions one by one to see if the problem goes away.
Still no success? You may want to run apache with gdb, but I have no experience with that, it might tell you something though.
No luck? Recompile either the module of cgi your webserver uses.
It's PHP 4.3.9 on RHEL4. Please don't shoot me.
I feel more sad for you then anger, we're beyond the 5.3 mark, come over, it's a lot more happy here.