Here is a short, simple and fast solution.
It works for IPv4 and IPv6
No substr and base conversion
function is_ip_in_cidr($ip, $cidr)
{
list($net, $mask) = explode('/', $cidr);
$ip = inet_pton($ip);
$net = inet_pton($net);
$prefix = $mask >> 3;
$shift = 8 - ($mask & 7);
if (8 == $shift) {
return !strncmp($ip, $net, $prefix);
} else {
$ch_mask = -1 << $shift;
return !strncmp($ip, $net, $prefix) && ((ord($ip[$prefix]) & $ch_mask) == (ord($net[$prefix]) & $ch_mask));
}
}