第11章 数据处理类
任何的程序都离不开数据,无论是大的程序、小的程序或是客户端程序还是网页程序等。而程序就是如何对这些数据进行处理。在前面几章中已经介绍了关于数字、变量和常量等的处理,本章主要讲解如何使用PHP处理字符串、Excel文档、加解密和时间日期的操作。
11.1 字符串
无论哪种语言,字符串操作都是一个重要的基础。PHP提供了大量的字符串操作函数用来处理字符串。如果在开发中合理地使用这些函数,那么它将有助于项目更快、更好地完成。本节就为读者介绍PHP开发中一些比较常用的字符串处理函数。
11.1.1 计算字符串的长度
字符串的长度一般是指,该字符串所包含字符的个数。在PHP中,可以使用strlen()函数来获取一个字符串的长度。使用该函数的语法如下所示:
int strlen ( string string )
strlen()函数接受一个字符串类型的参数并返回这个字符串的长度。代码11-1是使用strlen()函数计算字符串长度的一个例子。
代码11-1 使用strlen()函数计算字符串长度
<span class="kindle-cn-bold">使用strlen()函数计算字符串长度</span><hr /> 字符串“我非常喜欢PHP!”的长度为: <?php $str = "我非常喜欢PHP!"; //定义一个字符串 echo strlen($str); //使用strlen计算字符串的长度 ?>
以上代码首先定义一个字符串,然后使用strlen()函数计算它的长度并输出。运行代码后的结果如图11.1所示。
图11.1 使用strlen()函数计算字符串长度
由结果可以看到,如果按照正常的思维来算这个字符串包含的字符应该是9个,但是为什么这个字符串的长度为15呢?
这里对strlen()函数计算字符串长度方式做下介绍,它对单个英文字符的长度计算为1,对单个中文字的计算长度为2。所以才会出现图11.1所呈现的结果。
注意 如果strlen()函数计算的是UTF-8编码的字符串,其中的单个中文字的长度会被计算成3。
对于strlen()函数的这个特性与生活中计算的方式有些出入,如果使用PHP另外提供的mb_strlen()函数就能很好地解决这个问题,该函数的使用语法如下:
int mb_strlen ( string str [, string encoding] )
mb_strlen()函数的用法和strlen()函数类似,只不过它有第二个可选参数用于指定字符编码。例如得到UTF-8的字符串$str长度,可以用mb_strlen($str, 'UTF-8')。如果省略第二个参数,则会使用PHP的内部编码。内部编码可以通过mb_internal_encoding()函数得到。
注意 mb_strlen并不是PHP核心函数,使用前需要确保在php.ini中加载了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函数的问题。
代码11-2是使用mb_strlen()函数计算字符串长度的一个例子,如下所示。
代码11-2 使用mb_strlen()函数计算字符串长度
<span class="kindle-cn-bold">使用strlen()函数计算字符串长度</span><hr /> 字符串“我非常喜欢PHP!”的长度为: <?php $str = "我非常喜欢PHP!"; //定义一个字符串 echo mb_strlen($str, 'GB2312'); //使用mb_strlen函数计算字符串的长度,并制定编码 ?>
运行以上代码后,得到如图11.2所示的结果。这次的结果与平常计算字符串个数的方式是相同的。
图11.2 使用mb_strlen()函数计算字符串长度
11.1.2 截取指定长度字符串
截取指定长度字符串是指,获取这个字符串的某一特定部分。在PHP中,可以使用函数substr()来获取字符串的某一部分。该函数的语法如下所示:
string substr ( string string, int start [, int length] )
substr()返回string字符串中从位置start的字符开始,长度为length的字符串。如果开始是非负,则返回的字符串将开始在string的start位置,从0计数。例如,为“abcdef”中,在位置0字符是“a”,在位置2字符是“c”的,等等。
11.1.3 搜索指定的字符串
如果需要知道某个子字符串是否在指定的字符串中的位置,就可以使用PHP提供的strpos()函数。该函数的使用语法如下:
int strpos ( string haystack, mixed needle [, int offset] )
strops()返回needle第一次在haystack字符串中出现的位置。如果needle没有找到时,则返回FALSE。可选的offset参数允许在haystack字符串的指定位置开始搜索,返回的位置仍然是相对haystack的开始。
11.1.4 替换指定的字符串
在实际开发中,有时需要将字符串中的某些字符串替换成其他字符串,这可以通过PHP的内置函数str_replace()来完成。该函数的语法如下所示。
mixed str_replace ( mixed search, mixed replace, mixed subject [, int &count] )
该函数将字符串subject中的search部分全部替换成字符串replace,并且返回替换后的字符串。
11.1.5 转换字符串为数组
在PHP程序中,可以使用函数explode用一个字符串分隔另一个字符串,该函数的语法如下所示:
array explode ( string separator, string string [, int limit] )
此函数返回由字符串组成的数组,每个元素都是string的一个子串,它们被字符串separator作为边界点分隔出来。如果设置了limit参数,则返回的数组包含最多limit个元素,而最后那个元素将包含string的剩余部分。如果separator为空字符串(""),explode()将返回FALSE。如果separator所包含的值在string中找不到,那么explode()将返回包含string单个元素的数组。如果limit参数是负数,则返回除了最后的limit个元素外的所有元素。
11.1.6 转换数组为字符串
亦可使用implode()函数将数组转换为一个字符串,该函数的语法如下所示:
string implode ( string glue, array pieces )
此函数接受两个入参,glue为合并数组元素成字符串时所用的连接符,pieces为需要合并的数组。
11.1.7 设置字符编码
不过英文一般不会存在编码问题,只有中文数据才会有这个问题。比如你用Zend Studio或Editplus写程序时,用的是gbk编码,如果数据需要进入数据库,而数据库的编码为utf8时,这时就要把数据进行编码转换,不然进到数据库就会变成乱码。
PHP提供的iconv()函数库能够完成各种字符集间的转换,是编程中不可缺少的基础函数库。其使用语法如下所示:
string iconv ( string in_charset, string out_charset, string str )
11.2 使用PHPExcel操作Microsoft Excel文件
Microsoft Excel是微软公司的办公软件Microsoft office的组件之一,是由Microsoft为Windows和Apple Macintosh操作系统的电脑而编写和运行的一款试算表软件。Excel是微软办公套装软件的一个重要的组成部分,它可以进行各种数据的处理、统计分析和辅助决策操作,广泛地应用于管理、统计财经、金融等众多领域。
正因为Excel在现实生活中有如此普及的应用,不论是在学习和工作中都离不开它。所以在Web应用中也常会遇到需要操作Excel的事情。本小节就为读者讲解如何使用PHP来操作Microsoft Excel文件。
11.2.1 创建Excel文件
“工欲善其事,必先利其器”,需要调用PHPExcel类操作Word文件,就必须先了解PHPExcel这个类。这个用于操作Excel文件的PHP类的官方网址为http://phpexcel.codeplex.com/,如图11.3所示。
图11.3 PHPExcel官方网站
单击右上角的“Download”按钮即可下载最新稳定的版本,解压缩后得到的文档结构如图11.4所示。
图11.4 PHPExcel结构
其中Documentation文件夹与Tests分别为类文档和测试文件目录,在编程中需要真正用到的是Classes文件夹中的类。可以将其中的Classes文件夹整个解压到需要的程序目录下,以方便调用。此时PHPExcel的安装就完成了,是不是觉得很简单呢!
有了以上的基础,下面就来创建一个Word对象,并对它进行一些操作,具体如代码11-3所示。
代码11-3 创建Excel文件
<span class="kindle-cn-bold">使用PHPExcel生成Excel文档</span><hr /> <?php error_reporting(E_ALL); //错误显示级别 require_once 'Classes/PHPExcel.php'; //引入PHPExcel类 $objPHPExcel = new PHPExcel(); //创建PHPExcel对象 $objPHPExcel->setActiveSheetIndex(0); //设置活动表单 $objPHPExcel->getActiveSheet()->mergeCells('A1:D2'); //合并单元格 $objPHPExcel->getActiveSheet()->getStyle('A1:D2')->applyFromArray(//设定渐层背景颜色双色(灰/白) array( 'font'=> array( 'bold'=> true //字体加粗 ), 'alignment' => array( 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER, //左右居中对齐 ), 'borders' => array( 'top'=> array( 'style' => PHPExcel_Style_Border::BORDER_THIN //细边框 ) ), 'fill' => array( 'type'=> PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR, 'rotation'=> 90, 'startcolor' => array( 'rgb'=> 'DCDCDC' //渐变开始时的颜色 ), 'endcolor'=> array( 'rgb'=> 'FFFFFF' //渐变结束时的颜色 ) ) ) ); $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(16); //设定字号大小 //设定A1栏位显示文字PHPEXCEL 创建测试 $objPHPExcel->getActiveSheet()->setCellValue('A1', 'PHPEXCEL 创建测试'); $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_BLUE); //设定字体颜色 $objPHPExcel->getActiveSheet()->getStyle('A3:D3')->applyFromArray( //设定背景颜色单色 array('fill'=> array( 'type'=> PHPExcel_Style_Fill::FILL_SOLID, 'color'=> array('rgb' => 'D1EEEE') ), ) ); $objPHPExcel->getActiveSheet()->setCellValue('A3','test1'); //设定栏位值 $objPHPExcel->getActiveSheet()->setCellValue('B3','test2'); $objPHPExcel->getActiveSheet()->setCellValue('C3','test3'); $objPHPExcel->getActiveSheet()->setCellValue('D3','test4'); //设定的栏位宽度(自动) $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setAutoSize(true); $objPHPExcel->setActiveSheetIndex(0); //设置第一个表为默认表 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel 2007'); // Export to //Excel 2007 (.xlsx) 汇出成2007 $objWriter->save('11-3.xlsx'); $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel 5'); // Export to //Excel5 (.xls) 汇出成2003 $objWriter->save('11-3.xls'); ?>
整个创建过程是这样的,首先引入PHPExcel必要的文件,根据PHPExcel类创建一个对象,然后调用该类的方法对其中的表单元素进行相应操作,最后使用PHPExcel_IOFactory类的createWriter方法将创建的PHPExcel类导出成Excel文档。
其中最常用到的是用setCellValue()方法来设置每个单元格的内容,此方法接受两个参数,第一个是单元格的位置编号,第二个是需要设置的文本值。所以对于动态输入多行数据的情况,需要用程序来控制写入的单元格位置。除此之外还有许多其他的用法在示例中也有使用,但这里就不一一介绍,读者可以参考压缩包中的相关文档。
运行该程序成功以后,会在目录下产生两个Excel文档,如图11.5所示。打开其中的一个文档,看到的表格内容如图11.6所示。
图11.5 生成两个Excel文档 | 图11.6 生成的Excel内容 |
如上就是使用PHPExcel类来产生Excel文档的效果,如果生成的文档是Excel 2007以上的版本,那么它将支持更多的样式效果。
11.2.2 修改并导出Excel文件
在实际应用中,遇到的更多情况是根据原有的格式内容,插入相关数据并导出。对于这种情况就是需要在原有的Excel文档上添加指定格式的数据,然后导出数据文档。下面就举这样一个例子,如代码11-4所示。
代码11-4 修改并导出Excel文件
<?php require_once 'Classes/PHPExcel.php'; //引入PHPExcel类 $objReader = PHPExcel_IOFactory::createReader('Excel5'); //创建一个能读取的PHPExcel对象 $objPHPExcel = $objReader->load("template.xls"); //载入存在的xls文档 $objActSheet = $objPHPExcel->getActiveSheet(); //取得活动文档单 $objStyleA2 = $objActSheet->getStyle('A2'); //读取A2单元格样式 $objActSheet->duplicateStyle($objStyleA2, 'A8:P8'); //复制样式从A8到P8 $objStyleH2 = $objActSheet->getStyle('H2'); //读取H2单元格样式 $objActSheet->duplicateStyle($objStyleH2, 'H8'); //复制样式到H8 $objActSheet->getRowDimension(8)->setRowHeight(110); //设置第8行行高为110 $objActSheet->setCellValue('A8', '7'); //设置A8的值为7 $objActSheet->setCellValue('B8', '节能灯'); //设置B8的值为节能灯 $objActSheet->setCellValue('C8', 'energy saving lamp'); //设置单元格内容 $objActSheet->setCellValue('F8', '卡口式插头 20w 可调光'); $objActSheet->setCellValue('G8', 'bayonet type 20Wlight dimming avilable'); $objActSheet->setCellValue('H8', '32'); $objActSheet->setCellValue('I8', '50'); $objActSheet->setCellValue('J8', '0.018'); $objActSheet->setCellValue('K8', '10'); $objDrawing = new PHPExcel_Worksheet_Drawing(); //创建画笔对象 $objDrawing->setPath('template.jpg'); //载入图片 $objDrawing->setCoordinates('D8'); //定位画笔 $objDrawing->setWorksheet($objActSheet); //画在当前活动单上 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save(str_replace('.php', '.xls', __FILE__)); //导出到xls文档 ?>
具体的细节已在注释中说明,下面来讲一下这个程序的过程和重点。首先使用PHPExcel_ IOFactory的createReader方法创建一个PHPExcel的读取对象以便能载入现存的文档。然后对这个文档进行相应的操作,如添加数据、样式、图片等。完成这些以后,再调用PHPExcel_IOFactory的createWriter方法生成一个写入对象将此数据写入文档中并保存。
不要看这个示例中的代码数比前一个要少很多,但是这里提供的代码都是比较实用的。比如用duplicateStyle方法来复制应用的样式,setRowHeight方法来设置行高,PHPExcel_Worksheet_ Drawing类来插入图片等。
注意 很多时候要设置的格式比较复杂,一时在PHPExcel文档中找不到相关内容。可在原始的Excel文档中特定设置某一个单元格的样式,使用时可以复制该单元格样式,应用到需要的单元格中去。
在运行这个代码之前首先来看需要被插入数据的原始Excel文档,如图11.7所示。运行程序成功以后会得到一个新的Excel文档,如图11.8所示。在这个图片中高亮的部分就是新插入的数据,其中的格式基本与原来的保持一致。
图11.7 原始Excel文档
图11.8 插入数据后的Excel文档
11.3 加密和解密
随着互联网的快速发展,时时刻刻都在网络上发生大量的数据交互。当然一些重要的数据也在其中,所以对数据的安全性要求也越来越高。PHP作为一门流行的Web编程语言,为大家提供了一系列安全功能。在本小节中,将介绍这些PHP提供的数据安全功能,以便于给开发的程序增加安全性。
首先来简单介绍md5,它是一种不可逆加密算法。在互联网上的应用很广泛,比如很多的软件下载站提供某个软件相关的md5校验码(方便用户下载以后比较是否与服务器上的软件一致),保存在数据库中的用户密码一般也是结果md5加密的,诸如此类等。而PHP提供md5()函数,用来实现这种方式的加密。使用语法如下:
string md5 ( string str [, bool raw_output ] )
该函数实现对str的md5加密,并返回加密后的散列码。其中的可选参数raw_output如果为TRUE,则返回的散列码是16位的,默认该值为FALSE并返回32位的散列码。代码11-5是使用md5方式对字符串加密的一个例子。
代码11-5 使用md5对字符串进行加密
<span class="kindle-cn-bold">使用md5对字符串进行加密</span><hr /> <?php $str = "需要被加密的字符串"; //被加密的字符串 $md5_str = md5($msg); //使用md5加密 echo "<p>原字符串:" . $str; //输出原字符串 echo "</p><p>"; echo "md5加密后的字符串:" . $md5_str; //输出加密后的字符串 echo "</p>"; ?>
运行以上代码后的结果如图11.9所示。可以发现,尽管两个结果的长度都是32个字符,但明文中一点微小的变化使得结果发生了很大的变化,因此,混编和md5()函数是检查数据中微小变化的一个很好的工具。
图11.9 使用md5对字符串进行加密
接下来介绍的是PHP的一个扩展Mcrypt,完成了对常用加密算法的封装。其实该扩展是对Mcrypt标准类库的封装,Mcrypt完成了相当多的常用加密算法,如DES,TripleDES,Blowfish(default),3-WAY,SAFER-SK64,SAFER-SK128,TWOFISH,TEA,RC2和GOST加密算法,并且提供了CBC、OFB、CFB和ECB 4种块加密的模型。
这里介绍如何使用Mcrypt扩展库对数据进行加密,然后再介绍如何使用它进行解密。代码11-6对这一过程进行了演示,首先是对数据进行加密,然后在浏览器上显示加密后的数据,并将加密后的数据还原为原来的字符串,将它显示在浏览器上。
注意 如果提示没有相关函数,则需要将php.ini文件中“extension=php_mcrypt.dll”前的分号去掉。
代码11-6 使用Mcrypt对数据进行加解密
<span class="kindle-cn-bold">使用Mcrypt对数据进行加解密</span><hr /> <?php $string = "我是要被加密的字符串!"; //被加密的字符串 echo "原来字符串: $string <p>"; $key = "加密关键字"; $cipher_alg = MCRYPT_RIJNDAEL_128; //指定加密算法 //需要提供相应的加密向量 $iv = mcrypt_create_iv(mcrypt_get_iv_size($cipher_alg, MCRYPT_MODE_ECB), MCRYPT_RAND); $encrypted_string = mcrypt_encrypt($cipher_alg, $key, $string, MCRYPT_MODE_CBC, $iv); //开始加密 echo "加密字符串: ".bin2hex($encrypted_string)."<p>"; //输出加密后的字符 //解密echo "解密字符串: $decrypted_string"; $decrypted_string = mcrypt_decrypt($cipher_alg, $key, $encrypted_string, MCRYPT_MODE_CBC, $iv); ?>
上面的代码中两个最典型的函数是mcrypt_encrypt()和mcrypt_decrypt(),它们的用途是显而易见的,如图11.10和图11.11所示。这里使用了“电报密码本”模式,Mcrypt提供了几种加密方式,由于每种加密方式都有可以影响密码安全的特定字符,因此每种模式都需要了解。对于没有接触过密码系统的读者来说,可能对mcrypt_create_iv()函数更有兴趣,尽管对这一函数进行彻底地解释已经超出了本书的范围,但这里仍然会提到它创建的初始化向量(hence, iv),这一向量可以使每条信息彼此独立。尽管不是所有的模式都需要这一初始化变量,但如果在要求的模式中没有提供这一变量,PHP就会给出警告信息。
图11.10 使用Mcrypt对数据进行加解密1 | 图11.11 使用Mcrypt对数据进行加解密2 |
11.4 时间和日期
有关于时间和日期的信息在日常生活中占有很重要的地位,比如大家都会问:现在几点了,比如想知道下班公车什么时候到,比如在网上买了一件衣服,想看下掌柜是什么时候发的货,现在到了什么地方。同样,在编程中也会遇很多关于时间的问题。本节就来介绍如何使用PHP来处理时间和日期。
11.4.1 使用date()函数
看了本节所要介绍的内容,想必读者就会问,那如何使用PHP得到当前的时间和日期呢?针对这个问题,PHP提供date()函数来实现,它的使用语法如下:
string date ( string $format [, int $timestamp ] )
该函数返回根据预定义的格式,返回相应的被格式化后的字符串。$timestamp为一个UNIX时间戳格式的可选参数。如果该参数被设置,那么函数返回与其设置时间相应的被格式化后的字符串。如果没有给出时间戳,则使用当前的UNIX时间戳。表11.1给出了所有date函数的格式参数。
表11.1 date函数的格式参数
了解以上信息以后,就可以来构造一个显示当前时间的程序,如代码11-7所示。
代码11-7 使用PHP显示当前时间
<span class="kindle-cn-bold">使用PHP显示当前时间</span><hr /> 当前时间为:<?= date('Y-m-d H:i:s')?>
程序很简单,最重要的只有一行。运行后,输出服务器上的当前时间,如图11.12所示。
图11.12 使用PHP显示当前时间
11.4.2 使用mktime()函数
mktime()函数用于生成给定日期时间的时间戳,如果给出了日期和时间,则返回当前日期和时间的时间戳。其形式为:
int mktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]] )
每个可选参数的目的很明确,只有is_dst除外,需要夏时制时设置为1,不需要时设置为0,或者如果不确定则设置为-1(默认值)。默认值将提示由PHP确定日光节约是否生效。例如,如果希望了解2010年3月16日18:14的时间戳,只需输入适当的值:
echo mktime(18, 14, 00, 3, 16, 2010)
当然在程序设计中,最常用的莫过于和date()函数相结合来计算一些常用的时期差。下面是一个与date()相结合来计算明天、下个月与明年的时间,如代码11-8所示。
代码11-8 使用PHP计算日期
<span class="kindle-cn-bold">使用PHP计算日期</span><hr /> <?php $now = time(); //取得当前的时间 $tomorrow = mktime(0, 0, 0, date("m", $now), date("d", $now)+1, date("Y", $now)); //明天 $nextmonth = mktime(0, 0, 0, date("m", $now)+1, date("d", $now), date("Y", $now)); //下个月 $nextyear = mktime(0, 0, 0, date("m", $now), date("d", $now), date("Y", $now)+1); //明年 echo "今天:" . date('Y-m-d', $now) . "<p>"; //输出今天的时间 echo "明天:" . date('Y-m-d', $tomorrow) . "<p>"; //输出明天的时间 echo "下月:" . date('Y-m-d', $lastmonth) . "<p>"; //输出下月的时间 echo "明年:" . date('Y-m-d', $nextyear); //输出明年的时间 ?>
在以上代码中使用time()函数来得到当前时间的UNIX时间戳,在计算明天时,首先使用date()函数得到当天的值,然后使之加1。计算下月和明年的时间也是如此。运行的结果,如图11.13所示。
图11.13 使用PHP计算日期
11.4.3 验证日期有效性
在有了时间显示以后,有时候需要对它的有效性做一个验证。这时就需要用到PHP提供的checkdate()函数,该函数使用语法如下:
bool checkdate ( int month , int day , int year )
对于参数的传入值,从字面上可以很容易地理解,从左到右分别为月、日、年。这个和中国使用按年、月、日排列的习惯是有些差别的。如果给出的日期有效则返回TRUE,否则返回FALSE。检查由参数构成的日期的合法性。代码11-9是使用checkdate()函数检验时间有效性的例子。
代码11-9 使用checkdate()函数检验时间有效性
<span class="kindle-cn-bold">使用checkdate()函数检验时间有效性</span><hr /> <?php echo "2008年11月30日 " . (checkdate(11, 30, 2008) ? "<font color='green'>有效</font>" : "<font color='red'>无效</font>"); echo "<p>"; echo "2010 年 2 月 19 日 " . (checkdate(2, 19, 2010) ? "<font color='green'>有效</font>" : "<font color='red'>无效</font>"); echo "<p>"; echo "2012 年 4 月 31 日 " . (checkdate(4, 31, 2012) ? "<font color='green'>有效</font>" : "<font color='red'>无效</font>"); ?>
因为2012年的4月份只有30天,所以这个日期是无效的。其他的两个日期是有效的。运行代码以后得到的结果如图11.14所示。
图11.14 使用checkdate()函数检验时间有效性
11.5 典型实例
【实例11-1】截取字符串使用的是substr()函数,substr()函数可以根据指定的参数,截取一些字符,从而产生一个新的字符串。
在网页排版中,为了美观,往往会对过长的标题进行截取字符串的操作,但是substr()函数只对半角字符进行处理,如果用来处理全角的中文字符,会出现乱码的情况。本小节将介绍如何使用substr()函数,截取中文字符串。
由于中文字符都是全角,要截取中文字符时,需要一个偶数,作为第三个参数。还可以在字符串后加上“chr(0)”来防止乱码的出现。
代码11-10 构建一个新的截取字符串的函数
<?php //根据技术要点,构建一个新的截取字符串的函数 function getSubStr($str='',$length = 0){ //把参数的长度乘以2,以便于载取中文字符 $length *=2; //当要截取的字符串小于指定长度时,直接返回字符串 if(strlen($str)<=$length){ //使用strlen()函数,获取字符串的长度,再与指定的长度进行比较 return $str; } //根据指定的长度,截取字符串,并返回截取后的字符串 return substr($str,0,$length).chr(0)."..."; //在返回的字符串后加上chr(0),防止乱码的出现 } //定义一个含有中文与英文字符的字符串 $str = "这是中文,而且还包括半角符号"; //使用getSubStr()函数截取字符串并显示 echo getSubStr($str,14); ?>
运行该程序后,运行结果如图11.15所示。
图11.15 程序运行结果
【实例11-2】在PHP中获取日期和时间的函数包括:time()、mktime()等。这些函数返回的都只是一段数字,要想转换为常用的日期格式,可以使用date()函数进行转换。
(1)time()函数可以返回当前的Unix时间戳,time()函数没在参数。
(2)mktime()函数可以取得一个日期的Unix时间戳。mktime()有7个可选参数,前6个参数分别表示时、分、秒、月、日、年。第7个参数的值为1,表示支持夏时制时间;值为0时,表示不支持夏时制时间。当所有参数都省略时,将返回当前时间的Unix时间戳。
(3)date()函数可以根据参数,把Unix时间戳转换为常用的日期和时间格式。
代码11-11 获取日期和时间并转换
<?php $nextWeek = time() + (7 * 24 * 60 * 60); //当前日期秒数加上下周时间秒数 echo '现在日期:'. date('Y-m-d') ."<br>"; //显示当前日期 echo '下周日期:'. date('Y-m-d', $nextWeek)."<br>"; //显示下周日期 $time1 = mktime(0,0,0,1,1,1981); //取得1981年1月1日的Unix时间戳 $time2 = mktime(); //取得当前时间的Unix时间戳 //格式化时间戳,转换为常用日期格式 $oldtime = date("Y-m-d H:i:s",$time1); $nowtime = date("Y-m-d H:i:s",$time2); echo $oldtime."<br>".$nowtime."<br>"; //显示日期 echo $nowtime-$oldtime; //两个时间相减,得出时间差 ?>
运行该程序后,运行结果如图11.16所示。
图11.16 程序运行结果
【实例11-3】使用PHP生成万年历,主要使用了date()和mktime()函数,通过万年历的代码,可以详细地了解这两个函数的使用方法。
在本实例的代码中,主要用了3个函数来实现万年历:
(1)date()函数,用于格式化时间和取得当前时间信息。
(2)mktime()函数,用于取得请求的时间段的时间戳。
(3)checkdate()函数,用于检查参数运算的年、月、日是否合法。
代码11-12 使用PHP生成万年历
<html> <head> <title>万年月历</title> <meta http-equiv="Content-Type" content="text/html; charset=gb_2312"> <!-- Style --> <style type=text/css > <!-- table{ background-color: #B0C4DE; } tr{ background-color: White; } td{ font-size: 20pt; font-family : 宋体; color: #708090; line-height: 140%; } --> </style> </head> <body> <?php //检测用户是否提交数据 if(isset($_POST["year"])){ //使用用户提交的数据作为年数据 $year = $_POST["year"]; }else{ //使用当前日期的年作为年数据 $year = date("Y"); } if(isset($_POST["month"])){ $month = $_POST["month"]; }else{ $month = date("m"); } $date=01; //初始化月数据 $day=01; //初始化日数据 $off=0; //检测年数据是否正确 if($year<0 or $year > 9999){ //如果年数据不正确,显示错误信息,并返回上一页 echo "<script> alert('年份应在1至9999之间.');history.go(-1); </script>"; exit(); } if($month<0 or $month > 12){ //如果月数据不正确,显示错误信息,并返回上一页 echo "<script> alert('月份应在1至12月之间.');history.go(-1); </script> "; exit(); } while(checkdate($month,$date,$year)){ $date++; } //绘制万年历表头 ?> <form method=post action='' name=calendar> <table width=100% border=1 cellspacing=0 cellpadding=2 bordercolorlight=#333333 bordercolordark=#FFFFFF bgcolor=#CCCCFF> <tr align=center valign=middle> <td colspan=7 bgcolor=#efefef> <input type='text' name='year' size='4' maxlength='4' value=<?=$year?> > <input type='text' name='month' size='2' maxlength='2' value=<?=$month?> > <input type='submit' name='submit' align=absmiddle border=0 value='跳转'> </td> </tr> <tr align=center valign=middle> <td bgcolor=#efefef>日</td> <td>一</td> <td>二</td> <td>三</td> <td>四</td> <td>五</td> <td bgcolor=#efefef>六</td> </tr> <tr> <?php //构建万年历内容 while ($day<$date){ //设置日期颜色,如果是当前日期,使用红色进行标识 if($day == date("d") && $year == date("Y") && $month == date("m")){ $day_color = "red"; }else{ $day_color = "black"; } //设置星期天数据 if ($day == '01' and date( 'l', mktime(0,0,0,$month,$day,$year)) == 'Sunday'){ echo "<td><font color=$day_color>$day</font></td>"; $off = '01'; }elseif($day == '01' and date( 'l', mktime(0,0,0,$month,$day,$year)) == 'Monday'){ //设置星期一的数据 echo "<td> </td><td><font color=$day_color>$day</font></td>"; $off= '02'; }elseif($day == '01' and date( 'l', mktime(0,0,0,$month,$day,$year)) == 'Tuesday'){ //设置星期二的数据 echo "<td> </td><td> </td><td><font color=$day_color>$day</font></td>"; $off= '03'; }elseif($day == '01' and date( 'l', mktime(0,0,0,$month,$day,$year)) == 'Wednesday'){ //设置星期三的数据 echo "<td> </td><td> </td><td> </td><td><font color=$day_color>$day</font></td>"; $off= '04'; }elseif($day == '01' and date( 'l', mktime(0,0,0,$month,$day,$year)) == 'Thursday'){ //设置星期四的数据 echo "<td> </td><td> </td><td> </td><td> </td><td><font color=$day_color>$day</font></td>"; $off= '05'; }elseif($day == '01' and date( 'l', mktime(0,0,0,$month,$day,$year)) == 'Friday') { //设置星期五的数据 echo "<td> </td><td> </td><td> </td><td> </td><td> </td><td><font color=$day_color>$day</font></td>"; $off= '06'; }elseif($day == '01' and date( 'l', mktime(0,0,0,$month,$day,$year)) == 'Saturday') { //设置星期六的数据 echo "<td> </td><td> </td><td> </td><td> </td><td> </td><td>  </td><td><font color=$day_color>$day</font></td>"; $off= '07'; }else{ //直接显示日期 echo "<td><font color=$day_color>$day</font></td> \n"; } //递增while循环条件 $day++; //设置开关变量 $off++; //当$off大于7时,重起一行,并把$off变量置为1 if ($off>7) { echo "</tr><tr>"; $off= '01'; }else{ echo ""; } } //计算剩下数据,使用空表格填充 for($i=$off ; $i<=7 ; $i++){ echo "<td> </td>"; } ?> </tr> </table> </form> </body> </html>
运行该程序后,运行结果如图11.17所示。
图11.17 程序运行结果
11.6 小结
本章通过介绍一些主要的字符串处理函数,来学习在PHP程序中如何完成对字符串的操作。这些函数都是比较基本的,读者应该掌握。本章讲到的函数包括:将字符串分隔后存入数组的函数explode()。将数组中的元素合并成字符串的函数implode()。截取字符串的函数substr()。获取字符串长度的函数strlen()等。
介绍如何使用开源的PHPExcel来操作Microsoft Excel文件、PHP的加密和解密,以及时间日期函数date()、mktime()和checkdate()。
11.7 习题
一、填空题
1. 函数_____用于去除字符串两端指定的任意特殊字符。函数_____用于去除字符串左端指定的任意特殊字符。函数_____用于去除字符串右端指定的任意特殊字符。
2. 函数_____将传入的字符串全部转化为小写,函数_____将传入的字符串全部转化为大写。
3. 函数_____的作用是将字符串的第一个字符转化为大写,函数_____的作用是将字符串中的每个单词的首字符转化为大写。
4. 函数strcmp()用于_____的字符串的比较,函数strncasecmp()用于_____的字符串的比较。
5. 代码strncasecmp(“ABCde”,”abcde”,3)的返回结果为__________。
6. 函数_____返回查找字符串最后一次出现的位置,函数_____返回查找字符串第一次出现的位置。
7. 代码esho strsrt(“My name is li lei”,i)和echo strrchr(“My name is li lei”,i)的返回结果分别为__________、__________。
8. 用于加密字符串的函数为__________。
9. 代码eacho$formatted = sprintf(“%01.3f”,10)的输出结果为__________。
二、选择题
1. 查找字符串在母字符串中第一次出现的位置,并返回从此位置开始到母字符串结束的部分的函数是( )。
A. strstr()
B. strrchr()
C. strcmp()
D. str replace()
2. 用来查找字符串出现次数的函数为( )。
A. strrpos()
B. strpos()
C. substr count()
D. strncmp()
3. 下面程序的运行结果为( )。
eacho $pos = strrpos(php, “p”). “<br>”;
easho $po = strpos(php, “p”)
A. 3
1
B. 2
0
C. 1
1
D. 3
3
4.下面程序的运行结果为( )。
eacho substr replace(“ABC”, “DEF”, 3, 1)
A. ABC
B. DEF
C. ABCDEF
D. 以上都不对
5. 下面程序的运行结果为( )。
eacho substr count(“LiLi is a good girl”, ‘i’,2)
A. 4
B. 3
C. 2
D. 1
三、简答题
1. 简述trim()函数默认情况下去除的特殊字符。
2. 试列出字符串的大小转换的函数。
3. 列出关于查找匹配字符串的函数,并说明其功能。
四、编程题
1. 创建如下字符串:
$str=“welcome to BeiJing.”
然后进行如下操作:统计字符数、全部转化为大写,BeiJing改为China。
2. 将人名LiLeiLiLi|Tom|Jon放进数组中,并输出结果。