【PHP小课堂】学习PHP中的字符串操作函数(二)

学习PHP中的字符串操作函数(二)

接下来我们继续 PHP 中字符串函数的学习。今天学习的内容主要是带下划线的一些字符串函数,上篇文章说过,这些系统函数的命名是 PHP 非常令人诟病的,有些东西真的只能靠我们的记忆来强行记住,并没有什么特别的规律可循。

字符串替换

首先还是我们的字符串替换,这个函数应该也是我们字符串操作中使用频率最高的函数之一。

$str = "abcdefGHIjklMnOpQRSTUVWXYZabcdefGHIjklMnOpQRSTUVWXYZ";
$strC = "测试中文数据";echo str_replace('abc', 'cba', $str, $count), PHP_EOL; // cbadefGHIjklMnOpQRSTUVWXYZcbadefGHIjklMnOpQRSTUVWXYZ
echo $count, PHP_EOL; // 2echo str_replace('fgh', 'hgf', $str), PHP_EOL; // abcdefGHIjklMnOpQRSTUVWXYZabcdefGHIjklMnOpQRSTUVWXYZ
echo str_ireplace('fgh', 'hgf', $str), PHP_EOL; // abcdehgfIjklMnOpQRSTUVWXYZabcdehgfIjklMnOpQRSTUVWXYZ

这个函数没有什么多说的,第四个参数可能接触到的同学比较少,它返回的是原文中被替换的次数。另外一个 str_ireplace() 是忽略大小写的替换,从下面两行测试代码中就可以看出,fGH 可以直接被我们的小写的 fgh 给替换掉。

补齐、重复字符

补齐字符串,就是在字符串的前后来补上一些字符。

echo str_pad('abc', 10), PHP_EOL; // abc       
echo str_pad('abc', 10, '-=', STR_PAD_LEFT), PHP_EOL; // -=-=-=-abc
echo str_pad('abc', 10, '|', STR_PAD_BOTH), PHP_EOL; // |||abc||||
echo str_pad('abc',  4, "*"), PHP_EOL; // abc*
echo str_pad('abc',  2, "*"), PHP_EOL; // abc

如果不给第三个参数的话,默认就是补上空格,另外第四个参数指的是从哪边开始补,默认情况下也是从右边,我们可以设置它为从左边或者从两边。这里需要注意的是,我们在第二个参数填入的字符数量是按整个字符串的数量来规划的,比如最后两条测试代码。如果给定的字符数量是小于原始的字符数量的,那么就不会对这个字符串进行任何操作了。

重复一段字符串内容就比较简单了。

echo str_repeat('abc', 5), PHP_EOL; // abcabcabcabcabc

str_repeat() 根据指定的数量来重复字符串的内容。

其它操作

相对来说,下划线相关的字符串操作函数的功能都比较简单,我们继续看其它的一些操作函数。

分割 csv 格式

print_r(str_getcsv("a,b,c,d"));
// Array
// (
//     [0] => a
//     [1] => b
//     [2] => c
//     [3] => d
// )

fgetcsv() 是直接从文件中读取,而 str_getcsv() 是针对于字符串的格式化读取 csv 数据的函数。它后面也有可选的参数,可以指定我们的分隔符号,默认情况下都是以逗号进行分隔的。

偏移字符串

在某些加密算法中,会有一种偏移字符的加密方式,比如我们将正常的字符向后或者向前偏移多少位,像是 a ,在密文中表示为 c ,其实就是让所有的字母向后偏移两位。在 PHP 中,直接提供了一个这样的函数,不过它是固定偏移 13 位的。

echo str_rot13($str), PHP_EOL; // nopqrsTUVwxyZaBcDEFGHIJKLMnopqrsTUVwxyZaBcDEFGHIJKLM

大家可以想想它的应用场景,对于一些加密数据的打乱传输来说,这个功能也是非常有用的哦。

随机打乱字符串

