Archive for May 2008

Oracle XE 10gR2 on Kubuntu 64-bit

So I started poking around for instructions on installing Oracle XE 10gR2 on my Kubuntu Hardy 64-bit installation recently. I came across this article from Oracle, which seemed like exactly what I wanted. Unfortunately, it assumes that the intended host operating system is 32-bit, which causes issues if you try to install XE through apt as the Oracle article suggests. After following these instructions, I immediately received this error:

W: Failed to fetch http://oss.oracle.com/debian/dists/unstable/Release \ Unable to find expected entry main/binary-amd64/Packages in \ Meta-index file (malformed Release file?)

After that, any apt command issued (related or not) produced this error.

E: The package oracle-xe needs to be reinstalled, but I can't find an \ archive for it.

And finally, when I resorted to using this excellent guide instead, I ran into this problem because of the earlier failed installation.

dpkg: regarding oracle-xe-universal_10.2.0.1-1.1_i386.deb containing \ oracle-xe-universal: oracle-xe-universal conflicts with oracle-xe oracle-xe (version 10.2.0.1-1.0) is present and broken due to failed \ removal or installation.dpkg: error processing oracle-xe-universal_10.2.0.1-1.1_i386.deb \ (--install): conflicting packages - not installing oracle-xe-universalErrors were encountered while processing: oracle-xe-universal_10.2.0.1-1.1_i386.deb

Luckily, I was able to find a solution to purge the failed installation from the system.

dpkg --remove --force-remove-reinstreq oracle-xe-universal

One thing that the Oracle article was useful for was creating a swap file large enough for Oracle to use, as the issue described in the article with not having enough swap space did arise when I initially tried the installation. Beyond that, the non-Oracle guide mentioned earlier worked like a charm and I now have a working XE installation on my system.

DomQuery

Ever since I started working with the jQuery JavaScript library, I’ve loved it. It offers the power to do a lot with only a little code and makes features offered by the JavaScript DOM implementation much easier to access. My interest in web scraping prompted me to consider creating an equivalent of sorts for PHP.

This obviously doesn’t include some features specific to the client-side or any that require evaluating CSS, but it does include many for extracting data from a valid XML or HTML document. I’ve posted my initial work on the concept in an GitHub repository. The code there is commented with docblocks and includes unit tests with over 99% code coverage. Comments and suggestions are welcome.

php|tek and the Conference Experience

I read the conference synopsis post that Ben Ramsey posted to his blog about php|tek 2008 and couldn’t help but feel that I would made the exact same post myself had I been able to summarize my own thoughts as well. It really was a conference focused on community and I commend both the folks over at php|architect for their hard work in organizing it and the community for bringing their own unique talents and perspectives to enhance the experience.

ZendCon was an excellent first conference for me in 2007 and it had its own focus: the enterprise. However, the community was a large part of what brought me into the PHP community and continues to keep me there today, and that was what made php|tek so special. I enjoyed the good times had with friends new and old and look forward to being in attendance at php|tek in future years.

Apologies to all that I wasn’t able to say proper goodbyes to on account of having to rush to make my flight back home. I hope everyone made it home safely and that I will see many of you at ZendCon 2008 where, with any luck, you will find me among the speakers for the first time.

Now, back to your regularly scheduled programming…

Unit Tests and Code Coverage with PHPT

My initial experiences with unit testing and PHP were with PHPUnit. While it’s a great tool and I have to give kudos to Sebastian for contributing so much to its development, I’ve come to appreciate the simplicity of PHPT tests. Recently, I wrote some for a project and realized that I wasn’t aware of how to generate code coverage reports. Many thanks to the very helpful patrons in the #pear channel on EFNet for helping me to get this working.

First, the stock Kubuntu installation of PEAR is version 1.6.1. Their first recommendation was to upgrade to 1.7.2, which was easy enough:

sudo apt-get install php-pearpear update-channelspear upgrade-all

Next, PEAR bug 13958 can prevent code coverage reports from being generated properly. This bug has an available patch, which you can apply by doing the following:

cd /usr/local/share/PEARwget -c http://pear.php.net/bugs/...patch PEAR/RunTest.php phpt_coverage_bug.patch.txt

Now to install PHPUnit. I ran into an odd issue here where following the installation documentation resulted in PHPUnit 1.3.3 stable being installed, which is obviously a fairly old version. Even pear clear-cache didn’t seem to solve the issue. I checked to confirm that PEAR was using PHP 5. The only way I was able to get around this was to explicitly specify the latest version.

sudo pear install phpunit/phpunit-3.2.19

The current version of PHPUnit, 3.2.19, also has bugs 482, 483, and 484 related to generating PHPT code coverage reports. I had to apply the patch for bug 482 to fix issues I was having, but the others may also be necessary depending on the code being tested. These issues should be fixed when PHPUnit 3.2.20 is released. In the meantime, if you want to avoid manually applying patches and you’re feeling adventurous, you can use an git checkout.

