php字符串处理(邮件处理)

简介: 今日做单据邮件提醒功能,发现系统发出的邮件总是显示不全。调用发送邮件方法前记录下来的日志是完全的。经查询原来是邮件格式对邮件单行有长度限制: ps1:邮件字符限制 本标准对行字符数量有2种限制。

今日做单据邮件提醒功能,发现系统发出的邮件总是显示不全。调用发送邮件方法前记录下来的日志是完全的。
经查询原来是邮件格式对邮件单行有长度限制:

ps1:邮件字符限制

本标准对行字符数量有2种限制。每行字符数必须(MUST)不超过998个,应该(SHOULD)不超过78个,
除了CRLF。

ps2:邮件正文换行符规定

  邮件正文一般由US-ASCII字符组成的多行文字。只有2个限制,如下:
  -CR,LF必须同时出现为CRLF,他们不可以分开出现在正文里。
  -正文的每行字符数必须(MUST)不超过998个,应该(SHOULD)不超过78个,除了CRLF。


(原文链接):http://hi.baidu.com/zhufangtian/item/ba54cb5f09780413abf6d74b

所以在发送邮件时必须对邮件字符串进行换行处理

   开始尝试用php substr() 函数按长度截断字符串换行,因为邮件正文里有很多html标签,在仅判断固定长度字符情况下,将很多标签组合截断(如<td> 在t和d之间截断换行了 ),所以原有的html标签被拆断了,破坏了原意,导致显示异常。

     后来测试codeigniter框架邮件发送插件,发现它支持这种单行超长邮件的发送,于是查看源码。分析其邮件正文处理方法,

最终处理步骤:

1.将字符串全部转化为小写

2.将回车换行符替换为<br>。因为本项目邮件为html格式的

3.去除多余空格

4.替换a标签内容,防止标签内容超长被截断

5.wordwrap方法处理字符串自动换行。()

在实际项目中发现换行符必须为\r\n(在windows情况下实际测试,网上很多都说为\n\r,个人感觉是说错了),所以必须要规定wordwrap方法的替换参数,注意在替换格式后添加空格是为了有些邮件客户端(outlook)可以正常解析换行的属性标签,有些则不能(foxmail) 

如截断后标签换行 tr和span中间有换行符,无空格。

<tr
span='3'>
6.替换回a标签内容


ps1:改造后邮件处理方法

//邮件文本替换
function __mailreplace($content, $type) {
	//替换回车换行符(注意替换字符串后添加 空格,以便在wordwrap方法中可以将字符串换行)
	if (strtolower ( $type ) == "html") {
		$content = ltrim ( $content );
		$content = str_replace ( array ('\n', '\r\n' ), "<br/> ", $content );
		$content = str_replace ( array (chr ( 13 ), chr ( 13 ) . chr ( 10 ) ), "<br/> ", $content );
		//替换空格
		$content = str_replace ( " ", " ", $content );
		//处理表格过长问题,将每行换行
		$content = str_replace ( "</tr>", "</tr> ", $content );
	} else {
		$content = str_replace ( array ("<br>", "<br/>" ), "\r\n", $content );
		$content = str_replace ( " ", " ", $content );
	}
	
        //替换多余空格
	$content = preg_replace ( "| +|", " ", $content );
	
	//替换a标签(防止链接过长被截断)
	$unwrap = array ();
	if (preg_match_all ( '|(<a.*>.*</a>)|U', $content, $matches )) {
		for($i = 0; $i < count ( $matches ['0'] ); $i ++) {
			$unwrap [] = $matches ['1'] [$i];
			$content = str_replace ( $matches ['1'] [$i], "{{a-link" . $i . "}}", $content );
		}
	}
	//过长字符串自动换行(添加空格,避免html标签内属性换行时无法正常解析)
	$content = wordwrap ( $content, 75, "\r\n ", FALSE );
			
	//替换回a标签
	if (count ( $unwrap ) > 0) {
		foreach ( $unwrap as $key => $val ) {
			$content = str_replace ( "{{a-link" . $key . "}}", $val, $content );
		}
	}
	return $content;
}

ps3:codeigniter源码:

