购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.5 字符串

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。

3.5.1 格式化与转换

需要将数据按指定格式输出时可以使用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

3.5.2 查询、截取和替换

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

3.5.3 组合和分割

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指定每块后添加的内容。函数会返回重新组合后的字符串。

3.5.4 生成GUID和UUID

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();
    ?>

3.5.5 散列函数

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散列编码。

3.5.6 PHP 8新增函数

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。 htmWc72D7HlyMDstxM+PFqRPUUVpjYe1t47hRAat71BuJtK2/ovau644u9too6t9

点击中间区域
呼出菜单
上一章
目录
下一章
×