就像 array_shuffle() 一样,字符串中也有这样的一个函数可以随机的对字符串中的内容进行重新排序组合。

echo str_shuffle($str), PHP_EOL; // jaYpZMWIYSbpRacMenQOSGTWTekHlZcdGVVkbOXdHlXUfQnURfIj

分割字符串

对于分割字符串来说,我们最常接触到的是 explode() 这种分割函数,这个函数我们将在后面学习。当然,这个函数的出镜频率也非常高,但是,它是需要一个分割符号的,也就是说,必须要有一个分割符号才能完成对字符串转数组的分割。而我们接下来学习的这个函数,则是根据指定的字符长度来分割的。

print_r(str_split($str, 5));
// Array
// (
//     [0] => abcde
//     [1] => fGHIj
//     [2] => klMnO
//     [3] => pQRST
//     [4] => UVWXY
//     [5] => Zabcd
//     [6] => efGHI
//     [7] => jklMn
//     [8] => OpQRS
//     [9] => TUVWX
//     [10] => YZ
// )

使用 str_split() 就可以将原始的字符串按第二个参数给定的长度分割成数组了。除了这个之外,还有一个函数也可以按照长度来分割,并且默认会在字符后面加上一些特殊的内容。

echo  chunk_split(base64_encode(str_repeat($str, 5)));
// YWJjZGVmR0hJamtsTW5PcFFSU1RVVldYWVphYmNkZWZHSElqa2xNbk9wUVJTVFVWV1hZWmFiY2Rl
// ZkdISWprbE1uT3BRUlNUVVZXWFlaYWJjZGVmR0hJamtsTW5PcFFSU1RVVldYWVphYmNkZWZHSElq
// a2xNbk9wUVJTVFVWV1hZWmFiY2RlZkdISWprbE1uT3BRUlNUVVZXWFlaYWJjZGVmR0hJamtsTW5P
// cFFSU1RVVldYWVphYmNkZWZHSElqa2xNbk9wUVJTVFVWV1hZWmFiY2RlZkdISWprbE1uT3BRUlNU
// VVZXWFlaYWJjZGVmR0hJamtsTW5PcFFSU1RVVldYWVo=// chunk_split ( string $body , int $chunklen = 76 , string $end = "\r\n" ) : string

从注释中的函数签名可以看出,chunk_split() 函数还有两个默认参数,一个是长度默认为 76 个字符,另一个在每一段的结尾增加什么内容。注意,它返回的不是数组!!!是一个用最后那个 end 内容所分隔的字符串。

单词与单字数量

在很多搜索系统中,我们都会遇到过分词的问题,分词之后可能还要统计这个词出现的频率也就是词频,而对于英文来说,PHP 中直接就提供了这种类似的分词统计函数。毕竟英文本身就是以空格进行隔离单词的,所以它的实现比中文还是简单很多。

echo str_word_count('This is a test.'), PHP_EOL; // 4
print_r(str_word_count('This is a test.', 1));
// Array
// (
//     [0] => This
//     [1] => is
//     [2] => a
//     [3] => test
// )print_r(str_word_count('This is a test.', 2));
// Array
// (
//     [0] => This
//     [5] => is
//     [8] => a
//     [10] => test
// )

str_word_count() 默认情况下可以返回每个字符串中的单词数量。如果给定它的第二个参数为 1 的话,那么会将单词放到数组中返回,如果设置为 2 的话,数组的下标就是这个单词首次出现的位置。

print_r(count_chars('This is a test.', 1));
// Array
// (
//     [32] => 3
//     [46] => 1
//     [84] => 1
//     [97] => 1
//     [101] => 1
//     [104] => 1
//     [105] => 2
//     [115] => 3
//     [116] => 2
// )echo chr(84), PHP_EOL; // T
echo ord('a'), PHP_EOL; // 97

