Category Archives: PHP

Detecting if an IP address is in a certain range in PHP

First published on the Cu.be blog : link

If you ever need to detect whether an IP address (let’s say 192.168.0.2) is inside a certain IP range/subnet (let’s say 192.168.0.0/24), you can use the following code in PHP :

/**
 * Check IPv4 address is within a range
 *
 * @param string $ip A valid IPv4 address (xxx.xxx.xxx.xxx)
 * @param string $subnet A valid IPv4 subnet (xxx.xxx.xxx.xxx)
 * @param string $mask A valid IPv4 subnet mask (a number from 0-32)
 * @return boolean True if the address is within the range, false if it isn't
 */
function ip4_in_network($ip, $subnet, $mask)
{
    if ($mask <= 0) {
        return false;
    }
    $ip_bin_string = sprintf("%032b", ip2long($ip));
    $net_bin_string = sprintf("%032b", ip2long($subnet));
    return (substr_compare($ip_bin_string, $net_bin_string, 0, $mask) === 0);
}


For IPv6, the code is slightly more complicated:

/**
 * Check IPv6 address is within a range
 *
 * @param string $ip A valid IPv6 address
 * @param string $subnet A valid IPv6 subnet
 * @param string $mask A valid IPv6 subnet mask (a number from 0-128)
 * @return boolean True if the address is within the range, false if it isn't
 */
function ip6_in_network($ip, $subnet, $mask)
{
    $subnet = inet_pton($subnet);
    $ip = inet_pton($ip);

    // thanks to MW on http://stackoverflow.com/questions/7951061/matching-ipv6-address-to-a-cidr-subnet
    $binMask = str_repeat("f", $mask / 4);
    switch ($mask % 4) {
        case 0:
            break;
        case 1:
            $binMask .= "8";
            break;
        case 2:
            $binMask .= "c";
            break;
        case 3:
            $binMask .= "e";
            break;
    }
    $binMask = str_pad($binMask, 32, '0');
    $binMask = pack("H*", $binMask);

    return ($ip & $binMask) == $subnet;
}

A happy 20 years !

In honor of the 20th anniversary of PHP, I thought I’d write a short story about my years in PHP.

I discovered PHP in 1997 after I started experimenting with Linux and we started a university team of the Distributed.net RC5 challenge. We had a so-called personal key proxy running and wanted to generate some personal statistics. I decided to learn this relatively new language called PHP, which was at version 2.0FI at the time, which served to create some basic stats. Afterwards we used the Perl-based PPStats, but I soon found it too slow and too messy to deal with, so I rewrote it in PHP.

GNet
My first major PHP adventure was a personal project called GNet, a search engine submission system (back in the days when most search engines didn’t crawl the web and if they did, they did so slowly and inefficiently). The system I built was both web-based as well as Windows-based. The web-based version was built in PHP 3.0, the Windows version was not a standalone system, but rather plugged into the web-based version to fetch the latest engine list, parameter lists, etc using some custom API (well there were no ‘standard’ APIs at the time anyway). This was an actual client-server based application with PHP running on the server side, back in 1999 πŸ™‚

phpAds(New) / OpenX
The end of the 90s was also the boom of the online advertising industry. And having a system like GNet meant I could actually show some ads and try to make a little money. There was a system called phpAds, written by Tobias Ratschiller. After version 1.4 arrived, Tobias seemed to have vanished and although I had created a number of bug fixes, nobody was able to put them into the official phpAds project, which was being run from Tobias’ website.
So I merged all the existing patches with mine, added some functionality, and released phpAdsNew 1.4.9, the new part indicating that this was the new release. The new would remain part of its name until 2007, when the project was renamed to OpenAds (it has since been renamed to OpenX and recently to Revive Adserver). Over the course of 2 years, I rewrote the core of the system and added features, until in 2002 I gladly handed it over to someone else to maintain.
Although I never made much money with the ads, the project was fun, I got to see the fruits of my labour being used by thousands of companies and I learned a lot running it.

Consultancy
The next few years I spent building mostly control panels and online ordering systems (for our own domain name, hosting and colocation business) and small websites and webapps.
In 2006 I started working for a number of Belgian companies as a freelance PHP developer. I worked for Internet Architects, Telenet, NMBS (Belgian railways) and a few more, before finally starting a dedicated PHP development company called Cu.be Solutions.

Open Source
Although phpAdsNew/OpenX was an open source project from the start, I had been out of touch with actual open source work for a while when I started working on PHPCompatibility a few years ago. I’m happy to see a lot of people using it.
But my contribution is so small compared to the massive amounts of code so many have contributed to the PHP core, frameworks, CMS systems, testing tools, and so much more.

The community
Open Source makes PHP great, absolutely. But it’s the PHP community that makes it all worth it ten-fold. In the past 8 years I’ve met the most amazing people from all around the world, each with their own distinct tastes, opinions, abilities, mindset, and so on… with one single thing binding them together : they’re all using this tool Rasmus Lerdorf built 20 years ago, this tool that has taken the web by storm and has been the undisputed number 1 web language for a long time, a language I will gladly use for another 20 πŸ˜‰

