我需要使用PHP从textarea
元素的输出解析其IP和端口的代理数组。我想知道什么是解决此问题最有效的方法,因为通过textarea
上传的列表可能位于proxy:port
或proxy port
(带空格),在这两种情况下每个代理都会被换行符分开。
例如,如果在两个不同的场合上传了以下列表:
34.345.32.1 9032
4.3.21.234 2023
45.31.45.324 1025
和
34.345.32.1:9032
4.3.21.234:2023
45.31.45.324:1025
然后在两种情况下得到的数组都是
$proxies = array (
array('34.345.32.1',9032),
array('4.3.21.234',2023),
array('45.31.45.324',1025)
);
我已经尝试了以下代码,但是在var_dump()
array
上没有打印任何内容。
$array = explode("\n", $_POST['proxies']);
$array2 = explode(" " $array);
答案 0 :(得分:1)
您可以使用简单的foreach
循环遍历数组,strpos
来检测分隔符
$proxies = explode("\n", $_POST['proxies']);
foreach($proxies as $key => $value){
if(strpos($value, ' ')){
$proxies[$key] = explode(' ', $value);
} else {
$proxies[$key] = explode(':', $value);
}
}
print_r($proxies);
这是一个基本示例,您需要对此进行扩展,以确保您的数据在此之后进行标准化。
答案 1 :(得分:0)
为了验证代理,我在我的生产站点上使用此功能。
/**
* Validate IP and PORT | This will give you array of proxy into IP and PORT
* Valid IP Address (0.0.0.0 - 255.255.255.255): Valid port (1-65535)
* IP = $matches[1]
* PORT = $matches[2]
* @return boolean|array
*/
public function proxyIpPort($proxy)
{
try {
//Valid IP Address (0.0.0.0 - 255.255.255.255): Valid port (1-65535)
if (preg_match('~\b([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}):([0-9]{1,10}\b)~', $proxy, $matches)) {
//if port range doesnot match return error
if (!preg_match('/^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/m', $matches[2], $arraystr)) {
return array(
'success' => false,
'error' => 'Invalid Port Range',
'ip' => $matches[1],
'port' => $matches[2],
);
}
if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
return array(
'success' => false,
'error' => 'Invalid IP Address',
'ip' => $matches[1],
'port' => $matches[2],
);
}
if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE) === false) {
return array(
'success' => false,
'error' => 'Private IP provided',
'ip' => $matches[1],
'port' => $matches[2],
);
}
if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) === false) {
return array(
'success' => false,
'error' => 'Reserve IP provided',
'ip' => $matches[1],
'port' => $matches[2],
);
}
//all verifications done
return array(
'success' => true,
'ip' => $matches[1],
'port' => $matches[2],
);
}
//all validations failed return invalid ip
return array(
'success' => false,
'error' => 'Invalid IP:PORT'
);
} catch (\Throwable $th) {
return array(
'success' => false,
'error' => $th,
);
}
}
此功能将为您提供对公共代理的精确验证。
关于没有使用 :
的代理
$txt = "34.345.32.1 9032
4.3.21.234 2023
45.31.45.324 1025";
$proxies = str_replace(" ", ":", $txt); //replace the empty space between ip and port with `:`
$proxies = str_replace("\n", ",", $proxies); // replace the new line `\n` with `,` to convert text into array
$proxies_array = explode(",", $proxies);
print_r($proxies_array);
使用给定的代理数组并使用 foreach 一一测试每个代理?
答案 2 :(得分:0)
此任务接收用户提供的输入(textarea),然后尝试解析具有轻微可变性的字符串。这是正则表达式函数的一个很好的候选。
以简洁的模式提供确切所需输出的一种方法是:(Demo)
preg_match_all('~(\d{1,3}(?:\.\d{1,3}){3})[: ]\K\d{4}~', $string, $matches, PREG_SET_ORDER);
var_export(array_map('array_reverse', $matches));
上面是捕获代理子串,然后匹配不同的分隔符,然后忘记那些匹配的字符,然后匹配端口子串作为“全串匹配”。这样做时,$matches
数组具有相反顺序的子数组元素——如果顺序很重要,您可以在每个子数组上调用 array_reverse()
。
否则,您可以不那么花哨,只捕获代理和端口子字符串并容忍不需要的全字符串匹配。 (Demo)
preg_match_all('~(\d{1,3}(?:\.\d{1,3}){3})[: ](\d{4})~', $string, $matches, PREG_SET_ORDER);
var_export($matches); // just access the [1] and [2] subarray values
我发现 double-explode() 技术对这项任务的吸引力不大,因为正如我之前所说,这是用户提供的数据,不能信任。
如果我要使用非正则表达式解决方案(不提供验证),我会使用 D.R.Y.:
$proxies = [];
foreach (explode("\n", $_POST['proxies']) as $line) {
$proxies[] = explode(
strpos($value, ':') ? ':' : ' ',
$value
);
}