count_chars() 这个函数返回的则是每个字母出现的次数,注意它返回的数组下标对应的是 asc2 码中对应的值。我们可以使用 chr() 查看这个 asc2 码对应的字母是什么,同样,使用 ord() 可以获取一个字母的 asc2 码值。

编码转义

接下来,我们再来学习几个编码转义相关的内容。这一块基本上都是和系统安全相关的内容。对于一个现代化的应用项目来说,用户提交的内容是必不可少的,只要有用户输入,那么必然就会带来各种安全风险问题。不管是 SQL 注入,还是 XSS 攻击之类的,都和字符串的过滤转义有很大的关系。

特殊符号转义

这里的特殊符号其实主要就是指的是针对 SQL 注入而言的内容,也就是我们在早期经常会使用的函数。为什么说是早期呢?我们先看代码。

// 转义字符
echo addslashes("It's my test."), PHP_EOL; // It\'s my test.
echo addcslashes("It's my test.", 'A..z'), PHP_EOL; // \I\t'\s \m\y \t\e\s\t.

addslashes() 这个函数老码农们都不会陌生,在之前配合 MySQL 扩展的时候经常会用到。但是注意,现在框架中已经很少使用了。毕竟现在都是以 PDO 为主了,我们应该尽量使用 PDO 或者 MySQLi 的预编译能力,而尽量少地去自己拼接 SQL 语句参数。当然,这也是符合潮流的,所以说,现在这个函数真的是比较少见到了。

addcslashes() 是 C 语言实现版本,它需要第二个参数,这个参数可以是范围值,就像我们测试代码中的一样,它就是指从 A 到 z 的所有内容都会转义,也就是添加上斜杠。

uu 编码

uu 编码可以看做是一种加密编码格式,可以将字符串转换成我们看不懂的一种编码形式,当然,它也是提供了反解函数的。

$uu = convert_uuencode($str);
echo $uu, PHP_EOL;
// M86)C9&5F1TA):FML36Y/<%%24U155E=865IA8F-D969'2$EJ:VQ-;D]P45)3
// '5%565UA96@``
// `echo convert_uudecode($uu), PHP_EOL; // abcdefGHIjklMnOpQRSTUVWXYZabcdefGHIjklMnOpQRSTUVWXYZ

HTML 实体编码

最后就是 HTML 实体编码的内容,它们可是预防 XSS 攻击的最有效的手段。

html = htmlspecialchars("<a href='test'>Test</a>");
echo $html, PHP_EOL; // &lt;a href='test'&gt;Test&lt;/a&gt;$html = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
echo $html, PHP_EOL; // &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;echo htmlspecialchars_decode($html), PHP_EOL; // <a href=&#039;test&#039;>Test</a>
echo htmlspecialchars_decode($html, ENT_QUOTES), PHP_EOL; // <a href='test'>Test</a>$html = htmlentities("<a href='test'>Test</a>");
echo $html, PHP_EOL; // &lt;a href='test'&gt;Test&lt;/a&gt;$html = htmlentities("<a href='test'>Test</a>", ENT_QUOTES);
echo $html, PHP_EOL; // &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;echo html_entity_decode($html), PHP_EOL; // <a href=&#039;test&#039;>Test</a>
echo html_entity_decode($html, ENT_QUOTES), PHP_EOL; // <a href='test'>Test</a>

只要学过一点 PHP 的都知道它们的作用,就是将 < 、& 这些 HTML 中的特殊符号转换成 &xxxx; 这种形式的文本内容。这样,HTML 代码就不会在浏览器中直接运行了。htmlspecialchars() 和 htmlentities() 的功能其实都差不多,只是 htmlentities() 支持的内容更多一些,这个一会我们再讲。它们都有一个可选参数,这里我们设置为了 ENT_QUOTES ,表示的是单引号也编码。关于这个参数的可选常量还有很多,大家可以去官方文档中查阅。

