如何在邮件模板中使用动态变量值并解决URI非法字符错误
解决CodeIgniter邮件发送的变量替换与URI非法字符问题
我来帮你搞定这两个问题,咱们一步步调整代码来解决:
1. 动态变量未替换的问题
你当前的模板链接没有正确把$confirmationcode和$unumber嵌入到URL中,导致变量无法被解析。正确的做法是先构建完整的确认链接,再将其插入到邮件模板里。
首先生成带动态参数的完整确认URL:
$confirmationcode = rand(10, 1000); $unumber = uniqid(); // 拼接带动态参数的确认链接 $confirmLink = "http://example.com/mycon/emailconfirmation/{$confirmationcode}/{$unumber}";
然后修改邮件模板$fetch_tration,把链接替换成上面的变量:
// 把Confirm文本做成带动态链接的HTML $fetch_tration = '<p>Please <a href="'.$confirmLink.'" rel="nofollow noreferrer">CONFIRM</a> your registration with www.domain.Com</p>';
这样邮件内容里的链接就会自动带上动态生成的参数了。
2. URI包含非法字符的问题
CodeIgniter默认限制了URI中允许的字符,当$unumber(来自uniqid())包含下划线这类默认不允许的字符时,就会触发"The URI you submitted has disallowed characters."的错误。
有两种解决方式:
方法一:调整CodeIgniter的URI允许字符
打开application/config/config.php,找到$config['permitted_uri_chars'],把下划线(或其他需要的字符)加入允许列表,比如:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
注意:不要过度放宽字符限制,避免引入安全风险。
方法二:生成不含特殊字符的唯一ID
如果你不想修改全局配置,可以修改uniqid()的调用方式,生成仅含字母数字的唯一ID:
// 移除uniqid生成的下划线,避免URI错误 $unumber = str_replace('_', '', uniqid());
修正后的完整代码
把以上调整整合到你的邮件发送代码中,最终版本如下:
// 生成动态参数 $confirmationcode = rand(10, 1000); $unumber = str_replace('_', '', uniqid()); // 移除下划线避免URI非法字符问题 $confirmLink = "http://example.com/mycon/emailconfirmation/{$confirmationcode}/{$unumber}"; // 构建邮件模板 $fetch_tration = '<p>Please <a href="'.$confirmLink.'" rel="nofollow noreferrer">CONFIRM</a> your registration with www.domain.Com</p>'; // 构建邮件HTML内容 $message= '<html><head></head><body> <div style="height:600px; width:100%; "> <h3>'.$fetch_tration.'</h3> </div></body> </html>'; // SMTP配置 $config['protocol'] = 'smtp'; $config['smtp_host'] = 'ssl://smtp.gmail.com'; $config['smtp_port'] = 465; $config['smtp_user'] = 'example@example.com'; $config['smtp_pass'] = '************'; $config['charset'] = 'utf-8'; $config['wordwrap'] = TRUE; $config['mailtype'] = 'html'; // 直接把mailtype放入配置,减少重复代码 $this->load->library('email'); $this->email->initialize($config); $this->email->set_newline("\r\n"); $this->email->from('example@example.com', 'Admin Team'); $this->email->to('example@example.com'); // 注意给邮箱地址加引号,避免解析错误 $this->email->subject('Confirm Registration'); $this->email->message($message); // 可选:添加发送结果判断与调试信息 if ($this->email->send()) { echo '邮件发送成功'; } else { echo $this->email->print_debugger(); // 调试时查看发送错误详情 }
另外补充几个小细节:
$this->email->to(example@example.com)必须给邮箱地址加引号,否则会被当成常量解析- 将
mailtype放入配置中,避免重复调用set_mailtype - 添加发送结果判断和调试信息,方便排查发送失败的问题
内容的提问来源于stack exchange,提问作者Akash Jha