As far as I can tell, PHPUnit itself does not contain a runner for its PHPT suite extension. However, there is a runner script to do this in PEAR CVS. Download the script to the directory containing your PHPT test files and execute it with a command similar to this.

phpunit --coverage-html ../Tests-Results \    Console_CommandLine_AllTests AllTests.php

In the case of this particular command, the Tests-Results directory parallel to the directory containing your PHPT files should now contain an index.html file with your test results. There you have it. Happy testing folks!

PHP 5.2 and SQL Server 2000 on Windows XP

Recently at work, I was tasked with finding a method to retrieve data from a third-party SQL Server 2000-based system into our own MySQL-based application. It’s worth noting that both system are behind their own firewalls and I was trying to bear security in mind as I did this.

First, I had to actually get into the system with the SQL Server database. For this, I used Citrix GoToAssist. The company behind the software makes their money off of hosting the servers it uses and selling access to them as a service. The client software uses HTTPS for security and to get around firewall configurations. While their software is nice, I’d be interested to see if anyone knows of any OSS equivalents of it.

Once I had access to the system, I needed something akin to phpMyAdmin or Oracle SQL Developer in order to see what resources were available on the SQL Server itself. For that, I found a local copy of EMS SQL Manager already on the system. This wasn’t the most full-fledged product I’d seen for this type of purpose, but it was free, included everything I needed, and did the job in a pinch.

After doing some reconnaisance on the database structure using the information that had been given to me by the third-party vendor, I downloaded the ZIP archive containing the standard build of PHP 5.2 for Windows. Side note: one of the things I like about PHP on Windows is that, for CLI purposes, it only takes decompressing the ZIP archive, tweaking the configuration file to get the settings and extensions you want, and executing the binary to get it up and running.

With my SQL Server experience being dated by about six years, I started throwing PHP code at the system to see what would stick. I noticed that the server was already set up to accept trusted connections, and being that I was running the script on the local system, this made it likely that authentication wouldn’t present any issues, or so I thought.

I created my PDO instance like so:

$db = new PDO('mssql:localhost;dbname=...');

And then attempted to call a particular stored procedure that I’d been told would have some of the data I was looking to extract. I was surprised to get this in response when calling PDO::errorInfo().

Array(    [0] => HY000    [1] => 10007    [2] => Could not find stored procedure ... [10007] (severity 5) [EXEC ...]    [3] => -1    [4] => 5)

Now I had just been in EMS SQL Manager and seen the stored procedure myself, so I knew it was there. I tried using the sa account, but that didn’t seem to work either. After some digging, I found that I had to create an account for the current Windows user on the current network domain in order to make PHP capable of seeing the stored procedure when using a trusted connection. Once I’d created the account and given it access to execute the specific stored procedure I was trying to call, I tried again and PDO::errorInfo then gave me this.

Array(    [0] => HY000    [1] => 10007    [2] => Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier. [10007] (severity 5) [EXEC ...]    [3] => -1    [4] => 5)

Apparently there are issues with the MS SQL stand-alone PHP extension and SQL Servers using unicode collation. Some more digging turned up that the only way to get around this was to use ODBC. Once I did that, I found that I was no longer getting an error when trying to call the stored procedure.

$db = new PDO('odbc:Driver={SQL Server};Server=localhost;Database=...;Trusted_Connection=yes;');

Though I knew of stored procedures conceptually, my previous experience with SQL Server had never included using them. As such, I wasn’t familiar with the syntax and came across something rather strange while trying to troubleshoot it: if the arguments to a stored procedure are surrounded by parentheses in the  query calling that stored procedure, the code silently fails and returns no results.

// $stmt = $db->prepare('EXEC ...(?, ?)'); // Fails silently$stmt = $db->prepare('EXEC ... ?, ?'); // Works as expected

Last on the list of “interesting things I experienced” while on this little trek wasn’t related to the database, but to what was happening when I attempted to push data from the SQL Server machine to our LAMP machine. I was using the PHP serialize() function to encode the data into a string, then using the streams HTTPS wrapper to send it via a POST request to a PHP file on the LAMP machine. This meant I wouldn’t have to poke a hole in the firewall on either side since both were already open to web traffic. When attempting to run the code for this, I got an error on the client side:

PHP Warning:  file_get_contents(): SSL: An existing connection was forcibly closed by the remote host.PHP Warning:  file_get_contents(https://...): failed to open stream: HTTP request failed!

The cause for this wasn’t immediately apparent. Upon checking Apache error logs, I came across this:

PHP Fatal error:  Allowed memory size of 16777216 bytes exhausted (tried to allocate 3381676 bytes)

The actual issue had to do with how much data I was trying to send; it was exceeding the value specified in the memory_limit configuration setting, which as it turned out was set to the recommended value for a significantly older version of PHP. After updating it to a more current recommended value and bouncing Apache, all was well.

Hope the details of my experiences prove helpful to someone else. Thanks to those who provided assistance along the way.