如果设置了这个参数的话,那么使用对应的 htmlspecialchars_decode() 和 html_entity_decode() 进行反转义的时候,也要加上对应的参数常量。这里有个坑,注意 htmlentities() 的反转义函数的名字是 html_entity_decode() 这个哦,不是 htmlentities_decode() 。而 htmlspecialchars_decode() 却是真的只是给 htmlspecialchars() 后面加了个 _decode()。这个命名规范真的是无力吐糟。

网上有很多文章会说 htmlspecialchars() 和 htmlentities() 对于中文的编码会有不同,其实这也是比较老的问题了,在 PHP5.6 之后它们对中文的支持已经没有区别了。

// php5.6后中文没区别
echo htmlspecialchars("<a href='test'>测试</a>"), PHP_EOL;
echo htmlentities("<a href='test'>测试</a>"), PHP_EOL;

而它们两个现在最主的区别就是可以转义的字符范围了。

echo htmlspecialchars("<a href='test'>Ψ</a>"), PHP_EOL; // &lt;a href='test'&gt;Ψ&lt;/a&gt;
echo htmlentities("<a href='test'>Ψ</a>"), PHP_EOL; // &lt;a href='test'&gt;&Psi;&lt;/a&gt;

我们可以通过一个函数来查看它们所支持的编码字符。

print_r(get_html_translation_table(HTML_ENTITIES));
// Array
// (
//     ["] => &quot;
//     [&] => &amp;
//     [<] => &lt;
//     [>] => &gt;
//     [ ] => &nbsp;
//     [¡] => &iexcl;
//     [¢] => &cent;
//     [£] => &pound;
//     [¤] => &curren;
//     [¥] => &yen;
//     [¦] => &brvbar;
//     [§] => &sect;
//     [¨] => &uml;
//     [©] => &copy;
//     [ª] => &ordf;
//     [«] => &laquo;
//     [¬] => &not;
//     [­] => &shy;
//     [®] => &reg;
//     [¯] => &macr;
//     [°] => &deg;
//     [±] => &plusmn;
//     [²] => &sup2;
//     [³] => &sup3;
//     [´] => &acute;
//     [µ] => &micro;
//     [¶] => &para;
//     [·] => &middot;
//     [¸] => &cedil;
//     [¹] => &sup1;
//     [º] => &ordm;
//     [»] => &raquo;
//     [¼] => &frac14;
//     [½] => &frac12;
//     [¾] => &frac34;
//     [¿] => &iquest;
//     [À] => &Agrave;
//     [Á] => &Aacute;
//     …………………………
//     …………………………
//     …………………………print_r(get_html_translation_table(HTML_SPECIALCHARS));
// Array
// (
//     ["] => &quot;
//     [&] => &amp;
//     [<] => &lt;
//     [>] => &gt;
// )

其实在日常的开发过程中,直接使用 htmlspecialchars() 就够了,毕竟我们经常需要的,也是最重要的内容就是这四个。其中两个破折号更是影响安全的重中之重。

总结

今天学习的内容也还只是字符串操作函数中的一小部分,最主的就是 str_ 这些开头的函数。不过相对来说它们比 str 开头的函数还是要少一些。另外我们还学习了一点编码转义部分的内容,这些内容对于我们系统的安全来说非常重要,也是需要大家深入了解掌握的内容。下篇文章将学习的是剩下的一大堆函数名没什么规则的函数,继续加油吧!

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/2021/03/source/8.%E5%AD%A6%E4%B9%A0PHP%E4%B8%AD%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%93%8D%E4%BD%9C%E5%87%BD%E6%95%B0%EF%BC%88%E4%BA%8C%EF%BC%89.php

参考文档:

https://www.php.net/manual/zh/ref.strings.php

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/43160.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

显卡、显卡驱动、cuda、cuDNN之间关系

