You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP表单提交跳转错误页 邮件未发送问题排查

问题描述
  • 查阅过站内大量同类问题的修复方案后,表单提交功能仍异常:提交后直接跳转错误页面,无邮件发出。代码中已隐藏个人邮箱信息,实际$webmaster_email参数配置的是hotmail.com后缀的有效可接收邮箱。
  • 因表单代码过长未完整附出,该表单包含大量脚本逻辑,可根据单选框、下拉菜单的选项动态显示/隐藏对应表单区块,目前前端交互效果完全符合预期。
  • 表单前端脚本已针对部分输入项配置了required必填校验,暂不确定是否需要在发送邮件的PHP文件中补充相同的校验逻辑。
关联代码:landformsend_mail.php 完整代码
<?php
/*
This first bit sets the email address that you want the form to be submitted to.
You will need to change this value to a valid email address that you can access.
*/
$webmaster_email = "email@hotmail.com";

/*
This bit sets the URLs of the supporting pages.
If you change the names of any of the pages, you will need to change the values here.
*/
$feedback_page = "landformtest.php";
$error_page = "landform_not_sent.html";
$thankyou_page = "landform_thank_you.html";

/*
This next bit loads the form field data into variables.
If you add a form field, you will need to add it here.
*/
$Name = $_REQUEST['Name'] ;
$ifowner = $_REQUEST['ifowner'] ;
$actualowner = $_REQUEST['actualowner'] ;
$Email = $_REQUEST['Email'] ;
$Phone = $_REQUEST['Phone'] ;
$timezone = $_REQUEST['timezone'] ;
$callafter = $_REQUEST['callafter'] ;
$callbefore = $_REQUEST['callbefore'] ;
$street = $_REQUEST['street'] ;
$city = $_REQUEST['city'] ;
$county = $_REQUEST['county'] ;
$state = $_REQUEST['state'] ;
$zipcode = $_REQUEST['zipcode'] ;
$apn = $_REQUEST['apn'] ;
$parcelsize = $_REQUEST['$parcelsize'] ;
$landunits = $_REQUEST['$landunits'] ;
$access = $_REQUEST['access'] ;
$roadowner = $_REQUEST['roadowner'] ;
$roadtype = $_REQUEST['roadtype'] ;
$othersurfacedetails = $_REQUEST['othersurfacedetails'] ;
$easedescr = $_REQUEST['easedescr'] ;
$tempaccess = $_REQUEST['tempaccess'] ;
$tempaccessdetails = $_REQUEST['tempaccessdetails'] ;
$ifsurvey = $_REQUEST['ifsurvey'] ;
$datesurvey = $_REQUEST['datesurvey'] ;
$ifperc = $_REQUEST['ifperc'] ;
$dateperc = $_REQUEST['dateperc'] ;
$septicpermit = $_REQUEST['septicpermit'] ;
$ifflood = $_REQUEST['ifflood'] ;
$ifelectric = $_REQUEST['ifelectric'] ;
$offgridelectric = $_REQUEST['offgridelectric'] ;
$altelecticdetails = $_REQUEST['altelectricdetails'] ;
$ifwater = $_REQUEST['ifwater'] ;
$datewell = $_REQUEST['datewell'] ;
$potablewellwater = $_REQUEST['potablewellwater'] ;
$ifsewer = $_REQUEST['ifsewer'] ;
$dateseptic = $_REQUEST['dateseptic'] ;
$currentzoning = $_REQUEST['currentzoning'] ;
$futurezoning = $_REQUEST['futurezoning'] ;
$futurezoningdetails = $_REQUEST['futurezoningdetails'] ;
$restrictions = $_REQUEST['restrictions'] ;
$restrictiondetails = $_REQUEST['restrictiondetails'] ;
$farming = $_REQUEST['farming'] ;
$somefarmingdetails = $_REQUEST['somefarmingdetails'] ;
$landuse = $_REQUEST['landuse'] ;
$description = $_REQUEST['description'] ;
$msg = 
"Name: " . $Name . "\r\n" . 
"If owner: " . $ifowner . "\r\n" . 
"Actual owner: " . $actualowner . "\r\n" . 
"Email: " . $Email . "\r\n" . 
"Phone: " . $Phone . "\r\n" .
"Time zone: " . $timezone . "\r\n" . 
"Call after: " . $callafter . "\r\n" . 
"But before: " . $callbefore . "\r\n" . 
"Property street address: " . $street . "\r\n" . 
"Property city: " . $city . "\r\n" . 
"Propety county: " . $county . "\r\n" . 
"Property state: " . $state . "\r\n" . 
"Property zipcode: " . $zipcode . "\r\n" . 
"APN: " . $apn . "\r\n" . 
"Parcel size: " . $parcelsize . "\r\n" . 
"Land units: " . $landunits . "\r\n" . 
"Access to land: " . $access . "\r\n" . 
"Road owner: " . $roadowner . "\r\n" . 
"Road surface type: " . $roadtype . "\r\n" . 
"Other surface type: " . $othersurfacedetails . "\r\n" . 
"Details of easement: " . $easedescr . "\r\n" . 
"Is temporary access available?: " . $tempaccess . "\r\n" . 
"Temporary access details: " . $tempaccessdetails . "\r\n" . 
"Has a survey been done? : " . $ifsurvey . "\r\n" . 
"Date of survey: " . $datesurvey . "\r\n" . 
"Has a perc test been done? : " . $ifperc . "\r\n" . 
"Date of perc test: " . $dateperc . "\r\n" . 
"Is there a septic permit? : " . $septicpermit . "\r\n" . 
"Is the land within a flood zone? : " . $ifflood . "\r\n" . 
"Is there electric? : " . $ifelectric . "\r\n" . 
"Is there an alternate source of electricity? : " . $offgridelectric . "\r\n" . 
"Details of the alt electric source: " . $altelecticdetails . "\r\n" . 
"Is there water? : " . $ifwater . "\r\n" . 
"Date well drilled: " . $datewell . "\r\n" . 
"Is the water drinkable? : " . $potablewellwater . "\r\n" . 
"Is there a sewer system? : " . $ifsewer . "\r\n" . 
"Date septic system was installed: " . $dateseptic . "\r\n" . 
"Current land zoning: " . $currentzoning . "\r\n" . 
"Are there plans to change the zoning?: " . $futurezoning . "\r\n" .
"Details of future zoning: " . $futurezoningdetails . "\r\n" .
"Are there any Use restrictions? : " . $restrictions . "\r\n" .
"Details of any restrictions: " . $restrictiondetails . "\r\n" .
"Is farming permitted? : " . $farming . "\r\n" .
"Details of any farming restrictions: " . $somefarmingdetails . "\r\n" .
"What is the land being used for at this time? : " . $landuse . "\r\n" .
"Description of land: " . $description ;

