Scriptlets - Reusable Code

What I call Scriptlets are small PHP and Perl scripts/functions that I find useful in many of my scripts. They usually accomplish small quick tasks that I don't want to duplicate in every script. I simply embed including statements to pull them in. Feel free to use them as you see fit. As always, no warranties as to the suitability. That's up to you to figure out. Enjoy!

network functions

This file contains multiple functions. I normally avoid having multiple functions in a scriptlet. However they were so closely intertwined that it just made sense. These functions basically accomplish an IP calculator for PHP. They include functions to turn an IP into a binary string, and vice-versa along with functions for calculating the network and broadcast address of a particular network. There's also a function to check whether a particular IP exists in a given network.

I'll admit readily that I'd much rather have used binary arithmetic to work these functions. After all that would make sense. However PHP unfortunately does not support unsigned integers (at this time and I could find no reference to them extending their variable capabilities.) As a result, these functions are a slight bit slower than I would like. They have to do a string-based binary comparison to ensure that all IPs in the top end of the 32bits are covered. Some additional performance improvements could be made in two regards right now, but they aren't of priority.

  • Add a function to detect the submitted parameter so that in_network could avoid doing the binary calculation on the netmasks three times (once in subcalls to broadcast() and network() and of course once directly to get the netmasks's binary equivalent.
  • Change the whole thing into a class that caches its previous calculations for subsequent calls.
Of course, when I do code these features I'll update this page.

Example:

include 'network.inc';

ip2bin('192.168.90.5'); // returns 11000000101010000101101000000101
bin2ip('11000000101010000101101000000101'); // returns 192.168.90.5
network('192.168.90.5', '255.255.248.0'); // returns 192.168.88.0
broadcast('192.168.90.5', '255.255.248.0'); // returns 192.168.95.255
in_network('192.168.50.4', '192.168.90.5', '255.255.248.0'); // returns -1 (not present)
in_network('192.168.94.4', '192.168.90.5', '255.255.248.0'); // returns 1 (present)
	      

<?php

// Copyright (C) 2005  James Bly
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



    
function ip2bin($ip)
    {
        
$ret '';
        if(!
preg_match("/^\d+\.\d+\.\d+\.\d+$/"$ip)) return -1;
        foreach(
explode("."$ip) as $a)
        {
            if(!
is_numeric($a)) return -1;
            
$ret .= str_pad(decbin($a), 80STR_PAD_LEFT);
        }
        return 
$ret;
    }

    function 
bin2ip($bits)
    {
        if(!
preg_match("/^([0-9]{8})([0-9]{8})([0-9]{8})([0-9]{8})$/"$bits$matches)) return -1;
        return 
sprintf("%s.%s.%s.%s"
                           
bindec($matches[1]), bindec($matches[2]), bindec($matches[3]), bindec($matches[4]));
    }

    function 
bitmask($mask)
    {
        
$bits ip2bin($mask);
        if(
preg_match("/^(1+)(0+)$/"$bits$matches))
            return 
strlen($matches[1]);
        else
            return -
1;
    }

    function 
netmask($bits)
    {
        
$ret '';
        if(!
preg_match("/^\d+$/"$bits)) return -1;
        for(
$i 0$i 32$i++)
            
$ret .= ($bits $i)?1:0;
        return 
$ret;
    }

    function 
network($ip$mask)
    {
        
$ret '';
        
$bitip ip2bin($ip);
        
$bitmask ip2bin($mask);
        for(
$i 0$i 32$i++)
        {
            if(
$bitmask{$i} == '1')
                
$ret .= $bitip{$i};
            else
                
$ret .= '0';
        }
        return 
bin2ip($ret);
    }

    function 
broadcast($ip$mask)
    {
        
$ret '';
        
$bitip ip2bin($ip);
        
$bitmask ip2bin($mask);
        for(
$i 0$i 32$i++)
        {
            if(
$bitmask{$i} == '1')
                
$ret .= $bitip{$i};
            else
                
$ret .= '1';
        }
        return 
bin2ip($ret);
    }

    function 
in_network($check$network$netmask)
    {
        
$c '';
        
$b '';
        
$cip ip2bin($check);
        
$nip ip2bin(network($network$netmask));
        
$bip ip2bin(broadcast($network$netmask));
        
$bitmask ip2bin($netmask);
        for(
$i 0$i 32$i++)
        {
            if(
$bitmask{$i})
                if(
$cip{$i} != $nip{$i}) return -1;
            else
            {
                
$c .= $cip{$i};
                
$b .= $bip{$i};
            }
        }
        if(
bindec($c) > bindec($b)) return -1;
        else return 
1;
    }
    
?>

debug()

This useful little function checks a global parameter, $debug and if set displays whatever you ask it to display.

Example:
<?
   $debug = 1;
   debug("function_name", "Your debug message was: %s", $message); ?>


<?php

// Copyright (C) 2005  James Bly
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


function debug()
{
        global 
$debug;
        if(!
$debug) return;
        
$a func_get_args();
        
$fn sprintf("%s():"array_shift($a));
        
$f array_shift($a);
        print 
vsprintf(sprintf("%-20s%s\n"$fn$f), $a);
}

?>

is_key()

This PHP function checks an associative array for a key of a particular name. This may seem trivial but in truth I do this so often that it made sense to just create a quick function to pull it off.

Example:
<?
   $a = array("one" => 1, "two" => 2);
   if(is_key("one", $a)) { ... } // == true
?>


<?php

// Copyright (C) 2005  James Bly
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


function is_key($needle ''$haystack = array())
{
        if(
strlen($needle) > && count($haystack) > 0)
                if(
in_array($needlearray_keys($haystack))) return true;
                else return 
false;
        else
                return 
false;
}

?>

request()

This PHP function is ever-so-helpful. I use it for quickly, easily, and safely reading information from user input on web pages in either GET or POST submissions. It allows you to limit how much information they can feed back to you and also contains a regex filter capability so you can say "they can only submit information of such-and-such format."

Example:
Get no more than 40 characters from the user supplied HTML field:
$userfield = request("formfieldname", 40, "/^\w+$/");
 
Get any number of bytes (any type of data) from the user supplied HTML field:
$userfield = request("formfieldname");

<?php


// Copyright (C) 2005  James Bly
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


function request($item$len 0$regex '')
{
        
$data '';

        if(isset(
$_GET[$item])) $data =  ($len)?substr($_GET[$item], 0$len):$_GET[$item];
        if(isset(
$_POST[$item])) $data =  ($len)?substr($_POST[$item], 0$len):$_POST[$item];

        if(
strlen($regex) && !preg_match($regex$data)) return FALSE;
        if(
$data) return $data;
        return 
FALSE;

}

?>

CDF Formatting

I do find myself regularly needing to build comma-delimited files from my database applications. It suits many purposes like mail-merging and data analysis. These functions are just quick little helpers for the basic needs.

Example:
Populate a multi-dimensional array with the first arrow containing data rows and the rows containing the unique values. This is the type of data that would come back from a call like pg_fetch_all(). Then feed the data out to outputcdf() as such:
print outputcdf($array);
 
It is pretty straight-forward and really meant for most of he basic functions.

<?php

function outputcdf($data)
{
    
$out '';
    
header("Content-Type: text/plain; charset=iso-8859-1");
    for(
$a=0$a<count($data); $a++)
    {
        
$i 0;
        for(
$b=0$b<count($data[$a]); $b++)
        {
            
$out .= sprintf("%s%s", ($i)?",":""formatcdf($data[$a][$b]));
            
$i++;
        }
        
$out .= "\n";
    }
    return 
$out;
}

function 
formatcdf($string)
{
        
$string str_replace("\"""\"\""$string);
        if(
preg_match("/\r\n/"$string) || preg_match("/,/"$string))
        {
                
$string sprintf("\"%s\""$string);
                
$string preg_replace("/\r\n/""\n"$string);
        }

        return 
$string;
}

?>