显卡、显卡驱动、CUDA 和 cuDNN 是构成高性能计算和深度学习环境的关键组件&#xff0c;它们之间有着紧密的联系。下面是对这些组件及其关系的详细介绍&#xff1a; 显卡&#xff08;GPU&#xff09; 显卡&#xff0c;全称为图形处理器&#xff08;Graphics Processing Unit&…

【Unity2D 2022:NPC】制作任务系统

一、接受任务 1. 编辑NPC对话脚本&#xff1a; &#xff08;1&#xff09;创建静态布尔变量用来判断ruby是否接受到任务 public class NPCDialog : MonoBehaviour {// 创建全局变量用来判断ruby是否接到任务public static bool receiveTask false; } &#xff08;2&#xff…

python学习-错误与异常

代码是人的逻辑思维的具体体现&#xff0c;因为没有一个人的逻辑思维是完美无缺的&#xff0c;所以人在编写代码时必然会出现各种错误。既然错误或多或少都会发生&#xff0c;那么如何捕捉错误&#xff0c;并且捕捉到错误后要如何处理&#xff0c;就显得很重要。 语法错误 Py…

SPI通信协议和W25Q64

前言&#xff1a; STM32中的通信接口&#xff1a; UART 单总线 IIC SPI CAN 1. SPI FLASH W25Q64的关系 SPI:一种通信接口&#xff0c;可以用于和搭载SPI接口的设备通信 FLASH:是一种掉电不丢失的存储 -- 手机8256G的256 单片机 64K512K的512 芯片内部flash&…

STM32 GPIO的工作原理

STM32的GPIO管脚有下面8种可能的配置:&#xff08;4输入 2 输出 2 复用输出) &#xff08;1&#xff09;浮空输入_IN_FLOATING 在上图上&#xff0c;阴影的部分处于不工作状态&#xff0c;尤其是下半部分的输出电路&#xff0c;实际上是与端口处于隔离状态。黄色的高亮部分显示…

响应式布局下关于gird栅格布局的一些构思

1、传列数&#xff0c;根据列数计算元素容器宽度 好处是子元素可以写百分比宽度&#xff0c;不用固定某一种宽度&#xff0c;反正知道列数通过计算间距就能得到外层容器的宽度。 举个简单的例子&#xff1a; &#xff08;ps:以下用例皆在html中去模拟&#xff0c;就不另外起r…

Python 获取 SQL 指纹和 HASH 值

前言 本文介绍一个提取 SQL 指纹的方法&#xff0c;就是将 SQL 语句的条件转换为 &#xff1f;可用于脱敏和 SQL 聚类分析的场景。 1. 工具安装 这里用到的工具&#xff0c;就是 pt 工具集中的 pt-fingerprint 含在 Percona Toolkit 中&#xff0c;安装方法可参考 Percona T…

python7:装饰器

目录 1.调用外部程序os.system-阻塞式调用subprocess-python中的模块 2.装饰器前戏作用域&#xff08;1&#xff09;全局和局部-就近原则&#xff08;2&#xff09;嵌套作用域&#xff08;3&#xff09;内置作用域、变量 高阶函数&#xff1a;函数是最高级的对象&#xff08;1&…

海外媒体投稿:5个软文代发经典案例,教大家获得突破

随着互联网的飞速发展&#xff0c;软文代发成为一种高效的推广方法。下面我们就详细介绍五个成功软文代发推广实例&#xff0c;致力于帮助读者把握有关方法&#xff0c;完成突破。 第一实例&#xff1a;社交网络散播在如今社交媒体时代&#xff0c;软文代发能够通过社交平台迅速…

nodejs实现:支付宝订单查询

nodejs实现&#xff1a;支付宝订单查询&#xff1b; 原生http请求&#xff0c;不使用三方库&#xff1b; 代码如下&#xff1a; const https require(https); const crypto require(crypto); const querystring require(querystring);// 支付宝公共参数 const PRIVATE_KE…

[C++] 轻熟类和对象

