Thread: php URL 验证
View Single Post
  #1   IP: 222.76.215.18
Old 2008-01-24, 10:27 PM
car car is offline
高级会员
 
Join Date: 2006-05-14
Posts: 534
car 正向着好的方向发展
Default 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站点,然后尝试下载指定的文件,才能达到查证的目的。
Reply With Quote