



PHP中的字符串有三种定义方式,包括双引号、单引号和定界符。其中,双引号定义的字符串比较常用,其中的一些特殊字符需要使用\符号进行转义,如表3-1。
表 3-1 PHP字符串转义字符
双引号字符串中,除了字符转义,还可以直接引用变量的数据,前面已有相关的应用,通过下面的代码再来看一下应用效果。
<?php
$x=10;
$y=99;
echo "$x + $y = ",$x+$y;
?>
echo语句中,双引号定义的字符串中直接使用了$x和$y变量名,它们会自动转换为实际的数值,最终的显示结果就是10 +99 = 109。
有时候,由于变量名和字符串内容可能会混合在一起,无法有效地区分变量名。此时,可以使用一对花括号将变量名包含起来,如下面的代码。
<?php
$x=10;
$y=99;
echo "{$x}+{$y}=",$x+$y;
?>
单引号字符串,使用一对单引号定义字符串,其中,需要转义的字符只有两个,即“\’”表示单引号(')、“\\”表示外斜线(\)。此外,单引号字符串不能引用变量名,如'{$x}’定义的内容就是{$x},并不会转换为$x变量的值。
定界符字符串使用<<<作为起始标识,并定义一个名称,字符串的结束位置需要使用此名称。需要注意的是,结束标识必须位于独立代码行的顶格,不使用任何缩进。
定界符字符串实际上也有两种格式,分别对应双引号字符串和单引号字符串。首先介绍heredoc风格定界符字符串,它对应双引号字符串,如下面的代码。
<?php
$s=<<<STR1
<pre>
int x=10;
int y=99;
int sum=x+y;
</pre>
STR1;
echo $s;
?>
本例中定义的字符串标识为STR1,字符串内容保存在$s变量,其中包含了一个pre元素,定义了三行C语言代码,代码执行结果见图3-9。
图 3-9
为了与PHP 5.3中新增的nowdoc风格定界符字符串区分,在定义heredoc风格的字符串时,可以在标识名中使用双引号,如下面的代码。
<?php
$s = <<<"STR1"
...
STR1;
echo $s;
?>
nowdoc风格字符串名称需要使用一对单引号定义,其应用特点对应了单引号定义的字符串。下面的代码演示了nowdoc和heredoc风格字符串的区别。
<?php
$x=10;
$s1 = <<<"STR1"
{$x}
STR1;
$s2 = <<<'STR2'
{$x}
STR2;
echo $s1,"<br>",$s2;
?>
代码执行结果见图3-10,其中,STR1字符串中会将$x变量转换为实际的数据,而STR2字符串原样输出了{$x}。
图 3-10
需要将多个内容连接到一个字符串时,可以使用圆点(.)运算符,也称为串联运算符。下面的代码演示了圆点运算符的应用。
<?php
$s = "abc"."123";
echo $s;
?>
页面会显示abc123。
下面介绍一些常用的字符串操作函数。
chr()函数,返回ASCII编码对应的字符,如chr(65)返回大写字母A。
ord()函数,返回字符的ASCII编码,如ord("A")返回65。
trim()函数,删除字符串开始部分和结束部分的空白字符,包括空格、制表符等不可见字符。ltrim()函数删除字符串开始部分的空白字符。rtrim()和chop()函数删除字符串结束部分的空白字符。
比较字符串内容是否相等时,可以使用strcmp()或strcasecmp()函数。它们的区别在于,strcmp()函数按内容的二进制编码比较,strcasecmp()函数则不区分字母大小写。两个函数都需要两个参数,当参数一和参数二内容相同时返回0;参数一小于参数二时返回负数;参数一大于参数二时返回正数。下面的代码演示了这两个函数的使用。
<?php
$s1 = "Abc";
$s2 = "abc";
var_dump(strcmp($s1,$s2));
echo "<br>";
var_dump(strcasecmp($s1,$s2));
?>
代码执行结果见图3-11。
图 3-11
如果只需要比较两个字符串开始的一部分内容,可以使用strncmp($x,$y,$z)函数,其功能是比较$x和$y字符串的前$z个字符,当$x等于$y时返回0;$x小于当$y时返回负数;当$x大于$y时返回正数。如果不区分字母大小写,可以使用strncasecmp()函数。
strlen()函数用于获取字符串的字符数量,但字符串包含中文等双字节字符时,它的返回值并不是所期待的值,此时,需要使用mbstring库中的mb_strlen()函数,如下面的代码展示了这两个函数的使用。
<?php
$s = "学习PHP";
echo strlen($s),"<br>";
echo mb_strlen($s);
?>
使用strlen()函数时,一个汉字会按3个字节计算,这样两个汉字和三个字母共占用了9个字节。使用mb_strlen()函数时,可以对汉字和字符数量进行正确统计,如示例中的两个汉字和三个字母,共计5个字符。代码执行会显示9和5。
str_shuffle()函数将字符串中的字符随机排列,strrev()函数则将字符串中的字符顺序反转。下面的代码演示了这两个函数的使用。
<?php
$s = "abcdefg";
echo str_shuffle($s);
echo "<br>";
echo strrev($s);
?>
代码执行结果见图3-12。请注意,每次调用str_shuffle()函数的结果并不一样。
图 3-12
substr_count()函数可以计算指定内容在字符串中出现的次数,函数定义格式如下。
substr_count(string $s, string $n[, int $offset = 0[, int $length]]) : int
函数会计算$n在字符串$s中出现的次数;参数$offset指定从哪个字符开始统计,0表示第一个字符,1表示第二个字符,以此类推;参数$length指定处理的字符数。如果不使用$offset和$legnth参数指定计算的范围,将搜索$s的全部内容。下面的代码演示了substr_count()函数的应用。
<?php
$s = "abcdefgabcdabc";
echo substr_count($s,"ab"),"<br>";
echo substr_count($s,"abc",1);
?>
代码执行会显示3和2。
需要将数据按指定格式输出时可以使用sprintf()函数,其定义如下。
sprintf(string $format[, mixed $...]) : string
其中,第一个参数$format为带有格式的字符串,第二个参数开始按顺序指定需要格式化的数据。在参数$format中指定格式时,需要使用%符号指定格式,如:
● %b,二进制数据。
● %c,ASCII编码对应的字符。
● %d,有符号实数。
● %e,科学记数法,e小写。使用大写E时,科学记数法中的E大写。
● %f或F,显示为浮点数。
● %g、%e和%f的组合,格式较短。大写G表示%E和%f组合的较短格式。
● %o,八进制数据。
● %s,字符串数据。
● %u,无符号实数。
● %x,十六进制数,字母小写。
● %X,十六进制数,字母大写。
● %%,显示一个%符号。
下面的代码中整数将以十六进制形式显示,其中的字母大写。
<?php
echo sprintf("%X,%X",252,253);
?>
执行代码会显示FC,FD。
str_pad()函数可以使用指定的内容将字符串填充到指定的长度,函数定义如下。
str_pad(string $input, int $pad_length[, string $pad_string = " "[, int $pad_ type = STR_PAD_RIGHT]]) : string
函数的功能是,将$input使用$pad_string填充到$pad_length个字符。$pad_type指定填充位置,默认为右填充(STR_PAD_RIGHT),使用左填充时可以设置为STR_PAD_LEFT值,两端填充可以使用STR_PAD_BOTH值。
下面的代码演示了str_pad()函数的使用。
<?php
$s = "abcd";
echo str_pad($s,8,"*"),"<br>";
echo str_pad($s,8,"*",STR_PAD_BOTH),"<br>";
echo str_pad($s,8,"*",STR_PAD_LEFT);
?>
代码执行结果见图3-13。
图 3-13
number_format()函数用于格式化数字,并返回格式化之后的字符串,函数定义如下。
number_format( float $number, int $decimals = 0, string $dec_point = ".", string $thousands_sep = ",") : string
函数会返回数字$number的千分位分隔符形式,参数$decimals指定保留的小数位,默认为0;参数$dec_point指定小数分隔符,默认为圆点(.);参数$thousands_sep指定千分位分隔符,默认为逗号(,)。实际应用时,此函数的参数应为1个、2个或4个。下面的代码演示了number_format()函数的应用。
<?php
$n = 123456.789;
echo number_format($n),"<br>";
echo number_format($n,2),"<br>";
echo number_format($n,4,",",".");
?>
代码执行结果见图3-14。
图 3-14
第一个和第二个输出使用逗号作为千分位分隔符,圆点作为小数分隔符,是中国、美国等国家和地区的习惯用法;第三个输出使用逗号为小数分隔符,圆点为千分位分隔符,这是德国的数字书写方式,此外,法国的数字也使用逗号作为小数分隔符,而千分位分隔符则使用空格。
下面是几个关于字符大小写转换的函数。
● lcfirst()函数,字符串的首字母小写。
● ucfirst()函数,字符串的首字母大写。
● ucwords()函数,字符串中每个单词的首字母大写。
● strtolower()函数,字符串中所有字母小写。
● strtoupper()函数,字符串中所有字母大写。
下面的代码演示了这几个函数的应用。
<?php
$s = "I am learning PHP.";
echo lcfirst($s),"<br>";
echo ucfirst($s),"<br>";
echo ucwords($s),"<br>";
echo strtolower($s),"<br>";
echo strtoupper($s);
?>
代码执行结果见图3-15。
图 3-15
substr()函数用于截取字符串的一部分,函数定义如下。
substr(string $string, int $start[, int $length]) : string
函数的功能是在$string中从$start索引位置(从0开始的整数)截取$length个字符,如果达不到$length个字符,则返回从$start开始的所有内容。下面的代码演示了substr()函数的基本应用。
<?php
$s = "abcdefg";
echo substr($s,1,3);
?>
执行代码会显示bcd。此外,substr()函数还有一些灵活的用法,例如,将$start参数设置为负数时,可以得到字符串末尾的n个字符(n为$start参数的绝对值)。
<?php
$s = "abcdefg";
echo substr($s,-3);
?>
执行代码会显示efg。
如果substr()函数的$length参数为负数,截取内容不包含末尾的n个字符(n为$length的绝对值),如下面的代码。
<?php
$s = "abcdefg";
echo substr($s,1,-3);
?>
执行代码会显示bcd。
str_replace()函数,用于替换字符串中的指定内容,函数定义如下。
str_replace(mixed $search, mixed $replace, mixed $subject[, int &$count]) : mixed
函数的功能是在$subject字符串中,将$search指定的内容替换为$replace;$count为可选,用于指定替换的次数,如果不指定$count参数则搜索全部内容。请注意,$search可以指定一个字符串,其中可以包含%通配符,也可以指定为一个包含需要替换内容的数组。
下面先来看一下简单的示例。
<?php
$s = "abcdefgabcdabc";
echo str_replace("abc","***",$s);
?>
代码中会将$s字符串中的所有abc替换为***,代码执行后显示“***defg***d***”。
下面的代码会将$s中的b和d字母替换为*符号。
<?php
$s = "abcdefgabcdabc";
echo str_replace(["b","d"],"*",$s);
?>
代码执行会显示“a*c*efga*c*a*c”。此外,str_ireplace()函数与str_replace()函数功能相同,只是会忽略字母的大小写形式。
str_repeat(string $input, int $multiplier )函数返回$multiplier个$input组成的字符串,如str_repeat("*",3)返回"***”。
strstr()和strchr()函数查找并返回字符串,忽略字母大小写时可以使用stristr()函数。strstr()函数定义如下。
strstr(string $haystack, mixed $needle[, bool $before_needle = false]) : string
函数中,如果$haystack中包含$needle,则返回第一次出现位置开始的所有内容;如果$before_needle设置为true,则返回第一次出现位置以前的内容。下面的代码演示了strstr()函数的使用。
<?php
$s1 = "abcdefg";
$s2 = "cd";
echo strstr($s1,$s2);
echo "<br>";
echo strstr($s1,$s2,true);
?>
代码执行结果见图3-16。
图 3-16
strrchr()函数定义如下。
strrchr(string $haystack, mixed $needle) : string
函数的功能是在$haystack中查找$needle并返回从$needle最后一次出现位置开始的所有内容。下面的代码展示了strrchr()函数的使用。
<?php
$s1 = "abdefgabc";
$s2 = "ab";
echo strrchr($s1,$s2);
?>
执行代码会显示abc(最后三个字符)。
strpos()函数用于在字符串中查找内容,并返回出现的位置,函数定义如下。
strpos(string $haystack, mixed $needle[, int $offset = 0]) : int
函数的功能是在$haystack中查找$needle,并返回第一次出现的索引位置(从0开始)。参数$offset为可选参数,指定开始查询的索引值,默认为0,即从第一个字符开始查找;如果$offset为负数,只查询$haystack中的末尾的n个字符(n为$offset的绝对值)。下面的代码演示了strpos()函数的使用。
<?php
$s1 = "abcdefgabc";
$s2 = "cde";
var_dump(strpos($s1,$s2));
echo "<br>";
var_dump(strpos($s1,$s2,-5));
?>
代码执行结果见图3-17。
图 3-17
本例中,第一次调用strpos()函数时,从头开始查找cde,它位于第3个字符(索引值为2的位置),返回结果为整数数值2。第二次调用strpos()函数时,会从字符串的后5个字符中查询cde,它并不存在,此时返回结果为false。实际应用中,判断是否查询到需要的内容时,可以先使用全等运算符(===)进行判断,如下面的代码。
strrpos()函数用于查询指定内容在字符串中最后一次出现的位置,它的功能与strpos()函数相似,只是操作的顺序相反,如果$offset参数指定为负数,将在字符串开始的n个字符中查询(n为$offset的绝对值)。下面的代码演示了strrpos()函数的使用。
<?php
$s1 = "abcdefgabc";
$s2 = "ab";
var_dump(strrpos($s1,$s2));
echo "<br>";
var_dump(strrpos($s1,$s2,-5));
?>
代码执行结果见图3-18。
图 3-18
strpos()和strrpos()函数在查询字符时会区分字母大小写,如果不需要区分字母大小写形式,可以使用stripos()和strripos()函数。
strpbrk()函数,在字符串中查找指定的字符,并返回第一个匹配字符开始的所有内容,其定义如下。
strpbrk(string $haystack, string $char_list) : string
下面的代码演示了strpbrk()函数的使用。
<?php
$s = "I am learning PHP.";
echo strpbrk($s,"anH"),"<br>";
echo strpbrk($s,"iI");
?>
代码执行结果见图3-19。
图 3-19
strpbrk()函数只要找到$char_list中的任意字符就会立即返回执行结果。本例第一个输出找到了小写字母a后返回从第二个字符开始的所有内容;第二个输出找到大写字母I后返回了字符串的全部内容。
strtr()函数,使用指定的内容替换查询内容,并返回替换后的结果,函数定义如下。
strtr(string $str, string $from, string $to) : string
函数会将$str中的$from替换为$to,下面的代码演示了此函数的使用。
<?php
$s = "abcdefgabcdabef";
echo strtr($s,"ab","**");
?>
代码执行结果见图3-20。
图 3-20
substr_replace()函数,替换字符串指定位置的内容,函数定义如下。
substr_replace(mixed $s, mixed $r, mixed $start[, mixed $length]) : mixed
函数的功能是在$s中将$start开始的$length个字符替换为$r,如果不指定$length参数,会将$start位置开始的全部内容替换为$r,下面的代码演示了substr_replace()函数的应用。
<?php
$s = "abcdefg";
echo substr_replace($s,"***",2,3),"<br>";
echo substr_replace($s,"***",2);
?>
代码执行结果见图3-21。
图 3-21
explode()函数,用于分割字符串,并返回分割内容组成的数组,函数定义如下。
explode( string $delimiter, string $string[, int $limit] ) : array
函数的功能是使用$delimiter分割$string字符串,并返回分割后的数组。参数$limit为可选,如果不设置将完全分割$string,如果设置了$limit参数,返回的数组成员数量最多是$limit个。下面的代码演示了explode()函数的使用。
<?php
$s = "abc,def,ghi";
$arr1 = explode(",",$s);
print_r($arr1);
echo "<br>";
$arr2 = explode(",",$s,2);
print_r($arr2);
?>
代码执行结果见图3-22。
图 3-22
本例中,$arr1包含了三个成员,包括使用逗号分割$s字符串的所有内容;$arr2只包含了2个成员,这是由explode()函数的$limit参数确定的。稍后会详细讨论数组的应用。
join()和implode()函数,将一维数组的值连接成为字符串,其中,参数一指定连接分隔符,如果不指定分隔符,将直接连接;参数二为需要连接的数组。下面的代码演示了join()函数的应用。
<?php
$arr = array("abc","def","ghi");
echo join(";",$arr),"<br>";
echo join($arr);
?>
代码执行结果见图3-23。
图 3-23
str_split()函数用于按字符数量对字符串进行分组,函数定义如下。
str_split( string $string[, int $split_length = 1] ) : array
函数的功能是将$string分割为数组,每个成员的字符数由$split_length参数指定,默认为1。如下面的代码。
<?php
$s = "abcdefg";
echo "<h3>操作1</h3>";
print_r(str_split($s));
echo "<h3>操作2</h3>";
print_r(str_split($s,3));
?>
代码执行结果见图3-24。
图 3-24
本例中,第一次分割操作,每个成员有一个字符,所以数组有7个成员;第二次分割操作,每个成员指定为3字符,数组有3个成员。应用中,如果字符总数不能被每组数量整除,最后一个成员的字符数会少于$split_length参数指定的数量,如上例中的第二次分割操作。
wordwrap()函数,使用指定的内容和宽度分割字符串,函数定义如下。
wordwrap(string $str[, int $width = 75[, string $break = "\n"[, bool $cut = false]]] ) : string
函数的功能是将$str字符串进行分割,参数$width指定每部分期待的宽度,参数$break指定分割后每部分添加的内容。参数$cut设置为false时不会打断单词,如果指定为true则单词可能被分割。下面的代码演示了wordwrap()函数的应用。
<?php
$s = "I am learning PHP.";
echo wordwrap($s,10,"<br>");
?>
代码执行结果见图3-25(a),在浏览器中查看源代码内容见图3-25(b)。
图 3-25
当wordwrap()函数的第四个参数设置为true时,较长的单词可能被分割,如下面的代码。
<?php
$s = "I am learniiiiiiiiiiiiiing PHP.";
echo wordwrap($s,10,"<br>",true);
?>
代码执行结果见图3-26(a),生成的代码见图3-26(b)。
图 3-26
另一个与分割操作相关的是chunk_split()函数,定义如下。
chunk_split(string $body[, int $chunklen = 76[, string $end = "\r\n"]] ) : string
此函数在将BASE64编码字符串转换为符合RFC2045标准的字符串时非常有用。其中,$body指定源字符串,$chunklen指定每块的字符串,$end指定每块后添加的内容。函数会返回重新组合后的字符串。
GUID(Globally Unique Identifier,全局唯一标识符)和UUID(Universally Unique Identifier,通用唯一识别码),可以通过一定的算法获取唯一的标识,常用于给资源赋予唯一ID时。
下面的代码(/lib/cf/cf.php)定义了cf_get_guid()函数,它的功能是创建一个只包含字母和数字的GUID字符串,$isLower参数指定返回字符串中的字母大小写形式,默认为小写。
每次执行代码显示的内容都不同,但都是一个包含小写字母的GUID字符串和一个包含大写字母的GUID字符串,见图3-27。
图 3-27
在/lib/cf/tStr.php文件定义的tStr类中,getGuid()静态方法封装了同样的功能,开发中,可以参考如下代码生成GUID。
<?php
require_once $_SERVER["DOCUMENT_ROOT"]."/lib/cf/tStr.php";
use cf\tStr;
echo tStr::getGuid();
?>
关于UUID的生成,PHP官方网站提供了相应的代码,这里整理了一下,并封装在/lib/cf/cf.php文件的cf_get_uuid_v4()函数中,如下面的代码。
此外,UUID生成代码同时封装为/lib/cf/tStr.php文件中tStr类的getUuidV4()静态方法。
tStr类中的getUuidV4()静态方法用于返回v4版本UUID,返回结果是只包含字母和数字的UUID字符串,其中,字母为小写形式。开发中,可以参考如下代码生成UUID。
<?php
require_once $_SERVER["DOCUMENT_ROOT"]."/lib/cf/tStr.php";
use cf\tStr;
echo tStr::getUuidV4();
?>
hash()函数可以实现文本的多种散列算法,函数定义如下。
hash(string $algo, string $data[, bool $raw_output = false]) : string
参数包括:
● $algo,必选参数,指定算法名称,如"md5"、"sha256"等。
● $data,必选参数,指定需要编码的文本内容。
● $raw_output,可选参数,默认值为false,返回小写十六进制字符串,设置为true时返回原始二进制数据。
下面的代码演示了hash()函数的使用。
<?php
echo hash("sha256","123456");
?>
图3-28中显示了字符串“123456”的SHA-256编码内容,其中的字母使用了小写形式。
图 3-28
对于需要加密存储的内容,如密码,可以使用hash()函数很方便地转换为散列代码。需要注意的是,这些算法生成的结果是不可逆的,即不能还原文本的原始内容,所以只能对需要比较的内容转码后再判断是否一致。
此外,还有一些具体算法的函数,如:
● md5()函数,返回字符串的MD5散列编码。
● sha1()函数,返回字符串的SHA-1散列编码。
PHP 8中新增了一些字符串操作函数,下面分别介绍。
str_contains()函数,用于判断一个字符串中是否包含指定的内容,定义如下。
str_contains(string $haystack, string $needle): bool
如果$haystack中包含$needle,函数返回true,否则返回false。
str_starts_with()函数,用于判断字符串是否以指定的内容开始,定义如下。
str_starts_with(string $haystack, string $needle): bool
当$haystack的内容以$needle开始时,函数返回true,否则返回false。
str_ends_with()函数,用于判断字符串是否以指定的内容结束,定义如下。
str_ends_with(string $haystack, string $needle): bool
当$haystack的内容以$needle结束时,函数返回true,否则返回false。