类的定义 格式规范 class为定义类的关键字&#xff0c;后有类名&#xff0c;类的主体存于{}中&#xff1b;类定义结束时后面的分号不能省略&#xff1b;类体的内容成为类的成员&#xff0c;类中的变量成为成员变量&#xff0c;函数成为方法或成员函数&#xff1b;C兼容C语言的…

微软 Edge 浏览器全解析

微软 Edge 是微软推出的一个现代化浏览器,继承了 Internet Explorer(IE)的部分功能,但在速度、安全性和兼容性方面做出了很大改进。下面是对微软 Edge 浏览器的详细解析,包括其特点、安装、配置和常见问题的解答。 微软 Edge 浏览器的特点 基于 Chromium 内核 Edge 浏览…

SpringBoot配置flyway

背景 目前我们的项目代码都会交由Git、SVN等版本管理工具进行管理&#xff0c;但是我们的sql脚本&#xff0c;尤其是各类ddl脚本并没有进行版本的管理&#xff08;python的web框架Django默认就提供了类似的工具&#xff0c;从一开始就鼓励开发者通过版本管理的方式进行数据库的…

C++中的多重继承和虚继承:横向继承、纵向继承和联合继承;虚继承

多重继承 A.横向多重继承&#xff1a; B.纵向多重继承&#xff1a; C.联合多重继承&#xff1a; 因为 single 和 waiter 都继承了一个 worker 组件&#xff0c;因此 SingingWaiter 将包含两个 worker 组件&#xff0c;那么将派生类对象的地址赋给基类指针将出现二义性 那么如何…

idea http client插件上传文件,并忽略https证书验证

上传文件 ### 传临时素材 图片 POST https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token{{access_token}}&typeimage Content-Type: multipart/form-data; boundary----WebKitFormBoundarywKUX3Xj6aL5Wssnb------WebKitFormBoundarywKUX3Xj6aL5Wssnb Conten…

从Helm到 Operator:Kubernetes应用管理的进化

&#x1f9f0;Helm 的作用 在开始前需要先对 kubernetes Operator 有个简单的认识。 以为我们在编写部署一些简单 Deployment 的时候只需要自己编写一个 yaml 文件然后 kubectl apply 即可。 apiVersion: apps/v1 kind: Deployment metadata: labels: app: k8s-combat …

去水印小程序源码修复版-前端后端内置接口+第三方接口

去水印小程序源码&#xff0c;前端后端&#xff0c;内置接口第三方接口&#xff0c; 修复数据库账号密码错误问题&#xff0c;内置接口支持替换第三方接口&#xff0c; 文件挺全的&#xff0c;可以添加流量主代码&#xff0c;搭建需要准备一台服务器&#xff0c;备案域名和http…

农牧行业CRM洞察:打造营、销、服一体化数字营销平台

01、行业应用背景 保持企业活力&#xff0c;支撑业务单元协调发展&#xff0c;稳定核心产品竞争力&#xff0c;将成为农牧行业企业数字化、数智化建设的指导方向。 积极发挥数据在生产、流通、消费各个环节的决策支撑&#xff0c;为农牧企业特别是多业态集团型企业&#xff0…

JVM:类的生命周期

文章目录 一、介绍二、加载阶段三、连接阶段1、验证阶段2、准备阶段3、解析阶段 四、初始化阶段 一、介绍 类的生命周期描述了一个类加载、连接&#xff08;验证、准备和解析&#xff09;、初始化、使用、卸载的整个过程。 二、加载阶段 加载&#xff08;Loading&#xff09…

全栈业务开发入门——登录业务接口

业务已上传则资源 实现登录业务的前后端联调&#xff0c;前端点击登录按钮向后端发送一个请求&#xff0c;后端调用接口向前端响应结果 效果如下&#xff1a; 设计环境&#xff1a;springbootmybatisvue3axios 一.前端设计 1.基于vue3脚手架创建项目&#xff0c;搭建项目结构…