PHP 表单 - 验证邮件和URL

在Web表单中,经常需要用户输入电子邮件地址和URL。确保这些输入格式正确是非常重要的。本章节将详细介绍如何在PHP中验证电子邮件地址和URL的有效性。

为什么需要验证邮件和URL?

验证电子邮件地址和URL有以下几个重要原因:

  • 确保用户提供的联系方式可以被正确使用
  • 防止无效数据存储到数据库中
  • 提高用户输入数据的质量
  • 减少因无效数据导致的系统错误

PHP验证电子邮件地址

PHP提供了内置函数filter_var()来验证电子邮件地址:

<?php
$email = "user@example.com";

// 验证电子邮件地址
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $emailErr = "无效的邮箱格式";
} else {
    echo "邮箱格式正确";
}
?>

您也可以使用正则表达式来验证电子邮件地址,但使用PHP内置的过滤器通常更简单可靠。

PHP验证URL

同样,PHP也提供了验证URL的内置过滤器:

<?php
$url = "https://www.example.com";

// 验证URL
if (!filter_var($url, FILTER_VALIDATE_URL)) {
    $urlErr = "无效的URL格式";
} else {
    echo "URL格式正确";
}
?>

您还可以使用FILTER_FLAG_PATH_REQUIREDFILTER_FLAG_QUERY_REQUIRED标志来指定URL必须包含路径和查询字符串:

<?php
$url = "https://www.example.com/path?query=value";

// 验证URL,要求包含路径
if (!filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)) {
    $urlErr = "URL必须包含路径";
} else {
    echo "URL包含路径";
}

// 验证URL,要求包含查询字符串
if (!filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED)) {
    $urlErr = "URL必须包含查询字符串";
} else {
    echo "URL包含查询字符串";
}
?>

使用正则表达式验证

除了使用PHP内置的过滤器外,您还可以使用正则表达式来验证电子邮件地址和URL:

验证电子邮件的正则表达式

<?php
$email = "user@example.com";

// 电子邮件验证的正则表达式
$emailRegex = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';

if (!preg_match($emailRegex, $email)) {
    $emailErr = "无效的邮箱格式";
} else {
    echo "邮箱格式正确";
}
?>

验证URL的正则表达式

<?php
$url = "https://www.example.com";

// URL验证的正则表达式
$urlRegex = '/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/\/=]*)$/';

if (!preg_match($urlRegex, $url)) {
    $urlErr = "无效的URL格式";
} else {
    echo "URL格式正确";
}
?>

综合示例:包含邮件和URL验证的表单

下面是一个完整的表单示例,包含了电子邮件地址和URL的验证:

<?php
// 定义变量并设置为空值
$email = $website = "";
$emailErr = $websiteErr = "";
$successMessage = "";

// 检查表单是否已提交
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // 验证电子邮件
    if (empty($_POST["email"])) {
        $emailErr = "邮箱是必填的";
    } else {
        $email = test_input($_POST["email"]);
        // 使用PHP内置过滤器验证邮箱
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $emailErr = "无效的邮箱格式";
        }
    }
    
    // 验证网站URL
    if (!empty($_POST["website"])) {
        $website = test_input($_POST["website"]);
        // 检查URL是否包含协议,如果没有则添加http://
        if (!preg_match("/^https?:\/\//", $website)) {
            $website = "http://" . $website;
        }
        // 验证URL格式
        if (!filter_var($website, FILTER_VALIDATE_URL)) {
            $websiteErr = "无效的URL格式";
        }
    }
    
    // 如果没有错误,显示成功消息
    if (empty($emailErr) && empty($websiteErr)) {
        $successMessage = "表单提交成功!";
    }
}

// 清理输入数据的函数
function test_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}
?>

<!DOCTYPE html>
<html>
<head>
<style>
.error {
    color: #FF0000;
    font-size: 0.9em;
    margin-left: 5px;
}

.success {
    color: #059669;
    background-color: #d1fae5;
    padding: 10px;
    border-radius: 4px;
    margin-bottom: 20px;
}

.form-group {
    margin-bottom: 15px;
}

.form-group label {
    display: inline-block;
    width: 120px;
    font-weight: 500;
}

.form-group input {
    padding: 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
    width: 250px;
}

input[type="submit"] {
    padding: 10px 20px;
    background-color: #4F46E5;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

input[type="submit"]:hover {
    background-color: #4338CA;
}
</style>
</head>
<body>

<h2>联系表单</h2>

<?php if (!empty($successMessage)): ?>
    <div class="success"><?php echo $successMessage; ?></div>
<?php endif; ?>

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
    <div class="form-group">
        <label for="email">邮箱 *</label>
        <input type="text" id="email" name="email" value="<?php echo $email;?>">
        <span class="error"><?php echo $emailErr;?></span>
    </div>
    
    <div class="form-group">
        <label for="website">网站</label>
        <input type="text" id="website" name="website" value="<?php echo $website;?>" placeholder="http://www.example.com">
        <span class="error"><?php echo $websiteErr;?></span>
    </div>
    
    <p><span class="error">* 必填字段</span></p>
    <input type="submit" name="submit" value="提交">
</form>

</body>
</html>

高级验证技巧

以下是一些高级的电子邮件和URL验证技巧:

1. 检查电子邮件域名是否存在

除了验证电子邮件格式外,您还可以检查域名是否存在:

<?php
function isValidEmailDomain($email) {
    // 获取域名部分
    list(, $domain) = explode('@', $email);
    
    // 检查域名是否存在
    return checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A');
}

$email = "user@example.com";
if (filter_var($email, FILTER_VALIDATE_EMAIL) && isValidEmailDomain($email)) {
    echo "有效的电子邮件地址";
} else {
    echo "无效的电子邮件地址";
}
?>

2. 规范化URL

在验证URL之前,您可能需要规范化URL,例如添加缺失的协议:

<?php
function normalizeUrl($url) {
    // 移除首尾空白字符
    $url = trim($url);
    
    // 如果URL不包含协议,添加http://
    if (!preg_match("/^https?:\/\//", $url)) {
        $url = "http://" . $url;
    }
    
    return $url;
}

$url = "example.com";
$normalizedUrl = normalizeUrl($url); // 返回 "http://example.com"
?>

3. 获取URL信息

PHP的parse_url()函数可以帮助您获取URL的各个组成部分:

<?php
$url = "https://user:pass@example.com:8080/path?query=value#fragment";
$urlParts = parse_url($url);

print_r($urlParts);
/*
输出:
Array
(
    [scheme] => https
    [host] => example.com
    [port] => 8080
    [user] => user
    [pass] => pass
    [path] => /path
    [query] => query=value
    [fragment] => fragment
)
*/
?>

提示:在实际应用中,电子邮件验证通常分为两个步骤:首先验证格式是否正确,然后发送验证邮件到用户提供的邮箱,要求用户点击链接确认邮箱的所有权。这样可以确保用户提供的是真实有效的邮箱地址。