public function word_wrap($str, $charlim = '') {
  // Se the character limit
  if ($charlim == '') {
   $charlim = ($this->wrapchars == "") ? "76" : $this->wrapchars;
  }
  
  // Reduce multiple spaces  去除多余空格
  $str = preg_replace ( "| +|", " ", $str );
  
  // Standardize newlines  替换回车 换行符
  
  if (strpos ( $str, "\r" ) !== FALSE) {
   $str = str_replace ( array ("\r\n", "\r" ), "\n", $str );
  }
  
  // If the current word is surrounded by {unwrap} tags we'll
  // strip the entire chunk and replace it with a marker. 批量替换特定标签(改为批量替换a链接)
  $unwrap = array ();
  if (preg_match_all ( "|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches )) {
   for($i = 0; $i < count ( $matches ['0'] ); $i ++) {
    $unwrap [] = $matches ['1'] [$i];
    $str = str_replace ( $matches ['1'] [$i], "{{unwrapped" . $i . "}}", $str );
   }
  }
  
  // Use PHP's native public function to do the initial wordwrap.
  // We set the cut flag to FALSE so that any individual words that are
  // too long get left alone.  In the next step we'll deal with them.
  // 截断字符串
  $str = wordwrap ( $str, $charlim, "\n", FALSE );
  
  // Split the string into individual lines of text and cycle through them
  $output = "";
  foreach ( explode ( "\n", $str ) as $line ) {
   // Is the line within the allowed character count?
   // If so we'll join it to the output and continue
   if (strlen ( $line ) <= $charlim) {
    $output .= $line . $this->newline;
    continue;
   }
   
   $temp = '';
   while ( (strlen ( $line )) > $charlim ) {
    // If the over-length word is a URL we won't wrap it
    if (preg_match ( "!\[url.+\]|://|wwww.!", $line )) {
     break;
    }
    
    // Trim the word down
    $temp .= substr ( $line, 0, $charlim - 1 );
    $line = substr ( $line, $charlim - 1 );
   }
   // If $temp contains data it means we had to split up an over-length
   // word into smaller chunks so we'll add it back to our current line
   if ($temp != '') {
    $output .= $temp . $this->newline . $line;
   } else {
    $output .= $line;
   }
   $output .= $this->newline;
  }
  // Put our markers back
  // 将替换字符串替换回来
  if (count ( $unwrap ) > 0) {
   foreach ( $unwrap as $key => $val ) {
    $output = str_replace ( "{{unwrapped" . $key . "}}", $val, $output );
   }
  }
  return $output;
 }




目录
相关文章
|
17天前
|
PHP
在PHP中,字符串操作
在PHP中,字符串操作
22 3
|
18天前
|
PHP
06 一文带你搞定PHP字符串操作
路老师带你深入PHP:本文详细介绍了PHP中的字符串定义、操作及常用函数,包括字符串的定义方式、定界符、字符串操作(如去除空格、获取长度、截取、替换、分割和合成等)。通过实例讲解,帮助你快速掌握PHP字符串处理技巧。
22 2
|
3月前
|
XML SQL PHP
php学习笔记-php字符串及字符串常用函数总结-day04
本文总结了PHP中字符串的三种定义方式和常用字符串处理函数,包括字符串的修剪、转换、长度计算、子串操作、比较、连接、分割及替换等操作。
|
5月前
|
存储 PHP 索引
|
5月前
|
API PHP 开发者
​邮件发送API示例代码,AOKSend关于PHP示例代码
**邮件发送API简化了开发中的邮件功能,如自动化通知和营销邮件。常见示例包括SendGrid和Mailgun的Python代码。AOKSend在PHP中的使用示例展示了如何使用Guzzle库发送邮件,其特点包括高可靠性、易于集成和强大功能。通过API,开发者能高效、可靠地发送大规模邮件。**
|
6月前
|
PHP
php删除字符串中的所有空格
php删除字符串中的所有空格
35 0
|
6月前
|
运维 Serverless API
Serverless 应用引擎产品使用合集之如何使用PHP SDK调用函数并在请求体(body)中传递字符串
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
7月前
|
PHP 开发者
【PHP 开发专栏】PHP 字符串处理与正则表达式
【4月更文挑战第30天】本文探讨了PHP中的字符串处理和正则表达式应用。字符串处理部分涵盖基本操作(如连接、长度计算、截取)、格式化(printf/sprintf)、转换(数字与字符串间转换、大小写变换)、比较。正则表达式部分介绍了基本概念、语法(字符类、量词、边界符、分组)及其在搜索替换、数据验证和信息提取中的应用。了解并熟练运用这些技术对PHP开发者至关重要。
63 3
|
7月前
|
安全 PHP
PHP反序列化---字符串逃逸(增加/减少)
PHP反序列化---字符串逃逸(增加/减少)