PHPUnit and Facebook’s php-webdriver

This seems straight forward at first, but there is either an autoloading issue in my project, or the author of the blog assumed everyone would know about PHP “namespaces” and how to “use” (aka “import” in Java) the external classes.

Namespace tutorial: http://daylerees.com/php-namespaces-explained/

Once namespace imports were working, there was another error:

Call to undefined function Facebook\WebDriver\Remote\curl_init()

This was fixed by installing curl into PHP: sudo apt-get install php5-curl. Check it installed properly: php -info | grep -i curl

/etc/php5/cli/conf.d/20-curl.ini,
curl
cURL support => enabled
cURL Information => 7.38.0

Enums in PHP

Who knew enums could be so difficult in PHP 5.3?!? There are probably better options with higher versions of PHP, but I’m not to that point yet.

I tried to use the PHP provided SplEnum, but I could not get it to work with all of the default install of PHP. Maybe I had something wrong, or needed to enabled something in the php.ini file, but either way, enums should not be this hard.

[19-Jul-2015 15:15:33] PHP Fatal error: Class ‘SplEnum’ not found in C:\dev\php\workspace\project\StatusEnum.php on line 2

There are a few good options of enum classes that others have created out on the web, so instead of re-inventing the wheel, I borrowed one of the simpler enum implementations.

abstract class MyEnum
{
    final public function __construct($value)
    {
        $c = new ReflectionClass($this);
        if(!in_array($value, $c->getConstants())) {
            throw IllegalArgumentException();
        }
        $this->value = $value;
    }

    final public function __toString()
    {
        return $this->value;
    }
}

class Foo extends MyEnum
{
    const FOO = "foo";
    const BAR = "bar";
}

$a = new Foo(Foo::FOO);
$b = new Foo(Foo::BAR);
$c = new Foo(Foo::BAR);

if($a == Foo::FOO) {
    echo "My value is Foo::FOO\n";
} else {
    echo "I dont match!\n";
}

if($a == $b) {
    echo "a value equals b value!\n";
}
if($b == $c) {
    echo "b value equals c value!\n";
}

I think I may extend this to be a little more java-like (hasKey(), etc.), but for now, the most basic enum class above will work great for my needs.

Enable SSH2 in PHP on Windows

Anything that you do with PHP on Windows that is outside of the standard install is always an adventure. Especially installing extensions. This Law of PHP on Windows was again confirmed when I tried to enable SSH2 in PHP 5.3.3 on my Windows machine.

To save you time, here are the steps:

  • Determine which version of PHP you have: x64 or x32, as well as Thread Safe vs. Non-Thread Safe
  • C:\tmp>php -i > info.txt
  • then open info.txt and take note of the “Architecture” as well as the “Thread Safety” (enabled means you need the TS version)
  • Download the SSH2 related files for your version and whether your local install is TS or NTS
  • http://pecl.php.net/package/ssh2/0.12/windows
  • Unzip to your directory of choice
  • Copy libssh2.dll to C:\Windows\System32
  • if on a x64 system, you’ll also need to copy it to C:\Windows\SysWOW64
  • Copy php_ssh2.dll and php_ssh2.pdb to your PHP install directory’s /ext directory (e.g. C:\dev\php\5.3.3\ext)
  • Restart Apache

To test if SSH2 is installed, re-run the “php -i > info.txt” command and ensure that ssh2 related items are listed within the “PHP Streams” section.

Also, you can verify it within your code by running something like:

        if (!function_exists('ssh2_connect')) { 
            echo "ssh2 is not configured properly"
        }

PHP duplicate function name gives no errors

I had a very simple service class to perform some tasks:

class SomeService {
public function doSomething(){}
}

While adding some other functions, I was copy-and-pasting the doSomething(){} structure, and then renaming the new functions. I apparently forgot to rename one of the functions, and left it as doSomething(){}, which meant I had two functions with the same name.

This Service is being tested using SimpleTest framework for Unit Tests, and when running the tests via the browser, I saw nothing but a blank page. I searched through the PHP logs, nothing. Apache logs? Nothing.

After doing some debugging, I eventually narrowed it down to the SomeService class, which I promptly commented out everything, and I at least was able to see failures in my Unit Tests. After adding the functions back one by one, it become obvious of my goof, and once I removed the duplicate name all of my test passed again.

That was a few hours down the drain that could have been avoided with an extremely simple error message.

PHP System Variables

System variables in Java are pretty straight forward: add them with the -D parameter when you start the JVM (/bin/java -Dcom.example.prod=true). However in an interpreted language like PHP, it’s a little different: you update the php.ini file with your environment-specific key-value pairs.

So in PHP if you want to set com.example.debug=true, then you’d simply place it in the php.ini file, and restart the Apache that serves the PHP files.

I do not fully understand why yet, but to get the standard php.ini variables (e.g. post_max_size) you use the function ini_get(“post_max_size”), but if you want to retrieve a custom variable, you should use get_cfg_var(“my.custom.var”).

The reason you would want to use “System Variables” instead of a global value is that System Vars are pertinent at a higher level than the code. You would want to let the code know which environment it is running in at startup, outside of the code.

PHP Test Frameworks

I’ve got a PHP project that desperately needs some basic Unit Testing. I am a huge fan of building automated tests as I develop code, and (mostly) before I even write the implementations. “How do we test this?” is one of the 2 most important questions in software development. (The other being “How do we define ‘done'”)

JUnit has been amazing for my Java development, so having a PHP test framework that is similar, or based off of its ideas is a big plus if I can get it.

There are a lot of good options out there that look good, but I have not had a chance to review all of them yet. The main ones considered at this point are:

  1. SimpleTest
    • PROS: easy to get up and running, just download the tar.gz file, unzip, and go. It is also very JUnit like in the Java world (TestSuites, run functions that start with the word “test”, etc.).
    • CONS: latest version was released in 2012
  2. Testify.php
    • PROS: easy to get up and running
    • CONS: not updated since August of 2014, and does not seem to be as JUnit-like as I’d prefer, but maybe that is due to the lack of documentation, and my lack of time to research it
  3. PHPUnit – The PHP Testing Framework
    • PROS: most up-to-date and seems very enterprise ready (latest version was released about a week ago as of this writing)
    • CONS: install is not as easy as the others. It requires a PHAR file (not a real big issue), but it is not as easy as the others to get going in a Windows environment (again, not a huge problem, but it is more involved than the others)

In the end I decided to go with SimpleTest because its first few tutorials were very easy to get up and running, and it is very JUnit-like. The code base is also only running PHP 5.3.3, so it is on an older version of PHP, and the fact that SimpleTest (and Testify.php) were a little dated is not as big of an issue, and probably easier (as to not mix features of newer PHP versions) at this point in time.

At some point I should at least go through the Testify.php tutorials to see if it is a viable option.