It's been far too long. And I need to rant.
Recently I've mostly been working with PHP, and debugging my programs on a server, using Eclipse and XDebug remote debugging when it needed to be step-by-step. This has not always worked well, but it worked well enough for most purposes.
Usually I just wrote the code, uploaded it, tried it out, fixed problems. Only occasionally would I need to open Eclipse and do step-by-step debugging. When I opened Eclipse, all of the windows to the source code would be blank, and I had to close them all, open the remote-access project, and then re-open the source. It was a pain, but doable.
Then, for some reason Eclipse and XDebug decided that they weren't going to handle breakpoints properly on my latest Joomla-based project (Joomla is a PHP-based CMS).
And then Eclipse refused to terminate - it had to be killed using the Task Manager.
After several rounds of dealing with that, I figured out how to fix the termination problem using the "-clean" and "-clearPersistedState" options at startup. But it still didn't want to do step-by-step debugging.
Okay. It is probably some interaction between the remote access and Joomla's massive number of files. I'll have to install and work it locally. Originally that was a problem, but I managed to get Microsoft SQL Server working with PHP locally a couple of months ago, so this should be no biggie. Right?
Joomla installation is simple - just unzip the files and open the root folder in your browser. Enter some data - especially database login credentials - and you're off to the races.
Except this time, it returns to the final "these are the options you chose" screen, before the "success" screen.
No error message. No red markings saying "this option is bad", nothing. It just returns.
After several rounds of retrying with varied options, I tried duckduckgoing the problem (Duckduckgo is like Google, but without tracking you and biasing your results). No one seemed to have my specific problem: most people were using Linux instead of Windows. And when they were using Windows, they used XAMP (a package containing everything one needs for a modern webserver: Apache WebServer, Tomcat, Java, MySQL). I hadn't installed that because when I first tried it, I didn't have enough space, and because I needed some feature of Microsoft's IIS at the time.
So... being the stubborn SOB I am, I decided to debug the problem. After a false start or two, I got Eclipse and XDebug to play nice locally, and started the Joomla installation. Boom: before the first Joomla screen, it gives me two error messages in the browser: some MySQL error, followed by an error about sending headers twice. sigh.
So, why is it even trying MySQL? I try debugging into it, to find out why it's calling MySQL, which I don't have installed. It turns out it simply tries it as its first default. Hmmm. I change the default to SQLSRV (which I think I have), but that fails for some reason - it later turns out that the Express version is handled differently, but at this point, I decide that maybe, just maybe, the second error message is the real problem.
I deactivate XDebug, and the error messages go away, we're back to the previous situation. I re-activate, the error messages are back. Some duckduckgoing, and I find that the second header problem occurs when one attempts to setup output and there's already output - like an error screen. Looking through the XDebug options I find that there's an option I've been activating that sends the error messages straight to the screen. I deactivate this, and vóila!, I get my Joomla installation screen. MySQL fails silently, it recovers correctly and then proceeds to try other options until it finds the one that works.
Okay. So, I proceed to install Joomla with the debugger in the background, and ... it returns to the final screen, just as before. The debugger doesn't automatically stop at an error. Of course not. That would make things too easy.
So, hours of step-by-step debugging later, using all the tricks I know to debug through the forest that is Joomla, I find that it is throwing an exception in JArrayHelper::toObject, trying to create an object of type "stdclass". The header is:
public static function toObject(&$array, $class = 'stdClass', $recursive = true)
Anyone notice anything?
Take your time.
Yeah. So, I set a breakpoint at the function and ... no, that doesn't work at all: this thing is called everywhere!
Okay. I go and modify toObject(), telling it to do something if the class is all lowercase, and then setting a breakpoint on that "do something" line. This works: it stops right where it should.
Looking up the stack, the call only provides one parameter, so $class should be 'stdClass'. But it's 'stdclass'. That should not happen - it looks like a problem in PHP.
I correct it to 'stdClass' and let it proceed: I get the "success" screen from Joomla installation.
Did I mention that I'm stubborn? There's thousands of Joomla programmers, some of them must have hit this rock and given up - installed XAMP, worked around it, or gone and joined a monastery.
I set about figuring out what PHP call provokes the problem, and it turns out that the last call before 'stdClass' becomes 'stdclass' is a call to "$query->execute()" - in other words, to my non-standard database. So probably not PHP directly - probably the PHP database driver for Microsoft SQL Server. The one that everyone seems to complain about, just before telling you to use MySQL instead.
I look for the most recent version, and: apparently the drivers are offered for download by Microsoft, and it tells you that the most recent version is 4.3 and only supported for Windows 8 and later (I'm still on Windows 7). I decide to download and try it anyway. Except that the download only gives me 4.0 as an option. I double-check. Yep. The Microsoft page with the description telling me about 4.3 links to a page where 4.3 isn't available. A bit of work later, I deduce that I'm using the latest version of the 4.0 driver already.
A bit more searching later, and I find the one 4.3 'native' binary (shouldn't there be two? The PDO and the native version?) - I install the native binary anyway, but it doesn't work. Of course. PHP thinks there's no database access at all.
This is a challenge. I find the sources for the driver and download them, but they don't come with instructions. And don't compile properly if I just try the obvious.
Okay. The driver is a PHP extension, I'll lookup how to build PHP extensions in general - that's likely a clue.
The recommendation is, that one build PHP before one builds extensions. And for my version, PHP 7.0, if you are building under Windows instead of Linux, you will need Microsoft Visual C/C++ 2015 or later (Note: I already have two previous versions of Visual Studio cluttering my hard drive, I don't want a third). Why does it need Microsoft tools (as opposed to MingW), and why that version? Apparently because it was developed by people at Microsoft, who are familiar with SQL Server, and of course they use the latest and greatest.
Did I mention that I'm stubborn?
After some modifications to the include files and two source files, I get it through the compile phase of Visual C/C++ 2010, but the link fails with an unknown link option "-FitObjData".
One of the things I had to change to get it to compile, was a misuse of the ALLOCA_FLAG() macro - something that could overwrite things on the stack and cause random problems precisely like the one observed. I should probably notify the PHP developers about that.
So, none of the build files passes this "-FitObjData" anywhere. It must be an implicit flag of some sort. A search online shows first that this occurs when you use newer libraries with an older linker. Recommended solution is to use the same compiler for both. Hmmm. The libraries are provided, and it would take days or weeks to get all of their sources and recompile them all for this. A bit more searching, and somewhere, someone mentions "inlining" in connection with this linker problem, and that they gave up, too. Aha! Inlining is an optimization. If I set it up for debugging, then optimizations should be turned off, and maybe that will get rid of the problem.
It does. But now it's having trouble with doubly-defined functions and missing functions, related to vsprintf(). Oh, no. I've run into this kind of problem before, when I was working on embedded software. I ended up rolling my own vsprintf() equivalent, because all the different vsprintf()s are incompatible depending on your compiler options and dangerous to mix-and-match. It is time to give up on this path.
So, I go and install MySQL? You don't know me very well.
No, I'm going to compile PHP, even if I have to bite the bullet and install Visual Studio 2015. A couple hours later, I've signed up for some free developer stuff from Microsoft and have started the install for the free version of Visual Studio 2015. The installation takes a couple hours, and the installation of the Windows 10 SDK fails, but the rest appears to work.
So, this is the recommended toolset with everything setup exactly as recommended in the instructions. Everything should just work, right?
A clean build of the default configuration tells me: "fatal error C1007: unrecognized flag '-FitObjData' in 'p2'", just as before. That isn't supposed to happen - I have the new tools! Well, what worked once may work again - activate debug build!
The debug version tells me: lots of trouble with missing vsprintf() functions again! Verfluchte ... Wait a sec. It's "php7ts_debug.dll" is missing these functions - that's the thread safe version. Despite thread-safe being, well, safer, I know that the standard version is non-thread-safe. Time to rebuild!
The non-thread safe and debug version tells me: vsprintf() functions are still missing.
It's been over two days now. I've got things to get done. I don't have time for this crap anymore. I'm going to install Joomla using the debugger to set "stdclass to "stdClass" and move on. For now.