通过检查输入的字符串是否是合法的 IP 地址来理解KISS原则

处理字符串是否是ip的三个函数:

<?php
function isValidIpAddressV1(String $ipAddress){
	if(empty($ipAddress)){
		return false;
	}
	$regex = "/^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$/";
	$ret = preg_match($regex, $ipAddress,$matches);
	return is_bool($ret)?$ret:($ret>0?true:false);
}
function isValidIpAddressV2(String $ipAddress) {
	if(empty($ipAddress)){
		return false;
	}
	$ipUnits = explode('.',$ipAddress); 
	if (count($ipUnits) != 4) { 
		return false; 
	} 
	for ($i = 0; $i < 4; ++$i) {
		$ipUnitIntValue = 0; 
		try { 
			$ipUnitIntValue = intval($ipUnits[$i]); 
		} catch (\Exception $e){ 
			return false; 
		} 
		if ($ipUnitIntValue < 0 || $ipUnitIntValue > 255) { 
			return false; 
		} 
		if ($i == 0 && $ipUnitIntValue == 0) 
		{ 
			return false; 
		} 
	} 
	return true;
}
function isValidIpAddressV3(String $ipAddress){
	$ipChars = str_split($ipAddress);
	$length = count($ipChars);
	$ipUnitIntValue = -1;
	$isFirstUnit = true;
	$unitsCount = 0;
	for ($i=0; $i < $length; $i++) {
		$c = $ipChars[$i];
		if ($c == '.') {
			if ($ipUnitIntValue < 0 || $ipUnitIntValue > 255) return false;
			if ($isFirstUnit && $ipUnitIntValue === 0) return false;
			if ($isFirstUnit) $isFirstUnit = false;
			$ipUnitIntValue = -1; 
			$unitsCount++; 
			continue;
		} 
		if ($c < '0' || $c > '9') {
			return false;    
		}
		if ($ipUnitIntValue == -1) $ipUnitIntValue = 0;
		$ipUnitIntValue = $ipUnitIntValue * 10 + ($c - '0');
	}
	if ($ipUnitIntValue < 0 || $ipUnitIntValue > 255) return false;
	if ($unitsCount != 3) return false;
	return true;
}

第一种实现方式利用的是正则表达式,写出完全没有 bug 的正则表达本身就比较有挑战。所以,从 KISS 原则的设计初衷上来讲,这种实现方式并不符合 KISS 原则。第二种实现方式使用了现成的字符串函数,来处理 IP 地址。第三种实现方式通过逐一处理 IP 地址中的字符,来判断是否合法。从代码行数上来说,这两种方式差不多。但是,第三种要比第二种更加有难度,更容易写出 bug。从可读性上来说,第二种实现方式的代码逻辑更清晰、更好理解。所以,在这两种实现方式中,第二种实现方式更加“简单”,更加符合 KISS 原则。