This blogpost is an update for a old (2012) post on using the Win32 OutputDebugString API method from within PHP. To view the output of this Win32 API call, download dbgview.exe from SysInternals.com.
The solution presented takes another route (not through Borland Delphi but using .net) and will therefor only work on Microsoft Window based PC’s.
The code will display debug output no matter if code is being debugged or running freely on a webserver as Xampp. This enables debugging of code that is hard to debug due to nesting or has no good spots to put a breakpoint.
The easiest way would be to load/use System.Console using PHP’s dotnet class but that the Console class is a static class which are not supported by PHP’s dotnet class.
So I ended up creating a small wrapper which is available at Swiss Tools Homepage (bitbucket.io).
Compiling & installing the wrapper is a matter of four steps:
1) Create your own key for signing this assembly.
2) Compile the project using Visual Studio.
3) Add your assembly to GAC (use “gacutil.exe”)
a) Using PowerShell (Elevated) get the full assembly name using:
[System.Reflection.AssemblyName]:: GetAssemblyName(“bin\Debug\PhpConsole.dll”).FullName
b) Then install the assembly into the GAC using the PowerShell Command:
& “C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\gacutil.exe” /i “bin\Debug\PhpConsole.dll”
Note the location of GacUtil.exe might vary a bit.
4) Enabled the com_net extension which contains PHP’s dotnet class in the php.ini by adding:
extension=php_com_dotnet.dll
After this one can test the wrapper by starting DbgView.exe and running php code alike:
<?php
// Init $console
//
$console = new dotnet(“PhpConsole, Version=1.0.14.0, Culture=neutral, PublicKeyToken=c4a0f801a32e3553”, “PhpConsole.ConsoleUtils”);// Use $console.
//
$console->ODS(“Hello World from PhpConsole.”);
A more extensive example is:
<?php
…. create a class here
// Init $this->console
//
if (extension_loaded(‘com_dotnet’)) {
// Load .Net Assembly fro GAC.
$this->console = new dotnet(“PhpConsole, Version=1.0.14.0, Culture=neutral, PublicKeyToken=c4a0f801a32e3553”, “PhpConsole.ConsoleUtils”);
} else {
// Generate a fake method ODS($msg) and Clear() if com_dotnet is not loaded.
$this->console = new class() {
public function ODS($msg) {
$a=1;
}
};
$this->console = new class() {
public function Clear() {
$a=1;
}
};
}// Use PhpConsole
//// Clear DebugView Window.
//
$this->console->Clear();
$this->console->ODS(“Hello World from PhpConsole. @ “. __LINE__);
$this->console->ODS(__METHOD__.”() @ “. __LINE__);// Remove Prefix
//
$this->console->Prefix=””;
$this->console->ODS(__METHOD__.”() @ “. __LINE__);// Change Prefix to ‘[PHP]’
//
$this->console->Prefix=”PHP”;
$this->console->ODS(__METHOD__.”() @ “. __LINE__);
If added to a class, it creates a console class and attached it to $this.
The first line of the output looks like:
[32208] [ODS] Hello World from PhpConsole @ 27
where [ODS] is an adjustable prefix that can be used to narrow the filtering in DbgView.
The console class has only a two methods:
Clear(), which clears DbgView’s window
ODS(string), which sends a string to DbgView
and one property
Prefix, used to alter the line prefix.
The code presented above creates a dummy object if com_dotnet is not loaded (which happens on Linux machines or when the com_dotnet extension is disabled) so code using the $console will not fail.
Additionally one could swap:
$this->console
for
$console
and create a standalone class which could be declared global.