当前位置: 首页 > 后端技术 > PHP

PHP中iconv扩展相关函数学习

时间:2023-03-29 16:02:11 PHP

想必大家都接触过iconv的扩展相关函数吧。作为PHP的默认扩展,它已经存在了很长时间,也是我们在操作字符编码时经常使用的一个函数。但是除了iconv()这个函数,你知道它的其他函数吗?今天,我们就来了解一下iconv扩展中的各种好玩的功能。iconv设置和获取信息首先,我们可以在iconv扩展中设置默认定义的输出和输出字符编码格式。iconv_set_encoding("internal_encoding","UTF-8");//弃用:iconv_set_encoding():不推荐使用iconv.internal_encodingconv_set_encoding("output_encoding","ISO-8859-1");//弃用:iconv_set_encoding():不推荐使用iconv.output_encodingvar_dump(iconv_get_encoding());//array(3){//["input_encoding"]=>//string(5)"UTF-8"//["output_encoding"]=>//string(10)"ISO-8859-1"//["internal_encoding"]=>//string(5)"UTF-8"//}iconv_set_encoding()接收两个参数,一个是设置的属性类型,一种是设置编码格式。属性类型包括internal_encoding、input_encoding和output_encoding,分别代表内部、输入和输出编码格式。在这段测试代码中,我们设置internal_encoding为UTF8,设置output_encoding为ISO-8859-1,然后使用iconv_get_encoding()打印出当前环境下的相关iconv属性设置信息。可以看到默认情况下,当前环境中的input_encoding也是UTF8格式。不过需要注意的是iconv_set_encoding()已经是一个废弃的函数,否则不建议使用该函数来设置以上三种属性类型,它们会报outdatedwarning信息。现在更推荐使用php.ini中的default_charset直接设置。iconv获取字符长度,指定位置,根据编码截取字符串。面对中文字符串的操作时,strlen()等默认函数返回的汉字长度不正确,涉及到编码问题。问题。一般情况下,UTF8占用三个字节,而GBK占用两个字节,所以一个汉字如果是UTF8环境下的汉字,会返回3。当然,现在大多数情况下我们都会使用MB库扩展的相关函数来处理这类问题,但是iconv也为我们提供了几个字符串操作的函数。echoiconv_strlen("测试长度测试长度"),PHP_EOL;//8echoiconv_strlen("测试长度测试长度",'ISO-8859-1'),PHP_EOL;//24echoiconv_strlen("测试长度测试长度",'GBK'),PHP_EOL;//12echo'======',PHP_EOL;echoiconv_strpos("测试长度测试长度","long"),PHP_EOL;//2echoiconv_strpos("测试长度测试长度","long",0,'ISO-8859-1'),PHP_EOL;//6echoiconv_strpos("测试长度测试长度","Long",0,'GBK'),PHP_EOL;//echo'======',PHP_EOL;echoiconv_strrpos("测试长度测试长度","Long"),PHP_EOL;//6echoiconv_strrpos("测试长度测试长度","Long",'ISO-8859-1'),PHP_EOL;//18echo'======',PHP_EOL;echoiconv_substr("测试长度测试长度",2,4),PHP_EOL;//长度测试echoiconv_substr("测试长度testlength",6,12,'ISO-8859-1'),PHP_EOL;//长度测试echoiconv_substr("测试长度testlength",3,6,'GBK'),PHP_EOL;//lengthtesticonv_strlen()是获取字符串长度,如果不给第二个参数是根据默认字符集编码获取字符串长度。从测试代码可以看出,对于同样的八个汉字,不同编码返回的数字是不同的。这里我们发现iconv中GBK的中文是1.5个字节,即8个汉字占用12个字节的长度。iconv_strpos()与iconv_strrpos()和strpos()功能相同,返回字符第一次出现的位置,一种是从前到后(从左到右),一种是从后到前(从右到左边)。它们的第三个参数是偏移量,即找到指定字符后的几个单位。从这里我们可以看出GBK编码的运行有问题,因为在iconv中,GBK是1.5个字节,会造成单个字符无法定位的问题。iconv_substr()很明显是截取字符串的函数,我们还需要根据编码格式指定它的截取位置。iconv转换字符编码接下来就是本尊的iconv()函数的使用了。其实也没什么好说的。它只是将指定的编码转换为另一种编码。这个功能相信大家都不陌生。$phone=file_get_contents('https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13888888888');print_r($phone);//__GetZoneResult_={//mts:'1388888',//province:'????',//catName:'??й?????',//telString:'13888888888',//areaVid:'30515',//ispVid:'3236139',//运营商:'???????'//}print_r(iconv('GBK','UTF-8',$phone));//__GetZoneResult_={//mts:'1388888',//省份:'云南',//catName:'中国移动',//telString:'13888888888',//areaVid:'30515',//ispVid:'3236139',//carrier:'云南移动'//}print_r(iconv('GBK','ISO-8859-1//忽略',$phone));//__GetZoneResult_={//mts:'1388888',//省份:'',//catName:'',//telString:'13888888888',//areaVid:'30515',//ispVid:'3236139',//carrier:''//}找到这个淘宝开放接口查询手机号信息,返回只是右边是GBK类型的数据。当我们直接打印结果时,在UTF8环境下会输出乱码信息。这时候我们可以很方便的通过iconv()函数将编码转换为UTF8格式,并正确打印结果。第三个测试中,我们在要转换成的字符集编码类型后面加上//IGNORE,目的是忽略不能转换的内容,所以可以看出,当我们最后转换成错误的ISO-8859-1、中文信息全没了,因为不能转换,被忽略了。mimeheader操作最后,我们来看一个很不常见的内容,就是iconv也可以直接转换mimeheader中的编码内容信息。这个mime头信息实际上表明了当前文件或内容的mime类型。通常我们根据它来判断上传的文件是否正确。此外,这种mime标头还广泛用于电子邮件发送。做过邮件收发相关开发和抓包的同学一定看过下面的内容。headers_string=<<收到:来自localhost(localhost[127.0.0.1])bylocalhostwithSMTPidexamplefor;Thu,1Jan197000:00:00+0000(UTC)(envelope-fromexample-return-0000-example=example.com@example.com)Received:(qmail0由uid65534调用);1星期四200300:00:00+0000EOF;主题字符是电子邮件的标题,收件人是发件人的电子邮件地址。这里主要看Subject的内容。在它的开头,有一段描述了这个字段使用的编码信息,?UTF-8,然后后面就是一堆看不懂的东西。其实我们可以简单的看出这是一个base64编码的内容。如果我们在对应的编码内容下进行解码,就可以看到原文信息了。不过这时候我们也可以使用iconv直接转换它的编码。$headers=iconv_mime_decode_headers($headers_string,0,"ISO-8859-1");var_dump($headers);//array(5){//["Subject"]=>//string(15)"Pr.fungPr?fung"//["To"]=>//string(19)"example@example.com"//["Date"]=>//string(30)"Thu,1Jan197000:00:00+0000"//["Message-Id"]=>//string(21)""//["Received"]=>//array(2){//[0]=>//string(204)“来自本地主机(localhost[127.0.0.1]),本地主机使用的SMTPid示例;周四,1970年1月1日00:00:00+0000(UTC)(envelope-fromexample-return-0000-example=example.com@example.com)"//[1]=>//string(57)"(qmail0由uid65534调用);1Thu200300:00:00+0000"//}//}看到了吗?不仅直接转换了编码,还在PHP中将mime头格式转换成数组格式。当然,我们这里测试的代码是将正常的内容转成ISO-8859-1,反而出现了乱码。再举一个中文邮件的例子。$headers_string=<<Delivered-To:bhw98@sina.comReceived:(qmail75513通过别名调用);2002年5月20日02:19:53-0000收到:来自未知(HELObluesky)(61.155.118.135),通过202.106.187.143使用SMTP;2002年5月20日02:19:53-0000消息ID:<007f01c3111c$742fec00$0100007f@bluesky>发件人:“=?gb2312?B?wLbAtrXEzOwNCg==?=”收件人:“bhw98”抄送:主题:=?gb2312?B?ztK1xLbgtK6/2rPM0PI=?=Date:Sat,20May200210:03:36+0800MIME-Version:1.0Content-Type:multipart/mixed;boundary="----=_NextPart_000_007A_01C3115F.80DFC5E0"EOF;$headers=iconv_mime_decode_headers($headers_string,0,"UTF-8");var_dump($headers);//数组(11){//["Return-Path"]=>//string(21)""//["Delivered-To"]=>//string(14)"bhw98@sina.com"//["Received"]=>//array(2){//[0]=>//string(58)“(qmail75513由别名调用);2002年5月20日02:19:53-0000”//[1]=>//string(101)“来自未知(HELObluesky)(61.155.118.135)by202.106.187.143withSMTP;20May200202:19:53-0000"//}//["Message-ID"]=>//string(40)"<007f01c3111c$742fec00$0100007f@bluesky>"//["From"]=>//string(38)""BlueSky//""//["To"]=>//string(24)""bhw98""//["Cc"]=>//string(21)""//["Subject"]=>//string(21)"我的更多连载节目"//["Date"]=>//string(31)"Sat,20May200210:03:36+0800"//["MIME-Version"]=>//string(3)"1.0"//["Content-Type"]=>//string(16)"multipart/mixed;"//}这个中文邮件mime头的Subject指定GB2312。通过iconv_mime_decode_headers()函数,我们把整个文件头信息转换成UTF8格式,然后所有内容信息就可以正常显示了。当然,我们也可以对个别MIME字段进行转码。echoiconv_mime_decode("主题:=?gb2312?B?ztK1xLbgtK6/2rPM0PI=?=",0,'UTF-8'),PHP_EOL;//主题:我的多串口程序除了对接收到的信息进行编码转换外,还可以自己对相关内容进行编码发送。$preferences=array("input-charset"=>"UTF-8","output-charset"=>"GBK","line-length"=>76,"line-break-chars"=>"\n");$preferences["scheme"]="Q";echoiconv_mime_encode("Subject","Testheader",$preferences),PHP_EOL;//Subject:=?GBK?Q?=B2=E2=CA=D4=CD=B7?=$preferences["scheme"]="B";echoiconv_mime_encode("Subject","Testheader",$preferences),PHP_EOL;//Subject:=?GBK?B?suLK1M23?=iconv_mime_encode()函数是用于对mime标头进行编码的函数。第一个参数是mime字段名,第二个参数是字段值,第三个函数是我们编码的参数。encoding参数的内容从字段名可以看出,从什么编码到什么编码,行的长度是多少,换行符是什么。此外,它还有一个scheme字段,用于指定编码结果的类型。如果设置了B,那么编码结果会加上一层base64操作。总结奇怪的小动作是不是又变多了?没错,我刷文档之前只认识一个iconv。甚至在了解了这些内容后,我发现邮件信息原来是这样编码的,我一下子觉得自己高大上了。好了,废话少说,自己试试吧!测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202011/source/2。学习PHP中iconv扩展相关的函数。PHP参考文档:https://www.cnblogs。com/onelikeone/p/7865596.htmlhttps://www.php.net/manual/zh/book.iconv.php各媒体平台均可搜索【硬核项目经理】