php URL 验证
如果表单里请求用户输入其主站地址,那么就需要对这个URL进行检验来判断它是否像个有效地址。对URL的检验有两个层次。一是使用parse_url()函数尝试解析URL,对其中的组成部分进行基本的完整性检查。
二是尝试连接相应的Web服务器,查看这个URL是否真正存在。但是一定要注意这种方法存在缺陷,因为服务器可能在当时恰好关机了。程序清单11.8.1展示了URL的标准化与检验例程。
程序清单11.8.1 URL标准化和检验函数库
<?php
// A function to do a sanity check on a URL ... Since we are assuming
// that this is coming from user input, we will require it be a full
// URL, and not a relative one
function validate_url($url) {
// Use parse_url to break the URL into parts for us:
$up = parse_url($url);
// If scheme, host, or path don't exist, or complete failure: INVALID
if (!$up || !$up['scheme'] || !$up['host'] || !$up['path']) {
return false;
}
// If the scheme is anything besides http(S) or ftp: Fail
if (!( ($up['scheme'] == 'http') ||
($up['scheme'] == 'https') ||
($up['scheme'] == 'ftp')) ) {
return false;
}
// We made it here, it looks good to us.
return true;
}
// Function that will actually take a url, and attempt to contact the server
// if it can't access the remote file, it returns false, else true.
function check_url($url) {
// Request only the headers, no reason to download the whole file
// Note that this call will only handle https connections if PHP was
// compiled with SSL support.
$output = *get_headers($url);
// Return appropriately
return $output ? true : false;
}
// Test a few URLs
$urls = array('http://eliw.com/', 'http://php.net/get_headers',
'gopher://bob.com/', 'https://lawn.tractor/models/1.php',
'http://hubblesite.org/news/2006/01/', 'http://digg.com/');
// Loop over these, check if they appear valid, if they do, try to access
foreach ($urls as $r) {
// If this does not validate:
if (!(validate_url($r))) {
// Set the display accordingly:
$disp = 'Did not validate!';
} else {
// Try to access it, and set display accordingly
$disp = check_url($r) ? 'GOOD!' : 'Could not contact...';
}
// Display this
echo "<p>{$r} = {$disp}</p>\n";
}
?>
这段检验程序只允许包含http、https和ftp的URL。当然,现实中还存在其他有效的URL方案,如mailto、gopher等。我们这样做是有原因的,主要是因为允许的这三种协议是目前URL里最常见的,再考虑到我们检查的是用户输入的URL,就更是这样了。另一个原因是我们想让通过检查的URL能够被实际验证。现在使用的验证方法是利用get_headers()函数来查看站点是否存在和工作,它不支持mailto和gopher链接,这两种标准现在还没有得到很好的支持。
另外还要注意到,虽然我们认为ftp开头的URL是有效的,但check_url()函数不支持ftp站点。验证ftp站点是否存在更加困难一些,因为ftp不支持与HTML的HEAD命令等效的命令。因此,如果想更改check_url()来处理ftp请求,这个函数必须扫描给定的ftp站点,然后尝试下载指定的文件,才能达到查证的目的。
|