Happy happy birthday PHP ! Onwards to the next 20 !

PHPConsistent : a new tool to verify your calls and documentation quality

Back in 2009 and 2010 I wrote about a PHPUnit patch I wrote to automatically verify parameter types in function calls. The feature never made it into PHPUnit and honestly it didn’t really fit into the feature set either. Although I still plan on releasing it as a PHPUnit extension that you can easily load, I’ve since been using it outside of PHPUnit, not just on tests, but on any PHP code.

Introducing PHPConsistent

PHPConsistent will verify your code using both dynamic and static analysis.

The goal is to improve code quality of your code and the libraries you use by :

  • Verifying your code is making calls using the right parameters and parameter types
  • Verifying if the in-line documentation (docblock) of the called functions/methods is accurate

It will compare :

  • Parameter types specified in the docblock <-> types of parameters passed upon calling the function/method
  • Number of parameters specified in the docblock <-> number of parameters actually present in the function/method definition
  • Names of parameters specified in the docblock <-> names of parameters actually present in the function/method definition

Sample output

Invalid type calling SomeClass->GiveMeAnArray : parameter 3 ($somearray) should be of type array but got boolean instead : library/App.php (line 5)
Parameter names in function definition and docblock don't match when calling JustAnotherFunction : parameter 2 ($inputFilename) should be called $inputFile according to docblock : application/Bootstrap.php (line 214)
Parameter count in function definition and docblock don't match when calling OneMoreFunction : function has 6 but should be 5 according to docblock : application/Bootstrap.php (line 215)

Performance

Keep in mind that PHPConsistent relies on Xdebug’s trace functionality, making it quite slow. It also needs to analyze the output of that trace, making it even slower. So it’s definitely not something you want to run on a production environment !

Want to know more ?

Check out the PHPConsistent Github page

PHPCompatibility update

Update (Nov 3, 2013) : changed the parameters to reflect the new changes in PHP_CodeSniffer

Just a quick post about the updates made to PHPCompatibility.

I did a talk on PHP 5.4/5.5 at Zendcon, not just about what’s new and why you should upgrade, but also about the way PHPCompatibility can ease the pain. I received very good feedback, as well as very interesting questions. As a result, I added a feature I’ve wanted to add for a long time : the option to specify which PHP version to check for.

Here’s the caveat : it requires a change to PHP_CodeSniffer. I’m hoping that change will be accepted soon. From that point onwards, if you have the latest PHP_CodeSniffer (you might want to get it from Github).

So then you will be able to do :

phpcs --standard=PHPCompatibility --runtime-set testVersion 5.4 <path-of-your-php-files>

You can also test for backwards compatibility of your code by specifying versions like 5.2, which causes it to check whether you’re using functions or keywords not known to this older version. Quite nice if you’re coding on PHP 5.5, but your system engineer tells you half way through the project the project will have to be deployed on 5.2.

Important note : if you want to test backwards compatibility, it’s best to run on the latest PHP version available (5.5 right now), for the simple reason that if you have, for example, the keyword ‘yield’ in your code, PHP_CodeSniffer can only recognize it when you’re running PHP 5.5. It can only tell you it’s not available in previous versions if it actually knows what it is.

Expect more compatibility tools soon, as I have some more ideas, such as how to automatically figure out whether and where you’re still relying on register_globals and magic quotes πŸ˜‰

Conferences, development, ideas, …

I just returned from PHPCon Poland, a very nice conference taking place in the middle of beautiful scenery. Although there were only 5 talks in English (3 of which were given by Belgians – Thijs Feryn, Michelangelo Van Dam and myself), the conference was definitely interesting and fun.
I gave a relatively new talk, that I first presented as a 20-min ‘lightning talk’ at ZendCon Uncon 2011. It’s evolved into a 45-min talk (ok, it was only 38-min so I can add some content next time) titled ‘Remove PHP calls and scale your site like crazy’ in which I explain more about the Nginx extension we’re building to improve the performance and scalability of sites with user-specific content. I received some pretty good feedback on Joind.in and lots of people approached me afterwards, wanting to learn even more about it.

I also submitted 6 talks for Confoo, which is supposed to be one of the best web development conferences out there. Not sure if I’ll make it, but if you want to help out, feel free to vote for me. Registration is required to vote, but takes only a minute.

Lots of ideas buzzing in my head, but sadly not enough time to work on them. The Nginx thing is cool, but it’s what I call ‘phase 1’… which means there’s a ‘phase 2’ (in fact, there’s even a ‘phase 3’). But since that requires even more time, it’ll probably be for when phase 1 has been completed.

In the meantime, we’re on the hunt for people looking for a new challenge. If you’re looking to be seriously challenged, check out our jobs page and feel free to tweet/mail/call me πŸ˜‰