/*
The following function checks for email injection.
Specifically, it checks for carriage returns - typically used by spammers to inject a CC list.
*/
function isInjected($str) {
    $injections = array('(\n+)',
    '(\r+)',
    '(\t+)',
    '(%0A+)',
    '(%0D+)',
    '(%08+)',
    '(%09+)'
    );
    $inject = join('|', $injections);
    $inject = "/$inject/i";
    if(preg_match($inject,$str)) {
        return true;
    }
    else {
        return false;
    }
}

// If the user tries to access this script directly, redirect them to the feedback form,
if (!isset($_REQUEST['Email'])) {
header( "Location: $error_page" );
}

// If the form fields are empty, redirect to the error page.
elseif (empty($Name) || empty($Email) || empty($city) || empty($county) || empty($state)) {
header( "Location: $error_page" );
}

/* 
If email injection is detected, redirect to the error page.
If you add a form field, you should add it here.
*/
elseif ( isInjected($Email) || isInjected($Name) || isInjected($ifowner) || isInjected($actualowner) || isInjected($Phone) || isInjected($timezone) || isInjected($callafter) || isInjected($callbefore) || isInjected($street) || isInjected($city) || isInjected($county) || isInjected($state) || isInjected($zipcode) || isInjected($apn) || isInjected($parcelsize) || isInjected($landunits) || isInjected($access) || isInjected($roadowner) || isInjected($roadtype) || isInjected($othersurfacedetails) || isInjected($easedescr) || isInjected($tempaccess) || isInjected($tempaccessdetails) || isInjected($ifsurvey) || isInjected($datesurvey) || isInjected($ifperc) || isInjected($dateperc) || isInjected($septicpermit) || isInjected($ifflood) || isInjected($ifelectric) || isInjected($offgridelectric) || isInjected($altelecticdetails) || isInjected($ifwater) || isInjected($datewell) || isInjected($potablewellwater) || isInjected($ifsewer) || isInjected($dateseptic) || isInjected($currentzoning) || isInjected($futurezoning) || isInjected($futurezoningdetails) || isInjected($restrictions) || isInjected($restrictiondetails) || isInjected($farming) || isInjected($somefarmingdetails) || isInjected($landuse) || isInjected($description) ) {
header( "Location: $error_page" );
}

// If we passed all previous tests, send the email then redirect to the thank you page.
else {

    mail( "$webmaster_email", "Landform Results", $msg );

    header( "Location: $thankyou_page" );
}
?>
问题排查结果&修复方案
  • 核心触发原因:接收表单参数时,parcelsize和landunits两个字段的键名多写了多余的$符号,和前端实际传的字段名不匹配,导致两个变量取值为空,直接触发空值校验逻辑跳转错误页。将这两行的键名去掉$即可:
    // 修正前
    $parcelsize = $_REQUEST['$parcelsize'] ;
    $landunits = $_REQUEST['$landunits'] ;
    // 修正后
    $parcelsize = $_REQUEST['parcelsize'] ;
    $landunits = $_REQUEST['landunits'] ;
    
  • 后端校验必须补充:前端的required校验仅对正常操作的用户生效,恶意用户可以直接通过浏览器控制台绕过前端校验提交非法请求,后端必须配置和前端一致的必填校验、格式校验规则,不能依赖前端校验结果。
  • 邮件发送逻辑优化:PHP原生mail()函数默认无SMTP认证配置,向hotmail这类有严格反垃圾规则的邮箱发信时,大概率会被直接拦截拒收,即使校验通过也可能收不到邮件。建议替换为带SMTP认证的发信方式,配置正确的发件服务器地址、账号、密码、加密端口。
  • 代码逻辑补全:所有header()跳转语句后必须加exit;终止后续代码执行,避免出现逻辑漏洞。
  • 细节修正:拼接邮件正文时将Propety county的拼写错误修正为Property county,避免收到的邮件内容出现错别字。

内容的提问来源于stack exchange,提问作者Dragonwalker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:03:23