首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
184 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
32
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
560
篇与
的结果
2023-11-20
用yum方式安装php最新版
用yum方式安装php最新版采用在线安装的方式,安装php8.0版本,可自由查看版本并安装相关版本。用第三方软件源remi安装,因为对此源对php有非常好的支持。1 安装 epel-release源和 源管理工具yum-utils安装 epel-release源和 源管理工具yum-utilsyum -y install epel-release yum-utils2 安装Remi软件源Remi软件源官方地址: https://rpms.remirepo.net/找到自己的linux版本,我的是Centos8,为linux8,所有安装CentOS8安装:yum -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpmCentOS7安装:yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpm3 启用remi源php8.0模块,安装php及扩展注:这里貌似CentOS8要用另一个安装命令dnf启用,我用yum是不行的。CentOS8启动php模块并安装:dnf module list php #查看php可用模块和版本然后我们直接启用remi源里的remi-8.0模块,根据需要选择自己格式的版本,如remi-7.4模块。dnf module enable php:remi-8.0 -y然后直接命令安装默认为php8版本,及其他扩展dnf -y install php php-cli php php-fpm php-mysqlnd php-zip php-devel php-gd php-mbstring php-curl php-xml php-pear php-bcmath php-json php-redisCentOS7启动php模块并安装:yum启动php模块,根据需要选择自己格式的版本,如remi-php74模块,就是php7.4版本。:yum-config-manager --enable remi-php80 #启用remi源的php8.0模块注:如果显示没有这个命令,则需要先安装yum -y install yum-utils 插件。安装php及相关扩展:yum install php php-cli php-fpm php-mysqlnd php-zip php-devel php-gd php-mbstring php-curl php-xml php-pear php-bcmath php-json php-redis安装成功:php -v 查看版本为php8.0版本
2023年11月20日
60 阅读
0 评论
0 点赞
2023-10-13
《从菜鸟到大师之路 正则表达式 篇》
《从菜鸟到大师之路 正则表达式 篇》正则表达式是一个强大的文本匹配工具。但是,对于前端初学者来说,众多的符号和规则可能让人难以理解。其实,你不需要记住所有的正则表达式语法!本文将分享一些简单而实用的技巧,帮助理解正则表达式的核心概念,轻松使用正则表达式!一、基础入门概念正则表达式(Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。搜索模式可用于文本搜索和文本替换。它用一系列字符定义搜索模式。正则表达式的用途 有很多,比如:表单输入验证;搜索和替换;过滤大量文本文件(如日志)中的信息;读取配置文件;网页抓取;处理具有一致语法的文本文件,例如 CSV。创建正则表达式的语法如下:/正则表达式主体/修饰符(可选) 先来看一个最基本的正则表达式:/处/,它只匹配到了字符串中的第一个“处”:这里,正则表达式的主体就是“处”,没有使用修饰符,我们会在后面来介绍正则表达式的修饰符。创建正则表达式的方式有两种:字面量:正则表达式直接放在/ /之中:const rex = /pattern/;构造函数:RegExp 对象表示正则表达式的一个实例:const rex = new RegExp("pattern"); 这两种方法的一大区别是对象的构造函数允许传递带引号的表达式,通过这种方式就可以动态创建正则表达式。通过这两种方法创建出来的 Regex 对象都具有相同的方法和属性:let RegExp1 = /a|b/ let RegExp2 = new RegExp('a|b') console.log(RegExp1) // 输出结果:/a|b/ console.log(RegExp2) // 输出结果:/a|b/ RegExp 实例实例方法RegExp 实例置了test()和exec() 这两个方法来校验正则表达式。下面来分别看一下这两个方法。(1)test()test()用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。const regex1 = /a/ig; const regex2 = /hello/ig; const str = "Action speak louder than words"; console.log(regex1.test(str)); // true console.log(regex2.test(str)); // false (2)exec()exec()用于检索字符串中的正则表达式的匹配。该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。const regex1 = /a/ig; const regex2 = /hello/ig; const str = "Action speak louder than words"; console.log(regex1.exec(str)); // ['A', index: 0, input: 'Action speak louder than words', groups: undefined] console.log(regex2.exec(str)); // null 在当在全局正则表达式中使用 exec 时,每隔一次就会返回null,如图:这是怎么回事呢?MDN 的解释如下:在设置了 global 或 sticky 标志位的情况下(如 /foo/g or /foo/y),JavaScript RegExp 对象是有状态的。他们会将上次成功匹配后的位置记录在 lastIndex 属性中。使用此特性,exec() 可用来对单个字符串中的多次匹配结果进行逐条的遍历(包括捕获到的匹配),而相比之下, String.prototype.match() 只会返回匹配到的结果。为了解决这个问题,我们可以在运行每个exec命令之前将lastIndex赋值为 0:实例属性RegExp 实例还内置了一些属性,这些属性可以获知一个正则表达式的各方面的信息,但是用处不大。二、模式匹配关于正则表达式最复杂的地方就是如何编写正则规则了,下面就来看如何编写正则表达式。修饰符正则表达式的修饰符是一种可以在正则表达式模式中添加的标记,用于修改搜索模式的行为。这些修饰符通常以单个字符形式出现在正则表达式的末尾,并且可以通过在正则表达式模式前添加该字符来启用修饰符。常见的修饰符如下:g:表示全局模式,即运用于所有字符串;i:表示不区分大小写,即匹配时忽略字符串的大小写;m:表示多行模式,强制 $ 和 ^ 分别匹配每个换行符。最开始的例子中,字符串中有两个“处”,但是只匹配到了一个。这是因为正则表达式默认匹配第一个符合条件的字符。如果想要匹配所有符合条件的字符,就可以使用 g 修饰符:/处/g 这样就匹配到了所有符合条件的字符:当需要匹配引英文字符串,并且忽略字符串的字母大小写时,i 修饰符就派上用场了。先来看下面的表达式:/a/g 在进行匹配时,它匹配到了字符串中所有的 a 字符。但是最开始的 A 是没匹配到的,因为两者大小写不一致:那我们来添加上 i 修饰符:/a/gi 这时所有的 a 都被匹配到了,无论是大写还是小写,总共匹配到了三个 a:还有一个小疑问, 如果是对象构造函数的方式来构造正则表达式使,如何添加这些修饰符呢?其实很简单,只要将修饰符作为第二个参数传递给 构造函数就可以了:let regExp = new RegExp('[2b|^2b]', 'gi') console.log(regExp) // 输出结果:/[2b|^2b]/gi 字符集合如果我们想匹配 bat、cat 和 fat 这种类型的字符串该怎么办?可以通过使用字符集合来做到这一点,用 [] 表示,它会匹配包含的任意一个字符。这里就可以使用/[bcf]at/ig:可以看到,这里匹配到了字符串中的 bat、cat、fat。因为我们使用了 g 修饰符,所以匹配到了三个结果。当然,字符集也可以用来匹配数字:字符范围如果我们想要在字符串中匹配所有以 at 结尾的单词,最直接的方式是使用字符集,并在其中提供所有的字母。对于这种在一个范围中的字符, 就可以直接定义字符范围,用-表示。它用来匹配指定范围内的任意字符。这里就可以使用/[a-z]at/ig:可以看到,正则表达式按照我们的预期匹配了。常见的使用范围的方式如下:部分范围:[a-f],匹配 a 到 f 的任意字符;小写范围:[a-z],匹配 a 到 z 的任意字符;大写范围:[A-Z],匹配 A 到 Z 的任意字符;数字范围:[0-9],匹配 0 到 9 的任意字符;符号范围:[#$%&@];混合范围:[a-zA-Z0-9],匹配所有数字、大小写字母中的任意字符。数量字符如果想要匹配三个字母的单词,根据上面我们学到的字符范围,可以这样来写:[a-z][a-z][a-z] 这里我们匹配的三个字母的单词,那如果想要匹配10个、20个字母的单词呢?难道要一个个来写范围吗?有一种更好的方法就是使用花括号{}来表示,来看例子:可以看到,这里我们匹配到了所有连续5个字母的单词(包括超过5个字母的单词,不过只会匹配到前5个字母)。其实匹配重复字符的完整语法是这样的:{m,n},它会匹配前面一个字符至少 m 次至多 n 次重复,{m}表示匹配 m 次,{m,}表示至少 m 次。所以,当我们给5后面加上逗号时,就表示至少匹配五次:所以这里就匹配到了所有连续5个或5个以上的单词。当匹配次数为至少4次,至多5次时,匹配结果如下:除了可以使用大括号来匹配一定数量的字符,还有三个相关的模式:+:匹配前面一个表达式一次或者多次,相当于 {1,};*:匹配前面一个表达式0次或者多次,相当于 {0,};?:单独使用匹配前面一个表达式零次或者一次,相当于 {0,1},如果跟在量词*、+、?、后面的时候将会使量词变为非贪婪模式(尽量匹配少的字符),默认是使用贪婪模式。来看一个简单的例子,这里我们匹配的正则表达式为/a+/ig,结果如下:它和/a{1,}/ig的匹配结果是一样的:使用/[a-z]+/ig就可以匹配任意长度的纯字母单词:元字符使用元字符可以编写更紧凑的正则表达式模式。常见的元字符如下:\d:相当于[0-9],匹配任意数字;\D:相当于[^0-9];\w:相当于[0-9a-zA-Z],匹配任意数字、大小写字母和下划线;\W:相当于:[^0-9a-zA-Z];\s:相当于[\t\v\n\r\f],匹配任意空白符,包括空格,水平制表符\t,垂直制表符\v,换行符\n,回车符\r,换页符\f;\S:相当于[^\t\v\n\r\f],表示非空白符。来看一个简单的例子:这里使用\d来匹配任意数字、字母和下划线。这里就匹配到了7个连续四位的字符。特殊字符使用特殊字符可以编写更高级的模式表达式,常见的特殊字符如下:.:匹配除了换行符之外的任何单个字符;\:将下一个字符标记为特殊字符、或原义字符、或向后引用、或八进制转义符;|:逻辑或操作符;[^]:取非,匹配未包含的任意字符。来看一个简单的例子,如果我们使用 /ab*/ig 进行匹配,结果就如下:那我们就是想要匹配 * 怎么办?就可以使用 \ 对其进行转义:这样就只会匹配到 ab* 了。或匹配也很简单,来看例子,匹配规则为:/ab|cd/ig,匹配结果如下:这里就会匹配到字符串中所有 ab 和 cd 字符。那如果想要匹配 sabz 或者scdz呢?开头和结尾是相同的,只有中间的两个字符是可选的。其实只需要给中间的或部分加上括号就可以了:取非规则在范围中使用,来看例子:这里匹配到了所有非字母的字符。位置匹配如果我们想匹配字符串中以某些字符结尾的单词,以某些字符开头的单词该如何实现呢?正则表达式中提供了方法通过位置来匹配字符:\b:匹配一个单词边界,也就是指单词和空格间的位置;\B:匹配非单词边界;^:匹配开头,在多行匹配中匹配行开头;$:匹配结尾,在多行匹配中匹配行结尾;(?=p):匹配 p 前面的位置;(?!=p):匹配不是 p 前面的位置。最常见的就是匹配开始和结束位置。先来看一个开始位置的匹配,这里使用 /^ex/igm 来匹配多行中以ex 开头的行:使用/e$/igm来匹配以 e 结尾的行:可以使用 \w+$ 来匹配每一行的最后一个单词:需要注意,这里我们都使用 m 修饰符开启了多行模式。使用 /(?=the)/ig 来匹配字符串中the前的面的位置:我们可以使用\b来匹配单词的边界,匹配的结果如下:这可能比较难理解,我们可以使用以下正则表达式来匹配完整的单词:\b\w+\b,匹配结果如下:捕获组正则表达式中的“捕获组”是指使用括号 () 将子模式括起来,以便于在搜索时同时匹配多个项或将匹配的内容单独提取出来。组可以根据需要进行嵌套,形成复杂的匹配模式。使用捕获组,可以直接在正则表达式 /(Testing|tests) 123/ig 中匹配到 "Testing 123" 和 "Tests 123",而不需要重复写 "123" 的匹配项。正则表达式中的两种常见组类型:(...):捕获组,用于匹配任意三个字符。(?:...):非捕获组,也是用于匹配任意三个字符,但不进行捕获。可以使用以下 JavaScript 将文本替换为Testing 234和tests 234:const regex = /(Testing|tests) 123/ig; let str = ` Testing 123 Tests 123 `; str = str.replace(regex, '$1 234'); console.log(str); // Testing 234 // Tests 234 被括号包围的子模式称为“捕获组”,捕获组可以从匹配的字符串中提取出指定的部分并单独使用。这里我们使用 $1 来引用第一个捕获组 (Testing|tests)。也可以匹配多个组,比如同时匹配 (Testing|tests) 和 (123)。const regex = /(Testing|tests) (123)/ig; let str = ` Testing 123 Tests 123 `; str = str.replace(regex, '$1 #$2'); console.log(str); // Testing #123 // Tests #123" 这只适用于捕获组。如果把上面的正则表达式变成这样:/(?:Testing|tests) (123)/ig; 那么只有一个被捕获的组:(123),与之前相同的代码将输出不同的结果:const regex = /(?:Testing|tests) (123)/ig; let str = ` Testing 123 Tests 123 `; str = str.replace(regex, '$1'); console.log(str); // 123 // 123 修改后的正则表达式只有一个捕获组 (123)。因为 (?: ) 的语法用于创建非捕获组,所以它不会将其内容作为一个捕获组来使用。命名捕获组虽然捕获组非常有用,但是当有很多捕获组时很容易让人困惑。$3 和 $5 这些名字并不是一目了然的。为了解决这个问题,正则表达式引入了“命名捕获组”的概念。例如,(?<name>...) 就是一个命名捕获组,名为 "name",用于匹配任意三个字符。可以像这样在正则表达式中使用它来创建一个名为 "num" 的组,用于匹配三个数字:/Testing (?<num>\d{3})/ 然后,可以在替换操作中像这样使用它:const regex = /Testing (?<num>\d{3})/ let str = "Testing 123"; str = str.replace(regex, "Hello $<num>") console.log(str); // "Hello 123" 命名反向引用有时候需要在查询字符串中引用一个命名捕获组,这就是“反向引用”的用武之地。假设有一个字符串,其中包含多个单词,我们想要找到所有出现两次或以上的单词。可以使用具名捕获组和命名反向引用来实现。const regex = /\b(?<word>\w+)\b(?=.*?\b\k<word>\b)/g; const str = 'I like to eat pizza, but I do not like to eat sushi.'; const result = str.match(regex); console.log(result); // like 这里使用了具名捕获组 (?<word>\w+)来匹配单词,并将其命名为 "word"。然后使用命名反向引用 (?=.*?\b\k<word>\b) 来查找文本中是否存在具有相同内容的单词。前瞻组和后顾组前瞻组(Lookahead)和后顾组(Lookbehind)是正则表达式中非常有用的工具,它们用于在匹配过程中进行条件约束,而不会实际匹配这些约束的内容。它们使得我们可以更精确地指定匹配模式。前瞻组:正向前瞻((?=...)):用于查找在某个位置后面存在的内容。例如,A(?=B) 可以匹配 "A",但只有在后面跟着 "B" 时才进行匹配。负向前瞻((?!...)):用于查找在某个位置后面不存在的内容。例如,A(?!B) 可以匹配 "A",但只有在后面不跟着 "B" 时才进行匹配。后顾组:正向后顾((?<=...)):用于查找在某个位置前面存在的内容。例如,(?<=A)B 可以匹配 "B",但只有在其前面跟着 "A" 时才进行匹配。负向后顾((?<!...)):用于查找在某个位置前面不存在的内容。例如,(?<!A)B 可以匹配 "B",但只有在其前面不跟着 "A" 时才进行匹配。这些前瞻组和后顾组可以用于各种场景,例如:在匹配邮箱地址时,使用正向前瞻来确保地址的结尾是以特定的域名结尾。在匹配密码时,使用正向前瞻来确保密码满足特定的复杂度要求。在提取文本中的日期时,使用正向后顾来确保日期的前面有特定的前缀。例如,使用负向前瞻可以匹配 BC,但不会匹配 BA。/B(?!A)/ 我们甚至可以将负向前瞻组合使用,并使用 ^ 和 $ 这些元字符来尝试匹配完整的字符串。例如,以下的正则表达式将匹配任何不以 "Test" 开头的字符串:/^(?!Test).*$/gm 这个正则表达式可以匹配 Hello 和 Other,但无法匹配 Testing 123 和 Tests 123。同样,可以将其切换为正向前瞻,以强制字符串必须以“Test”开头:/^(?=Test).*$/gm 三、字符串方法在 JavaScript 内置了 6 个常用的方法是支持正则表达式的,下面来分别看看这些方法。search()search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。如果没有找到任何匹配的子串,则返回 -1。const regex1 = /a/ig; const regex2 = /p/ig; const regex3 = /m/ig; const str = "Action speak louder than words"; console.log(str.search(regex1)); // 输出结果:0 console.log(str.search(regex2)); // 输出结果:8 console.log(str.search(regex3)); // 输出结果:-1 可以看到,search() 方法只会返回匹配到的第一个字符的索引值,当没有匹配到相应的值时,就会返回-1。match()match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。const regex1 = /a/ig; const regex2 = /a/i; const regex3 = /m/ig; const str = "Action speak louder than words"; console.log(str.match(regex1)); // 输出结果:['A', 'a', 'a'] console.log(str.match(regex2)); // 输出结果:['A', index: 0, input: 'Action speak louder than words', groups: undefined] console.log(str.match(regex3)); // 输出结果:null 可以看到,当没有 g 修饰符时,就只能在字符串中执行一次匹配,如果想要匹配所有符合条件的值,就需要添加 g 修饰符。matchAll()matchAll() 方法返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。因为返回的是遍历器,所以通常使用for...of循环取出。for (const match of 'abcabc'.matchAll(/a/g)) { console.log(match) } //["a", index: 0, input: "abcabc", groups: undefined] //["a", index: 3, input: "abcabc", groups: undefined] 需要注意,该方法的第一个参数是一个正则表达式对象,如果传的参数不是一个正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个 RegExp 。另外,RegExp必须是设置了全局模式g的形式,否则会抛出异常 TypeError。replace()replace() 用于在字符串中用一些字符串替换另一些字符串,或替换一个与正则表达式匹配的子串。const regex = /A/g; const str = "Action speak louder than words"; console.log(str.replace(regex, 'a')); // 输出结果:action speak louder than words 可以看到,第一个参数中的正则表达式匹配到了字符串的第一个大写的 A,并将其替换为了第二个参数中的小写的 a。replaceAll()replaceAll() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串,该函数会替换所有匹配到的子字符串。const regex = /a/g; const str = "Action speak louder than words"; console.log(str.replaceAll(regex, 'A')); // 输出结果:Action speAk louder thAn words 需要注意,当使用一个 regex 时,您必须设置全局("g")标志, 否则,它将引发 TypeError:"必须使用全局 RegExp 调用 replaceAll"。split()split() 方法用于把一个字符串分割成字符串数组。其第一个参数是一个字符串或正则表达式,从该参数指定的地方分割字符串。const regex = / /gi; const str = "Action speak louder than words"; console.log(str.split(regex)); // 输出结果:['Action', 'speak', 'louder', 'than', 'words'] 这里的 regex 用来匹配空字符串,所以最终在字符串的每个空格处将字符串拆成了数组。四、应用场景上面介绍了正则表达式的用法,下面就来看看正则表达式的实际应用场景。数据验证数据验证应该是正则表达式最常见的场景了,经常用于用户的输入是否符合所需的条件。数据验证可确保输入或导入的数据准确、一致,并符合预定义的规则。验证手机号:const phoneNumber = "13712345678"; const regex = /^1[3-9]\d{9}$/; console.log("手机号格式正确:", regex.test(phoneNumber)); 验证邮箱:const email = "example@example.com"; const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; console.log("电子邮件格式正确:", regex.test(email)); 验证密码(要求:至少包含一个数字,一个字母,一个特殊字符,长度在8~18之间):const password = "Abcdef.123"; const regex = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\W_]).{8,18}$/; console.log("密码格式正确:", regex.test(password)) 验证输入内容不能包含 emoji 表情:function hasEmoji(str) { const emojiRegex = /[\uD800-\uDFFF]|[\u2600-\u27FF]|[\u1F000-\u1F9FF]/g; return emojiRegex.test(str); } // 测试样例 const text1 = 'Hello, world!'; const text2 = '你好,🌍!'; console.log(hasEmoji(text1)); // false console.log(hasEmoji(text2)); // true 搜索和替换搜索和替换是正则表达式的很常见的用例。它允许查找文本中的特定模式并将其替换为所需的内容。笔者之前做个一个需求:获取 HTML 字符串中所有图片,也就是获取所有 img 标签的 src 属性值,这个需求属于数据提取,第三部分会讲到;将获取到的图片转灰度图,转灰度成功的图片的名称会加一个-gray后缀,将这个图片替换 HTML 原来的图片。也就将转换成功的图片的src地址加-gray后缀。灰度图替换:const grayImgReplace = (html: string, imgUrl: string) => { const regex = /(https?:\/\/[^\s"']+\.[^\s"']+(?<!-gray))\.(jpg|jpeg|png)/; const match = regex.exec(html); if (match) { return html.replace(match[0], `${imgUrl}`); } return html; }; 注意:这里仅替换一张图,若需要替换多张,每个图片都执行该方法即可。另一个例子就是在 IDE 中进行正则表达式搜索和替换操作。比如,在 VS Code 中,只需在搜索栏中点击搜索栏左侧的正则表达式按钮(.*)或按下快捷键 Alt + R,就可以激活正则表达式搜索模式。比如,有一个动态接口路径:/app/api/:modal/list,想要看看哪些地方调用了这个接口。这个路径中间的 modal 是动态的,没办法直接通过字符串进行搜索,怎么办呢?可以借助正则表达式轻松实现:\/app\/api\/([^\/]+)\/list 不管 modal 是什么,都可以轻松搜索到:除此之外,还可以通过搜索替换轻松实现数据的格式化。例如,将数字转换为货币格式:const formatMoney = (money) => { return money.replace(new RegExp(`(?!^)(?=(\\d{3})+${money.includes('.') ? '\\.' : '$'})`, 'g'), ',') } formatMoney('123456789') // '123,456,789' formatMoney('123456789.123') // '123,456,789.123' formatMoney('123') // '123' 数据提取数据提取是正则表达式的另一个常见用例。正则表达式使我们能够根据定义的模式从较大的文本中有效地提取特定信息。上面提到了从 HTML 字符串中获取所有图片 URL 的需求,下面来实现一下:const getImgs = (domContent) => { const imgs = []; const imgPattern = /<img[^>]+src=['"]((?!.*\.svg).+?)['"]/g; let match = null; while ((match = imgPattern.exec(domContent)) !== null) { imgs.push(match[1]); } return imgs; }; 再比如,获取所有 a 标签链接,也就是获取 href 属性值:const html = '<a href="https://www.example.com">Link 1</a> <a href="https://www.google.com">Link 2</a>'; // 使用正则表达式提取 <a> 标签链接 const linkRegex = /<a\s+(?:[^>]*?\s+)?href=(["'])(.*?)\1/g; const links = []; let match; while ((match = linkRegex.exec(html)) !== null) { const link = match[2]; links.push(link); } console.log(links); 输出结果如下:[ 'https://www.example.com', 'https://www.google.com' ] 再比如,提取 URL 中的域名:const url = 'https://www.example.com/path/to/page?param1=value1¶m2=value2#section'; const domainRegex = /https?:\/\/([\w.-]+)/; const match = url.match(domainRegex); const domain = match && match[1]; console.log(domain); // www.example.com 数据清洗通过适当使用正则表达式,可以轻松地从文本数据中查找、匹配和替换特定的模式和字符,从而对数据进行清理和预处理。以下是一些常见的数据清洗任务,可以使用正则表达式来完成:移除多余空格:使用正则表达式将连续的多个空格或制表符替换为单个空格,或者完全移除所有空格。格式化日期:使用正则表达式解析和提取日期字符串,并将其格式化为指定的格式或日期对象。清除特殊字符:使用正则表达式从文本数据中移除不需要的特殊字符和标点符号,例如 emoji 表情符号、HTML 标签、URL 等。提取信息:使用正则表达式从文本数据中提取特定的信息,例如电话号码、邮件地址、IP 地址等。替换错误或不一致的数据:使用正则表达式查找和替换文本数据中的错误拼写、大小写、颠倒顺序等问题,使得数据更加一致和规范化。比如,删除字符串中的标签和 emoji 表情:const text = 'Hello, <b>world</b>! 🌍'; const cleanText = text.replace(/<\/?[^>]+(>|$)/g, '').replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, ''); console.log(cleanText); // Hello, world! 这里使用了两个正则表达式替换操作:/<\/?[^>]+(>|$)/g:这个正则表达式用于匹配并移除 HTML 标签。它会匹配尖括号内的任何内容,并将其替换为空字符串。/[\uD800-\uDBFF][\uDC00-\uDFFF]/g:这个正则表达式用于匹配并移除 emoji 表情符号。由于 emoji 符号采用 Unicode 编码的多个字符表示,我们使用这个正则表达式匹配并移除这些字符。五、实用工具Regex101Regex101 是学习正则表达式最有效的工具网站之一,本文的示例使用的就是这个工具。在REGULAR EXPRESSION栏中可以输入正则表达式,可以在输入框右侧选择需要的修饰符,在下面的TEST STRING栏中输入要测试的字符串,即可显示出匹配到的结果。在右侧的EXPLANATION区域会显示出对输入的正则表达式的详细解释。右下角的 QUICK REFERENCE 栏会显示正则表达式速查表。Regex101 还支持在上面练习编写正则表达式:可以在上面搜索一些正则表达式的库:除此之外,我们还可以使用 RegexDebugger 来跟踪匹配的过程。更多功能可以在Regex101 上进行探索。官网: https://regex101.com/RegExrRegExr 是一个基于 JavaScript 开发的在线工具,用来创建、测试和学习正则表达式。它是一个开源的工具,具有以下特性:输入时,结果会实时更新;支持 JavaScript 和 PHP/PCRE RegEx;将匹配项或表达式移至详细信息;保存并与他人共享表达式;使用工具探索结果;浏览参考以获取帮助和示例;在编辑器中使用 cmd-Z/Y 撤消和重做。官网: https://regexr.com/Regex PalRegexpal 是一个基于 Javascript 的在线正则表达式验证工具。它的页面非常简洁,只有两个输入框,上面的输入框中可以输入正则表达式(匹配规则),下面的输入框可以输入待匹配的数据。此外,根据具体要求,还可以设置忽略大小写、多行匹配等参数。官网: https://www.regexpal.com/Regex-VisRegex-Vis 是一个辅助学习、编写和验证正则的工具。它不仅能对正则进行可视化展示,而且提供可视编辑正则的能力。在输入一个正则表达式后,会生成它的可视化图形。然后可以点选或框选图形中的单个或多个节点,再在右侧操作面板对其进行操作,具体操作取决于节点的类型,比如在其右侧插入空节点、为节点编组、为节点增加量词等。官网: https://regex-vis.com/Regex previewerRegex previewer 是一个 VScode 插件,在插件市场搜索名称即可安装。当我们在编写正则表达式时,可以直接使用快捷键 Ctrl+Alt+M (windows)或者 ⌥+⌘+M(Mac)在编辑器右侧启动一个标签页,我们可以在这个标签页写一写测试用例,用来测试我们写的正则表达式,写完字符串用例之后,点击我们编写的正则表达式上方的 Test Regex...即可,这样右侧匹配到字符就会高亮显示了,如下图:
2023年10月13日
57 阅读
0 评论
0 点赞
2023-10-08
PHP知识大全
以下资料来源于网络持续排版中。。。1. 变量如何定义?如何检查变量是否定义?如何删除一个变量?怎样检测变量是否设置?$定义 isset()// 检测变量是否设置 defined()// 检测常量是否设置 unset()//销毁指定的变量 empty()// 检测变量是否为空2. 什么是可变变量?一个变量的变量名可以动态的设置和使用。//$a = 'hello' , $$a = 'world', ${$a}=hello world $a = 'hello'; $$a = 'world'; define("HELLO","${$a}=hello world"); echo $a; echo $$a; echo HELLO; echo defined("HELLO"); //helloworldworld=hello world13. 变量赋值方式有哪几种?1)直接赋值 2)变量间赋值 3)引用赋值4. 引用和拷贝有什么区别?拷贝是将原来的变量内容复制下来,拷贝后的变量与原来的变量使用各自的内存,互不干扰。引用相当于是变量的别名,其实就是用不同的名字访问同一个变量内容。当改变其中一个变量的值时,另一个也跟着发生变化。5. php中变量有哪些基本数据类型?php支持 8种 原始数据类型包括:四种标量类型(布尔型boolean,整型interger,浮点型float/double , 字符串string)两种复合类型(数组array , 对象object)两种特殊类型(资源resource,NULL)6. 其它类型转换为boolean类型时,哪些被认为是false?其它类型转换为boolean类型时,哪些被认为是false?布尔值false,整型值0, 浮点型值0.0, 空白字符串, 字符串'0', 空数组,特殊数据类型NULL, 没有设定的变量。empty()函数在哪些情况下返回true?布尔值false,整型值0, 浮点型值0.0, 空白字符串, 字符串'0', array()空数组,特殊数据类型NULL, 没有任何属性的对象,没有赋值的变量。7. 如果定义了一个变量$a ,但是没有赋初始值那么$a==0吗? $a==false吗? $a==''吗?$a==NULL吗? $a===NULL吗? ———————————— 答:echo=>什么都没有 , var_dump=>NULLempty($b)==true吗?———————————— 答:echo=>1 , var_dump=>bool(true)此时如果输出$a++是多少?——————— 答:echo=>什么都没有 , var_dump=>NULL如果输出++$a又是多少?————————— 答:echo=>1 , var_dump=>int(1)8. 字符串怎么转成整数,有几种方法?怎么实现?强制类型转换: (整型)字符串变量名;直接转换:settype(字符串变量,整型);内置函数:intval(字符串变量);$a = 'hello'; echo (int)$a; echo intval($a); settype($a,'int'); echo $a; //0009. 标量数据和数组的最大区别是什么?一个标量只能存放一个数据,而数组可以存放多个数据。10. 常量如何定义? 如何检测一个常量是否被定义?常量的值只能是哪些数据类型?define()//定义常量 , defined()//检查常量是否定义常量的值只能是标量类型的数据。11. 常量分为系统内置常量和自定义常量。请说出最常见的几个系统内置常量?__FILE__ , __LINE__ , PHP_OS , PHP_VERSION12. 如果定义了两个相同的常量,前者和后者哪个起作用?前者起作用,因为常量一旦定义就不能被重新定义或者取消定义。13. 常量和变量有哪些区别?1)常量前没有$符号;2)常量只能用 define () 函数或const定义,而不能通过赋值语句定义;3)常量可以在任何地方定义和访问,而变量有全局和局部之分;4)常量一旦定义就不能被重新定义或者取消定义,而变量而通过赋值方式重新定义;5)常量的值只能是标量数据,而变量的数据库类型有8种原始数据类型。14. PHP中常用的几个预定义的全局数组变量是哪些?有 9大 预定义的内置数组变量:$_POST, $_GET, $_REQUEST, $_SESSION, $_COOKIE, $_FILES,$_SERVER, $_ENV, $GLOBALS15. 在实际开发中,常量最常用于哪些地方?1)连接数据库的信息定义成常量,如数据库服务器的用户名、密码、数据库名、主机名;2)将站点的部分路径定义成常量,如web绝对路径,smarty的安装路径,model、view或者controller的文件夹路径;3)网站的公共信息,如网站名称,网站关键词等信息。16. 函数的优越性有哪些?提高程序的可维护性 提高软件的可靠性 提高程序的可重用性 提高程序的开发效率17. 如何定义一个函数?函数名区分大小写吗?1)使用 function 关键字;2)函数命名规则和变量一样,以字母或者下划线开头,而不能以数字开头;3)函数名不区分大小写;4)函数名不可以使用已经声明过的或者系统自建的函数名称。18. 什么是变量的能见度 或者 说是变量作用域?就是变量在程序中的可作用范围。根据变量的能见度,变量分为局部变量和全局变量。19. 什么是局部变量和全局变量?函数内是否可以直接调用全局变量?局部变量是函数内部定义的变量,其作用域是所在的函数。如果函数外还有一个跟局部变量名字一样的变量,程序会认为它们两个是完全不同的两个变量。当退出函数的时候,其中的局部变量就同时被清除。全局变量是定义在所有函数以外的变量,其作用域是整个php文件,但是在用户自定义的函数内部是无法使用的。如果一定要在用户自定义的函数内部使用全局变量,那么就需要使用global关键字声明。也就是说如果在函数内的变量前加上golbal来修饰,那么函数内部就可以访问到这个全局变量,不仅可以利用这个全局变量进行运算而且可以对这个全局变量进行重新赋值。全局变量还可以使用 $GLOBALS['var'] 来调用。$var = 123; function a(){ $var = 2; //global $var = 2; //等同 //$GLOBALS['var'] = 2; } a(); echo $var; //123 //221. 什么是静态变量?如果一个函数内定义的变量前使用关键字static来声明,那么该变量就是静态变量。一般函数内的变量在函数调用结束后,其存储的数据将被清除,所占的内存空间也被释放。而使用 静态变量 时, 该变量会在函数第一次被调用时被初始化,初始化后该变量也不会被清除 ,当再次调用该函数时,这个静态变量不再被初始化,而能保存上次函数执行完后的值。可以说 静态变量在所有对该函数的调用之间共享。22. php中函数传递参数的方式有哪些?两者有什么区别?按值传递和按地址传递(或按引用传递) (1)按值传递: 待传递的变量,与传递给函数之后的变量是存储在不同的空间中。所以函数体内对该变量值做的修改,不影响原本的变量值。(2)按地址传递 : 使用 & 符号,表明该参数是以地址的方式传递值。并不会将主程序中的指定数值或目标变量传递给函数,而是把该数值或变量的内存储存区块地址导入函数之中,所以函数体内的该变量和主程序中的该变量在内存中是同一个。函数体做的修改,直接影响到函数体外部的该变量的值。23. 什么是递归函数?如何进行递归调用?递归函数 其实就是 调用自身的函数 ,但是必须满足以下 两个条件 :1)在每一次调用自身时,必须是更接近于最终结果;2)必须有一个确定的递归终止条件,不会造成死循环。举例说明:在实际工作中往往会在遍历文件夹的时候使用。如果有个例子是希望获取到目录windows下所有的文件,那么先遍历windows目录,如果发现其中还有文件夹,那么就会调用自身,继续往下寻找,依次类推,直到遍历到再也没有文件夹为止,这也就是意味着遍历出来了所有的文件。24. 判断一个函数是否存在?function_exists( string $function_name ) //如果存在,返回true, 不存在则返回 false。25. func()和@func()之间有什么区别?第二个函数调用失败不会报错,第一个会报错,即@符号忽略报错,非特殊情况不建议使用,因为程序出错应该暴露出来解决掉,而不是忽略可能导致后续不可预计的错误26. include()和require()函数的用法和区别是什么?include_once()和require_once()呢?include和require出现错误后的错误级别不一样, include是包含文件 ,如果引入的文件不存在,会发出 警告错误 ,但 脚本会继续执行 ;而 require是必须包含文件 ,如果引入的文件不存在,会发出 致命错误 , 脚本会停止执行 。include_once()和require_once()在加载之前要判断是否已经导入,即会在导入文件前先检测该文件是否在该页面的其他部分被应用过,如果有,则不会重复引用该文件,程序只能引用一次。而它们的报错级别跟include和require一样。强烈建议使用require()、require_once()27. 说出前置++和后置++的区别?前置++是先将变量增加1,然后在将值赋值给原来的变量;后置++是先返回变量的当前值,然后再将变量的当前值增加1.$one_num = 0; $two_num = 0; echo $one_num++; echo ++$two_num; //0128. 字符串运算符“.”与算术运算符“+”有什么区别?当“a”“b”之间 使用.时认为是连字符。如果两者间是+的时候php会认为是一次运算。 1)如果+号两边的字符串是数字组成的,那么会将字符串自动转为整型;2)如果+号两边是纯粹的字母/中文,那么会输出0;3)如果+号两边的字符串是以数字开头的,那么会截取字符串开头的数字,然后进行运算。$a = "你好"; $b = "世界"; echo $a+$b; echo $a.$b; //0你好世界 $a = "hello"; $b = "world"; echo $a+$b; echo $a.$b; //0helloworld $a = "2你好"; $b = "31世界"; echo $a+$b; echo $a.$b; //33 2你好31世界29. 什么是三目(或三元)运算符?根据一个表达式的结果在另两个表达式中选择一个。例如: ($a==true) ? 'good':'bad';30. 控制流程语句有哪些?1:三种程序结构 顺序结构、分支结构、循环结构2:分支: if/esleif/esle/ switch/case/default3: switch 需要注意的:case子句中的常量可以是整型、字符串型常量、 或者常量表达式,不允许是变量。同一个switch子句中,case的值不能相同,否则只能取到首次出现case中的值。4: 循环 for while do...whiledo...while 后面必须加入分号结尾(如do{ //todo }while(表达式);)。while 和 do...while 的区别,后者 不管三七二十一先执行一次循环体内容 再判断while中表达式是否为ture然后再进入循环体。5:break 和 continue 的区别。break终止当前这一层循环,有嵌套循环情况下会结束该循环体内的循环,循环体外的循环并不结束。continue跳过本次循环,进入到下一次循环中。31. 数组的概念是什么?数组根据索引分为哪两种,如何区分?数组的赋值方式有哪两种?数组是一个可以存储一组或一系列数值的变量(复合型变量)索引数组(索引值为数字,以0开始)和关联数组(以字符串作为索引值)数组的赋值方式有哪两种?数组的声明方式主要有两种。1.通过array()函数声明数组;可以通过key=>value的方式分别定义索引和值,也可以不定义数组的索引下标,只给出数组的元素值。2.直接为数组元素赋值,不需要调用array()函数。例如:$arr[0] = 1; $arr[1] = 2;特别注意:数组的下标如果是等价于整数的字符串值(但不能以0开头),则会被当作整数对待。例如: $array[3] 与 $array['3'] 引用的是相同的一个元素,而 $array['03'] 引用的则就是另外的一个元素了。32.数组如何遍历?①for循环②foreach循环这是最常用的遍历方式。用法如下:foreach($arr as $key=>$value){}③list each 和while 配合起来循环<?php $contact=array( 'gao'=>array('ID'=>1,'name'=>'高某','company'=>'A公司','addr'=>'北京市','phonenumber'=>'(010)98765432','email'=>'gao@mail.com'), 'li'=>array('ID'=>2,'name'=>'李某','company'=>'B公司','addr'=>'上海市','phonenumber'=>'(021)98765432','email'=>'li@mail.com'), 'ma'=>array('ID'=>3,'name'=>'马某','company'=>'C公司','addr'=>'重庆市','phonenumber'=>'(023)98765432','email'=>'ma@mail.com'), 'fan'=>array('ID'=>4,'name'=>'范某','company'=>'D公司','addr'=>'天津市','phonenumber'=>'(022)98765432','email'=>'fan@mail.com') ); while(list($key,$value)=each($contact)){ while(list($name,$info)=each($value)){ echo $name.':'.$info.'<br>'; } echo "------------------------------------<br>"; } ?>参考:https://blog.csdn.net/maminyao/article/details/7569079each函数:https://www.runoob.com/php/func-array-each.html33. foreach数组的时候指针是如何指向的?list()/each()/while()循环数组的时候指针如何指向的呢?当foreach开始执行的时候,数组内部的指针会自动指向第一个单元。因为foreach所操作的是指定数组的拷贝,而不是该数组本身。而each()一个数组后,数组指针将停留在数组中的下一个单元或者碰到数组结尾时停留在最后一个单元。如果要再次使用each()遍历数组,必须要使用reset().reset()将数组的内部指针倒回到第一个单元并返回第一个数组单元的值。34. 如何计算数组长度(或者说计算数组中所有元素的个数)?字符串怎么取长度?数组长度: count() -- 计算数组中的元素个数。可以使用count(数组名)或者count(数组名,1),如果有第二个参数,并且是数字1,则表示递归统计数组元素的个数。如果第二个参数是数字0,则等同于只有一个参数的count()函数。sizeof() -- count() 的别名 (count — 计算数组中的单元数目或对象中的属性个数)字符串长度: strlen() -- 获取字符串长度mb_strlen() -- Get string length两者区别 :https://www.51cto.com/article/263103.htmlPHP内置的字符串长度函数 strlen 无法正确处理中文字符串,它得到的只是 字符串所占的字节数。 对于GB2312的中文编码,strlen得到的值是汉字个数的2倍,而对于UTF-8编码的中文,就是3倍的差异了(在 UTF-8编码下,一个汉字占3个字节)。采用 mb_strlen 函数可以较好地解决这个问题。mb_strlen的用法和 strlen类似,只不过它 有第二个可选参数用于指定字符编码 。例如得到UTF-8的字符串$str长度,可以用 mb_strlen($str,'UTF-8')。35. 数组中相关的常用函数有哪些?1) count --(sizeof别名)— 计算数组中的单元数目或对象中的属性个数 例如:int count ( mixed $var [, int $mode ] ) $var 通常都是数组类型,任何其它类型都只有一个单元。 $mode 默认值为0. 1为开启递归地对数组计数2) in_array ( mixed $needle , array $haystack [, bool $strict ] ) — 检查数组中是否存在某个值。如果 needle 是字符串,则比较是区分大小写的。如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会检查 needle 的类型是否和 haystack 中的相同。3) array_merge(array $array1 [, array $array2 [, array $... ]] ) 将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。特别注意:如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引$people = array("Peter", "Joe"=>array("Peter", "Joe", "Glenn"), "Glenn", "Cleveland"=>array("Peter", "Joe", "Glenn"),6=>"666"); $people1 = array("Peter1", "Joe"=>array("Peter1", "Joe1", "Glenn1"), "Glenn1", "Cleveland1"=>array("Peter", "Joe", "Glenn"),"6"=>"666"); var_dump(array_merge($people,$people1)); //输出 array(9) { [0]=> string(5) "Peter" ["Joe"]=> array(3) { [0]=> string(6) "Peter1" [1]=> string(4) "Joe1" [2]=> string(6) "Glenn1" } [1]=> string(5) "Glenn" ["Cleveland"]=> array(3) { [0]=> string(5) "Peter" [1]=> string(3) "Joe" [2]=> string(5) "Glenn" } [2]=> string(3) "666" [3]=> string(6) "Peter1" [4]=> string(6) "Glenn1" ["Cleveland1"]=> array(3) { [0]=> string(5) "Peter" [1]=> string(3) "Joe" [2]=> string(5) "Glenn" } [5]=> string(3) "666" }4) 数组与字符串之间的转换(1)explode ( string $separator , string $string [, int $limit ] ) 使用一个分隔字符来分隔一个字符串。(2)implode ( string $glue , array $arr ) 使用一个连接符将数组中的每个单元连接为一个字符串。 join 为 implode 的别名5) sort(array &$array [, int $sort_flags ]) — 对数组按照值排序,当本函数结束时数组单元将被从最低到最高重新安排。sort() 函数用于对数组单元从低到高进行排序(值顺序排序)。rsort() 函数用于对数组单元从高到低进行排序(值倒序排序)。asort() 函数用于对数组单元从低到高进行排序并保持索引关系(保持索引,值顺序排序)。arsort() 函数用于对数组单元从高到低进行排序并保持索引关系(保持索引,值倒序排序)。ksort() 函数用于对数组单元按照键名从低到高进行排序(键名顺序排序)。krsort() 函数用于对数组单元按照键名从高到低进行排序(键名倒序排序)。36. 数组合并函数array_merge()和数组加法运算$arr + $arr2 的区别是什么?array_merge()->使用array_merge(),如果是关联数组合并,如果数组的键名相同,那么后面的值将覆盖前者;如果是数字索引数组合并,则不覆盖,而是后者附加到前者后面。"+"->使用数组加法运算,与array_merge()不同,加法运算不管是关联数组还是数字索引数组,都是将相同键名的的值舍弃,也就是只保留首次出现该键名的元素,后来的具有相同键名的元素都不会被加进来。37. 字符串定义的时候单引号和双引号有什么区别?单引号加载速度比双引号加载速度快38. echo(),print(),print_r()的区别?(1)echo 是语法,Output one or more strings,没有返回值;(2)print 是函数,不能输出数组和对象,Output a string,print有返回值;(3)print_r 是函数,可以输出数组。print_r是个比较有意思的函数,可以输出stirng、int、float、 array、object等,输出array时会用结构表示,print_r输出成功时返回true;而且print_r可以通过print_r($str,true)来,使print_r不输出而返回print_r处理后的值。此外,对于echo和print,基本以使用echo居多,因为其效率比print要高。39. 按照功能分类说说都有哪些字符串处理函数?这些函数的作用是什么?A. 字符串输出函数(1)echo $a,$b,$c......; 是一个语言结构,而不是一个真正的函数。(2)print($a) 本函数输出字符串。若成功则返回 1,失败返回 0(3)print_r($a)(4)var_dump($a); 能输出类型、长度、值B. 去除字符串首尾空格的函数trim ltrim rtrim(别名:chop) 使用第二个参数,还可以去除指定的字符。C. 转义字符串函数:addslashes()D. 获取字符串长度的函数:strlen()E. 截取字符串长度的的函数:substr()F. 检索字符串函数: strstr() , strpos()G. 替换字符串函数:str_replace()40. 请给出以下问题的正确答案?1).$arr = array('james', 'tom', 'symfony');请将$arr数组的值用’,’分割并合并成字符串输出? echo implode(‘,’,$arr);2).$str = ‘jack,james,tom,symfony’; 请将$str用’,’分割,并把分割后的值放到$arr数组中? $arr = explode(‘,’,$str);3).$arr = array(3,7,2,1,’d’,’abc’); 请将$arr按照从大到小的顺序排序,并保持其键值不变? arsort($arr); print_r($arr);4).$mail = “gaofei@163.com”; 请将此邮箱的域(163.com)取出来并打印,看最多能写出几种方法?echo strstr($mail,'163'); echo substr($mail,7); $arr = explode("@",$mail); echo $arr[1];5). 如果有一个字符串,该字符串是“123,234,345,”。请问如何切割掉这个字符串最后一个逗号?$str = '123,234,345,'; echo trim($str,',');6). 获取随机数的函数有哪几个?mt_rand() 和 rand()哪个执行速度快?前者41.页面字符出现乱码,怎么解决?1.首先考虑当前文件是不是设置了字符集。查看是不是meta标签中写了charset,如果是php页面还可以看看是不是在header()函数中指定了charset;例如:<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> header(“content-type:text/html;charset=utf-8”);2.如果设置了字符集(也就是charset),那么判断当前文件保存的编码格式是否跟页面设置的字符集保持一致,两者必须保持统一;3.如果涉及到从数据库提取数据,那么判断数据库查询时的字符集是否跟当前页面设置的字符集一致,两者必须统一,例如:mysql_query(“set names utf8”)。42. 正则表达式是什么?php中有哪些常用的跟正则相关的函数?请写出一个email的正则,中国手机号码和座机号码的正则表达式?正则表达式是用于描述字符排列模式的一种语法规则。正则表达式也叫做模式表达式。网站开发中正则表达式最常用于表单提交信息前的客户端验证。比如验证用户名是否输入正确,密码输入是否符合要求,email、手机号码等信息的输入是否合法在php中正则表达式主要用于字符串的分割、匹配、查找和替换操作。preg系列函数可以处理。具体有以下几个:string preg_quote ( string str [, string delimiter] )转义正则表达式字符 正则表达式的特殊字符包括:. \\ + * ? [ ^ ] $ ( ) { } = ! < \> | :。preg_replace -- 执行正则表达式的搜索和替换mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]preg_replace_callback -- 用回调函数执行正则表达式的搜索和替换mixed preg_replace_callback ( mixed pattern, callback callback, mixed subject [, int limit] )preg_split -- 用正则表达式分割字符串array preg_split ( string pattern, string subject [, int limit [, int flags]] )常用的正则表达式写法:中文:/^[\u4E00-\u9FA5]+$/手机号码:/^(86)?0?1\d{10}$/EMAIL:/^[\w-]+[\w-.]?@[\w-]+.{1}[A-Za-z]{2,5}$/密码(安全级别中):/^(\d+[A-Za-z]\w|[A-Za-z]+\d\w)$/密码(安全级别高):/^(\d+[a-zA-Z~!@#$%^&(){}][\\w~!@#$%^&(){}]|[a-zA-Z~!@#$%^&(){}]+\\d[\\w~!@#$%^&(){}])$/正则表达式拓展44. preg_replace()和 str_ireplace()两个函数在使用上有什么不同?preg_split()和split()函数如何使用?preg_replace — 执行正则表达式的搜索和替换str_ireplace — str_replace() 的忽略大小写版本 str_replace — 子字符串替换preg_split — 用正则表达式分割字符串split — 用正则表达式将字符串分割到数组中45. 获取当前时间戳的函数主要有哪些?用PHP打印出今天的时间,格式是2010-12-10 22:21:21?用PHP打印出前一天的时间格式是2010-12-10 22:21:21?如何把2010-12-25 10:30:25变成unix时间戳?echo date ("Y-m-d H:i:s" ,strtotime(‘-1,days’));date('Y-m-d H:i:s',time());$unix_time = strtotime("2009-9-2 10:30:25");//变成unix时间戳echo date("Y-m-d H:i:s",$unix_time);//格式化为正常时间格式46. 在url中用get传值的时候,若中文出现乱码,应该用哪个函数对中文进行编码?用户在网站表单提交数据的时候,为了防止脚本攻击(比如用户输入alert(111);),php端接收数据的时候,应该如何处理?使用urlencode()对中文进行编码,使用urldecode()来解码。使用htmlspecialchars($_POST[‘title’])来过滤表单传参就可以避免脚本攻击。48. 说说mysql_fetch_row() 和mysql_fetch_assoc()和mysql_fetch_array之间有什么区别?第一个是返回结果集中的一行作为索引数组,第二个是返回关联数组,而第三个既可以返回索引数组也可以返回关联数组,取决于它的第二个参数 MYSQL_BOTH MYSQL_NUM MYSQL_ASSOC 默认为MYSQL_BOTH$sql =”select * from table1”; $result = mysql_query($sql); mysql_fetch_array($result, MYSQL_NUM);49. 请说出目前学过的返回是资源的函数?答: fopen(打开文件)imagecreatefromjpeg(png gif) — 从 JPEG 文件新建一图像imagecreatetruecolor — 新建一个真彩色图像imagecopymerge — 拷贝并合并图像的一部分imagecopyresized — 拷贝部分图像并调整大小mysql_connect — 打开一个到 MySQL 服务器的连接mysql_query();只有这执行select的时候成功,才返回资源,失败返回FALSE50. 打开、关闭文件分别是什么函数? 文件读写是什么函数?删除文件是哪个函数?判断一个文件是否存在是哪个函数?新建目录是哪个函数?待回答。。。51. 文件上传需要注意哪些细节?怎么把文件保存到指定目录?怎么避免上传文件重名问题?1.首现要在php.ini中开启文件上传;2.在php.ini中有一个允许上传的最大值,默认是2MB。必要的时候可以更改;3.上传表单一定要记住在form标签中写上enctype="multipart/form-data";提交方式 method 必须是 post;设定 type="file" 的表单控件;6.要注意上传文件的大小MAX_FILE_SIZE、文件类型是否符合要求,上传后存放的路径是否存在。可以通过上传的文件名获取到文件后缀,然后使用时间戳+文件后缀的方式为文件重新命名,这样就避免了重名。可以自己设置上传文件的保存目录,与文件名拼凑形成一个文件路径,使用move_uploaded_file(),就可以完成将文件保存到指定目录。52. $_FILES是几维数组?第一维和第二维的索引下标分别是什么?批量上传文件的时候需要注意什么?二维数组。第一维是上传控件的name,二维下标分别为name/type/tmp_name/size/error.53. header()函数主要的功能有哪些?使用过程中注意什么?答:header()发送http头信息 -header("content-type:text/html; charset=utf-8");-------------------//当前页面输出内容是html,编码为utf-8格式 -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -header("content-type:image/png gif jpeg");----------------------------------//当前页面输出内容的格式是图片 -header("refresh:5;url=http://www.1004javag.com/five/string.php");--//页面5秒后要跳转到新网址 -header("location:http://1004javag.com/five/string.php");-----------//页面重定向54. 文件下载的时候如果使用header()函数?答:header("content-type: application/octet-stream;charset=UTF-8"); //在这里加utf-8和在上面定义有什么区别? header("accept-ranges: bytes"); header("accept-length: ".filesize($filedir.$filename)); header("content-disposition: attachment; filename=".$filedir.$filename);55. 什么是ajax?ajax的原理是什么?ajax的核心技术是什么?ajax的优缺点是什么?ajax是asynchronous javascript and xml的缩写,是javascript、xml、css、DOM等多个技术的组合。页面中用户的请求通过ajax引擎异步地与服务器进行通信,服务器将请求的结果返回给这个ajax引擎,最后由这个ajax引擎来决定将返回的数据显示到页面中的指定位置。Ajax最终实现了在一个页面的指定位置可以加载另一个页面所有的输出内容。这样就实现了一个静态页面也能获取到数据库中的返回数据信息了。所以ajax技术实现了一个静态网页在不刷新整个页面的情况下与服务器通信,减少了用户等待时间,同时也从而降低了网络流量,增强了客户体验的友好程度。ajax的核心技术是XMLHttpRequest,它是javascript中的一个对象。Ajax的优点是: 减轻了服务器端负担,将一部分以前由服务器负担的工作转移到客户端执行,利用客户端闲置的资源进行处理; 在只局部刷新的情况下更新页面,增加了页面反应速度,使用户体验更友好。Ajax的缺点是不利于seo推广优化,因为搜索引擎无法直接访问到ajax请求的内容。56. jquery是什么?jquery简化ajax后的方法有哪些?jQuery是Javascript的一种框架。$.get(),$.post(),$.ajax()。$是jQuery对象的别名。代码如下:$.post(异步访问的url地址 , {'参数名' : 参数值} , function(msg){ $("#result").html(msg); }); $.get(异步访问的url地址 , {'参数名' : 参数值} , function(msg){ $("#result").html(msg); }); $.ajax({ type: "post", url: loadUrl, cache:false, data: "参数名=" \+ 参数值, success: function(msg) { $("#result").html(msg); } }); 57. 什么是会话控制?简单地说会话控制就是跟踪和识别用户信息的机制。会话控制的思想就是能够在网站中跟踪一个变量,通过这个变量,系统能识别出相应的用户信息,根据这个用户信息可以得知用户权限,从而展示给用户适合于其相应权限的页面内容。目前最主要的会话跟踪方式有cookie,session。58. 会话跟踪的基本步骤1).访问与当前请求相关的会话对象 2).查找与会话相关的信息3).存储会话信息 4).废弃会话数据59. 使用cookie的注意事项有哪些?1) setcookie()之前不可以有任何页面输出,就是空格,空白行也不可以; 2) setcookie()后,在当前页面调用$_COOKIE['cookiename']不会有输出,必须刷新或到下一个页面才可以看到cookie值;3) 不同的浏览器对cookie处理不同,客户端可以禁用cookie,浏览器也可以闲置cookie的数量,一个浏览器能创建的cookie数量最多300个,并且每个不可以超过4kb,每个web站点能设置的cookie总数不能超过50个(注意,每种浏览器支持cookie数量不一样,谷歌好像是53个,ie6是20个)。4) cookie是保存在客户端的,用户禁用了cookie,那么setcookie就不会起作用了。所以不可以过度依赖cookie。60. 使用session的时候,通过什么来表示当前用户,从而与其他用户进行区分?sessionid,通过session_id()函数可以取得当前的session_id。61. session和cookie的使用步骤分别是什么?什么是sesssion和cookie的生命周期?session和cookie的区别是什么?cookie是保存在客户端机器的,对于未设置过期时间的cookie, cookie值会保存在机器的内存中 ,只要关闭浏览器则cookie自动消失。 如果设置了cookie的过期时间,那么浏览器会把cookie以文本文件的形式保存到硬盘中,当再次打开浏览器时cookie值依然有效。 session是把用户需要存储的信息保存在服务器端。每个用户的session信息就像是键值对一样存储在服务器端,其中的键就是sessionid,而值就是用户需要存储信息。服务器就是通过sessionid来区分存储的session信息是哪个用户的。两者最大的区别就是session存储在服务器端,而cookie是在客户端。session安全性更高,而cookie安全性弱。 session在web开发中具有非常重要的份量 。它可以将用户正确登录后的信息记录到服务器的内存中,当用户以此身份访问网站的管理后台时,无需再次登录即可得到身份确认。而没有正确登录的用户则不分配session空间,即便输入了管理后台的访问地址也不能看到页面内容。通过session确定了用户对页面的操作权限。使用session的步骤:启动session:使用session_start()函数来启动。注册会话:直接给$_SESSION数组添加元素即可。使用会话:判断session是否为空或者是否已经注册,如果已经存在则像普通数组使用即可。删除会话:4.1.可以使用unset删除单个session;4.2.使用$_SESSION=array()的方式,一次注销所有的会话变量;4.3.使用session_destroy()函数来彻底销毁session。cookie怎么使用?记录用户访问的部分信息在页面间传递变量将所查看的internet页存储在cookies临时文件夹中,可以提高以后的浏览速度。创建cookie:setcookie(string cookiename , string value , int expire);读取cookie:通过超级全局数组$_COOKIE来读取浏览器端的cookie的值。删除cookie:有两种方法1.手工删除方法:右击浏览器属性,可以看到删除cookies,执行操作即可将所有cookie文件删除。2.setcookie()方法:跟设置cookie的方法一样,不过此时将cookie的值设置为空,有效时间为0或小于当前时间戳。62. 如何设置一个cookie的名字为username,值为jack,并且让此cookie一周后失效?setcookie(‘username’,’jack’,time()+7*24*3600);63. 设置或读取session之前,需要做什么?可以直接在php.ini中开启session.auto_start = 1 或者在页面头部用session_start();开启session,session_start()前面不能有任何输出,包括空行。64. 在实际开发中,session在哪些场合使用?session用来存储用户登录信息和用在跨页面传值。1)常用在用户登录成功后,将用户登录信息赋值给session;2)用在验证码图片生成,当随机码生成后赋值给session。65. 注销session会话的形式有几种?unset() $_SESSION=array(); session_destroy();66. 什么是OOP?什么是类和对象?什么是类属性?OOP(object oriented programming),即面向对象编程,其中两个最重要的概念就是类和对象。世间万物都具有自身的属性和方法,通过这些属性和方法可以区分出不同的物质。属性和方法的集合就形成了类,类是面向对象编程的核心和基础,通过类就将零散的用于实现某个功能的代码有效地管理起来了。类只是具备了某些功能和属性的抽象模型,而实际应用中需要一个一个实体,也就是需要对类进行实例化,类在实例化之后就是对象。★类是对象的抽象概念,对象是类的实例化。对象是一个高级的数组,数组是一个最原始的对象 ,同样的对象也可以遍历OOP具有三大特点: 1. 封装性 :也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系,或者说只公开了一些供开发人员使用的方法。于是开发人员只需要关注这个类如何使用,而不用去关心其具体的实现过程,这样就能实现MVC分工合作,也能有效避免程序间相互依赖,实现代码模块间松藕合。2. 继承性 :就是子类自动继承其父级类中的属性和方法,并可以可以添加新的属性和方法或者对部分属性和方法进行重写。继承增加了代码的可重用性。 php只支持单继承,也就是说一个子类只能有一个父类。3. 多态性 :子类继承了来自父级类中的属性和方法,并对其中部分方法进行重写。于是多个子类中虽然都具有同一个方法,但是这些子类实例化的对象调用这些相同的方法后却可以获得完全不同的结果,这种技术就是多态性。多态性增强了软件的灵活性。OOP的优点:1、代码重用性高(省代码) 2、使程序的可维护性高(扩展性) 3、灵活性67. 常用的属性的访问修饰符有哪些?分别代表什么含义?private,protected,public。类外:public ,var子类中:public,protected ,var本类中:private,protected,public ,var如果不使用这三个关键词,也可以使用var关键字。但是var不可以跟权限修饰词一起使用。var定义的变量,子类中可以访问到,类外也可以访问到,相当于public类前面:只能加final,abstract属性前面:必须有访问修饰符(private,protected,public,var)方法前面:static,final,private,protected,public ,abstract68. $this和self、parent这三个关键词分别代表什么?在哪些场合下使用?$this 当前对象 self 当前类 parent 当前类的父类$this在当前类中使用,使用->调用属性和方法。self也在当前类中使用,不过需要使用::调用。 parent在类中使用。69.类中如何定义常量、如何类中调用常量、如何在类外调用常量。类中的常量也就是成员常量,常量就是不会改变的量,是一个恒值。定义常量使用关键字const. 例如:const PI = 3.1415326;无论是类内还是类外,常量的访问和变量是不一样的,常量不需要实例化对象,访问常量的格式都是类名加作用域操作符号(双冒号)来调用。即:类名::类常量名;70. 作用域操作符::如何使用?都在哪些场合下使用?调用类常量 调用静态方法71. 什么是魔术方法?常用的魔术方法有哪几个?以__开头的系统自定义的方法。__construct() __destruct() __autoload() __call() __tostring()72. 什么是构造方法和析构方法?构造方法就是在实例化一个对象的同时自动执行的成员方法,作用就是初始化对象。 php5之前,一个跟类名完全相同的方法是构造方法,php5之后魔术方法__construct()就是构造方法。如果类中没有定义构造方法,那么php会自动生成一个,这个自动生成的构造方法没有任何参数,没有任何操作。构造方法的格式如下:function __construct(){} 或者:function 类名(){}构造方法可以没有参数,也可以有多个参数。析构方法的作用和构造方法正好相反,是对象被销毁时被自动调用的,作用是释放内存。 析构方法的定义方法为:__destruct(); 因为php具有垃圾回收机制,能自动清除不再使用的对象,释放内存,一般情况下可以不手动创建析构方法。73. __autoload()方法的工作原理是什么?使用这个魔术函数的基本条件是类文件的文件名要和类的名字保持一致 。当程序执行到实例化某个类的时候,如果在实例化前没有引入这个类文件,那么就自动执行__autoload()函数。这个函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后就执行include或者require来载入该类,然后程序继续执行,如果这个路径下不存在该文件时就提示错误。使用自动载入的魔术函数可以不必要写很多个include或者require函数。74. 什么是抽象类和接口?抽象类和接口有什么不同和相似的地方?抽象类是一种不能被实例化的类,只能作为其他类的父类来使用。 抽象类是通过关键字 abstract 来声明的。抽象类与普通类相似,都包含成员变量和成员方法,两者的区别在于, 抽象类中至少要包含一个抽象方法, 抽象方法没有方法体,该方法天生就是要被子类重写的。抽象方法的格式为:abstract function abstractMethod(); 因为php中只支持单继承,如果想实现多重继承,就要使用接口 。 也就是说子类可以实现多个接口 。接口类是通过interface关键字来声明的,接口类中的成员变量和方法都是public的,方法可以不写关键字public,接口中的方法也是没有方法体。接口中的方法也天生就是要被子类实现的。抽象类和接口实现的功能十分相似,最大的不同是接口能实现多继承。在应用中选择抽象类还是接口要看具体实现。 子类继承抽象类使用extends,子类实现接口使用implements。 抽象类至少有一个抽象方法吗? 答:如果一个类声明成抽象类,里面可以没有抽象方法 如果一个类中有抽象方法,这个类必须是抽象类75. __call的参数有几个,类型是什么,意义是什么?魔术方法__call()的作用是当程序调用一个不存在或不可见的成员方法时,php会先调用__call()方法,将那个不存在的方法的方法名和参数都存储下来。 __call()包含两个参数, 第一个参数是那个不存在的方法的方法名,是个字符串类型;第二个参数是那个不存在的方法的所有参数,是个数组类型。本人认为__call()方法的意义更多在于调试,可以定位到错误。同时可以捕捉异常,如果某个方法不存在,则执行其它可替代方法。76. smarty模板技术的用途是什么?为了php与html分开,美工和程序员各司其职,互不干扰。77. smarty配置主要有哪几项?引入smarty.class.php;实例化smarty对象;重新修改默认的模板路径;重新修改默认的编译后文件的路径;重新修改默认的配置文件的路径;重新修改默认的cache的路径。可以设置是否开启cache。可以设置左侧和右侧定界符。78. smarty在使用过程中需要注意哪些细节?Smarty是基于MVC概念的一种模板引擎,它将一个页面程序分成了两部分来实现:即视图层和控制层,也就是说smarty技术将用户UI与php代码分离开。这样程序员和美工各司其职,互不干扰。smarty运用过程中要注意以下几个问题:1.正确配置smarty。主要要实例化smarty对象,配置smarty模板文件的路径;2.php页面中使用assign赋值 和 display显示页面;3.smarty模板文件中不允许出现php代码段,所有的注释,变量,函数都要包含在定界符内。A.{}B. foreachC. if elseD. includeE. literal79. MVC的概念是什么?各层主要做什么工作?MVC(即模型-视图-控制器)是一种软件设计模式或者说编程思想。M指Model模型层,V是View视图层(显示层或者用户界面),C是Controller控制器层。使用mvc的目的是实现M和V分离,从而使得一个程序可以轻松使用不同的用户界面。在网站开发中,模型层一般负责对数据库表信息进行增删改查,视图层负责显示页面内容,控制器层在M和V之间起到调节作用,控制器层决定调用哪个model类的哪个方法,执行完毕后由控制器层决定将结果assign到哪个view层。81. java语言中方法重写和重载分别代表什么意思?准确说php支持方法的重载吗?很多参考书中提到的php重载实际上该如何正确理解?答:php不支持方法的重载,很多书里提到的PHP‘重载’应该是‘重写’82. final关键字能定义类中的成员属性吗?答:不能,类的成员属性只能有public ,private , protected ,var 来定义83. final关键字定义的类能够被继承吗?答:final定义的类不能被继承84. 说说static关键字的使用场合?static能用在class前吗?static可以跟public,protected,private一起使用吗?构造方法可以是static的吗?答: static可以在属性和方法前面使用,调用static属性或者方法时,只要将类载入就可用,不用实例化static不能用在class的前面static可以跟public,protected,private一起使用,在方法的前面;▲构造方法不能是static85. 接口可以实例化吗?抽象类能实例化吗?答:接口和抽象类都不能被实例化86. class前面能加访问修饰符吗?如果能加,只能是哪几个访问修饰符?可以是权限访问修饰符public,protected,private吗?答:class前面可以加final,static;★class前面不能加public,protected,private类中属性前可以不加访问修饰符吗?成员变量前的修饰符只能是public,protected,private吗?还可以是哪几个?答:类中的属性必须加修饰符,除了那3个以外,还可以加var如果echo一个数组,页面输出什么?echo一个对象呢?print一个数组或者对象呢?答:页面只能输出“Array”;echo一个对象会出现“Catchable fatal error: Object of class t2 could not be converted to string in G:\php2\t2.php on line 33” print一个数组时也只是输出“Array”,print一个对象出现“Catchable fatal error: Object of class t2 could not be converted to string in G:\php2\t2.php ” ▲print和echo是一样的 __tostring()魔术方法在什么时候被自动执行? __tostring()魔术方法必须要return返回值吗?当echo或者print一个对象时,就是自动触发。而且__tostring()必须要返回一个值什么是抽象方法?答:在方法前面有abstract,而且方法没有方法体,连“{ }”也不能有如果一个类中有一个方法是抽象方法,而这个类没有定义成抽象类,会报错吗?答:会,"Fatal error: Class t2 contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (t2::ee) in"如果一个类是抽象类,而类中的方法都是非抽象的方法,会报错吗?答:不会报错,如果一个类是抽象类,其中可以没有抽象方法,但是一个类中有个方法是抽象方法,那么这个类一定是一个抽象类final 关键字的应用应注意的问题?使用final关键字定义的类,禁止继承。使用final关键字定义的方法,禁止重写。如果一个类既要继承一个父类,又要实现多个接口,该如何写?书写格式例如: class MaleHuman extends Human implements Animal,Life { ... }什么是单点入口呢? 所谓单点入口就是整个应用程序只有一个入口,所有的实现都通过这个入口来转发, 比如说在上面我们就使用index.php作为程序的单点入口,当然这个是可以由你自己任意控制的。单点入口有几大好处: 第一、一些系统全局处理的变量,类,方法都可以在这里进行处理。比如说你要对数据进行初步的过滤,你要模拟session处理,你要定义一些全局变量,甚至你要注册一些对象或者变量到注册器里面 第二、程序的架构更加清晰明了。PHP提供了2套正则表达式函数库,分别是哪两套?【(1) PCRE Perl兼容正则表达式 preg_ 为前缀(2) POSIX 便携式的操作系统接口 ereg_ 为前缀正则表达式的组成? 由原子(普通字符,如英文字符)、 元字符(有特殊功用的字符) 模式修正字符 一个正则表达式中,至少包含一个原子不常用魔术方法的触发时机?__isset() __unset()的触发时机__sleep()、 __wakeup() 在对对象进行串行化的时候调用如果序列化对象的时候,不写__sleep()方法,则所有的成员属性都会被序列化,而定义了__sleep()方法,则只序列化指定数组中的变量。因此,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。使用 __sleep 的目的是关闭对象可能具有的任何数据库连接,提交等待中的数据或进行类似的清除任务。此外,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。使用 __wakeup 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务。101.常见框架thinkPHP yii ZendFramework CakePhp sy常用魔术方法的触发时机?1)__autoload() :当程序实例化某个类,而该类没有在当前文件中被引入。此时会触发执行__autoload()。程序希望通过该方法,自动引入这个类文件。该方法有一个参数,即就是那个忘记引入的类的名称。__autoload()方法的工作原理是什么?当程序执行到实例化某个类的时候,如果在实例化前没有引入这个类文件,那么就自动执行__autoload()函数。这个函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后,就执行include或者require来载入该类,然后程序继续执行,如果这个路径下不存在该文件时就提示错误。使用自动载入的魔术函数可以不必要写很多个include或者require函数。2)__construct() :这个是魔术构造方法。构造方法是实例化对象的时候自动执行的方法,作用就是初始化对象。该方法可以没有参数,也可以有多个参数。如果有参数,那么new这个对象的时候要记得写上相应的参数。在php5以前,没有魔术构造方法,普通构造方法是一个跟类名同名的方法来实现构造的。如果一个类中既写了魔术构造方法,又定义了普通构造方法。那么php5以上版本中,魔术方法起作用,普通构造方法不起作用。反之,在php5以前版本中,不认识魔术构造方法,只是把该方法当做普通的方法。3)__destruct() :这个是魔术析构方法。析构方法的作用和构造方法正好相反,是对象被销毁时被自动调用的,作用是释放内存。析构方法没有参数。4)__call() :当程序调用一个不存在或不可见的成员方法时,自动触发执行__call()。它有两个参数,分别是未访问到的方法名称和方法的参数。而第二个参数是数组类型。5)__get() :当程序调用一个未定义或不可见的成员属性时,自动触发执行__get()。它有一个参数,表示要调用的属性的名称。6)__set():当程序试图写入一个不存在或不可见的成员属性时,PHP就会自动执行__set()。它包含两个参数,分别表示属性名称和属性值。7)__tostring() :当程序使用echo或print输出对象时,会自动调用该方法。目的是希望通过该方法将对象转化为字符串,再输出。__tostring() 无参数,但是该方法必须有返回值。8)__clone() :当程序clone一个对象的时候,能触发__clone()方法,程序希望通过这个魔术方法实现:不仅仅单纯地克隆对象,还需要克隆出来的对象拥有原来对象的所有属性和方法。MVC的概念是什么?MVC(即模型-视图-控制器)是80年代发明的一种软件设计模式或者说编程思想。M指模型层,V是指视图层(显示层或者用户界面),C是指控制层。使用mvc的目的是实现M和V分离,从而使得一个程序可以轻松使用不同的用户界面。C存在的目的则是在M和V之间起到调节作用,确保M和V的同步,一旦M改变,V应该能同步更新。将M和V分离,就可以做到同一个网页,在不同节日到来的时候能显示不同的页面风格,这只需要提前制作多个视图层模板页面,而无需更改M层程序。MVC做到了编程中的分工合作,代码的可重用性得到最大化体现,程序逻辑更加清晰而富有条理,便于后期维护管理。104、 访问权限修饰符有哪几种,对比解释答:1、public 表示公共的,在本类中和子类中以及类外,可以对其调用2、protected表示受保护的,可以在本类中和子类中调用3、private表示私有的,只能在本类中调用4、var,效果等同于public105、 Class关键词前可以有哪些修饰词a) Final修饰,表示该类是最终的,无法继承b) Abstract修饰,表示该类是抽象类106、 作用域操作符在那些场合下使用答:作用于操作符的使用场合a) 本类中:i. self::类常量ii. self::静态属性iii. self::方法() parent::方法()b) 子类中:i. parent::类常量ii. parent::静态属性(public或者protected)iii. parent::方法()(public或者protected)c) 类外:i. 类名::类常量ii. 类名::静态属性(public)iii. 类名::静态方法(public)107、 $this,self, parent分别代表什么?哪些场合下使用答:$this代表的是当前对象 self代表的是当前的类 parent代表的是当前类的父类使用场合:$this只能使用在当前类中,通过$this->可以调用当前类中的属性和方法;self只能在当前类中使用,通过作用域操作符::访问当前类中的类常量、当前类中的静态属性、当前类中的方法;parent只能使用在有父类的当前类中,通过作用域操作符::访问父类中的类常量、父类中的静态属性、父类中的方法。108、 说明是接口、抽象类二者有何相同和不同的地方?1、接口是帮助php实现功能意义上的多继承的,用interface来声明,其方法没有方法体,使用implemens关键词来实现接口。接口中只能包含抽象方法和类常量,不可以包含成员属性。2、抽象类是一种不能被实例化的类,只能作父类,用abstract class来定义,抽象类和普通类可以没有区别,类中可以包含成员属性、类常量、方法。子类得用extends来继承,而且只能是单继承。两者相同点是都不可以被实例化,都是需要被继承才可以使用。两者的最大区别是接口可以实现多继承,而抽象类只能是单继承。接口中不能包含成员属性,而抽象类中可以有成员属性。接口中的抽象方法必须是public或者无访问修饰词,接口中的抽象方法不能用abstract来修饰。抽象类中的方法可以是普通方法,也可以是抽象方法,如果是抽象方法,一定需要使用abstract来修饰。109、 解释PHP中单例模式?又叫做单态模式、单元素模式、singleton pattern。单例模式指在PHP的应用程序的范围内只对指定的类创建一个实例。使用单例模式的类称为单例类。在php中单例类必须要有一个私有的构造方法,还要有一个私有的魔术克隆方法(该方法体中为空)和一个私有的静态的成员属性$_instance.私有构造方法防止除自身以外的类来实例化它。私有的方法体为空的克隆方法防止该类被克隆。$_instance用来存储被自身实例化后的对象。还必须要有一个公共的静态的方法getInstance()。该方法返回已经存储了实例对象的$_instance。单例:一个类至始至终只能实例化一个对象,这样的类就是单例类单例类的优点:① 节省空间 ② 节省资源实现单例类的四个要点:①私有的构造函数②私有的__clone的方法③私有的静态属性,属性有以保存类的实例④公共的静态方法来实例化对象无限级分类: ①数据库设计:region_id(自增ID) region_name(地区名称) parent-id(上级地区id) region_path(全路径)②程序设计:全路径的作用:a根据全路径顺序取数据 b用作信息层级显示 110、 什么是SQL注入?SQL注入攻击是黑客对数据库进行攻击的常用手段之一。一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,注入者可以在表单中输入一段数据库查询代码并提交,程序将提交的信息拼凑生成一个完整sql语句,服务器被欺骗而执行该条恶意的SQL命令。注入者根据程序返回的结果,成功获取一些敏感数据,甚至控制整个服务器,这就是SQL注入。111、 如何防止SQL注入?要对提交的信息进行过滤,对单引号进行转义。首先可以在php.ini中设置,让所有的单引号在提交后都进行转义。或者使用addslashes().112、 FCKEditor自动过滤的解决办法?如果您需要编辑模板页,默认的FCK设置是会去掉标签,而且会给你加上标签的,如果需要保留的话,只要更改下设置可以了。在fckconfig.js里面有:FCKConfig.FullPage = false ;改为:FCKConfig.FullPage = true;如果想去掉自动添加的代码就可以在这里设置默认是FCKConfig.EnterMode = 'p' ; // p | div | brFCKConfig.ShiftEnterMode = 'br' ; // p | div | br改成FCKConfig.EnterMode = 'br' ; // p | div | brFCKConfig.ShiftEnterMode = 'p' ; // p | div | br113、 $_REQUEST、$_GET、$_POST、$_COOKIE 的关系和区别:1.关系:$_REQUEST包含了$_GET、$_POST、$_COOKIE等的所有内容,是它们的集合体。2.通过$_REQUEST获取变量值,PHP页面因为不确定它是哪种传值方式,因此会根据php.ini中的配置来接收值。php.ini里可以设置,variables_order = “GPC”。其含义是GET,POST,COOKIE.所以PHP页面会先从$_GET中获取,再从$_POST中获取,然后从$_COOKIE中获取。新获得的值会覆盖之前获取到的值。因此从表现形式上看,$_REQUEST最后是获取$_COOKIE中的值,如果$_COOKIE中没有值,会获取$_POST中的值,如果$_POST没有获取到 ,就去$_GET中获取。如果$_GET中也没有该值,那么$_REQUEST就返回null。114、 什么是多条件查询(复合查询),如何实现多条件查询?如何实现万能查询呢?查询的时候要填写查询条件,这些条件会通过表单进行提交。首先需要检查提交的条件是否为空。如果不为空,就认为这个值是要被当作条件,我们就可以使用字符串连接的方式来组合一个sql查询语句。当执行后获取查询结果。文件上传需要注意哪些细节?怎么把文件保存到指定目录?怎么避免上传文件重名问题?1). 首现要在php.ini中开启文件上传;2). 在php.ini中有一个允许上传的最大值,默认是2MB。必要的时候可以更改;3). 上传表单一定要记住在form标签中写上enctype="multipart/form-data";4). 提交方式 method 必须是 post;5). 设定 type="file" 的表单控件,并且必须具有name属性值;6). 为了上传成功,必须保证上传文件的大小是否超标、文件类型是否符合要求,上传后存放的路径是否存在;7). 表单提交到接收页面,接收页面使用$_FILES来接收上传的文件。$_FILES是个多维数组。第一维下标是上传控件的name,二维下标分别为name/type/tmp_name/size/error。分别代表文件名、文件类型、上传到临时目录下的临时文件名、文件大小、是否有错误。如果是批量上传,那么二维下标就是数组,而并非是字符串。8). 文件上传后是被放置在服务器端临时路径下,需要使用move_uploaded_file ()函数,才可以将上传后的文件保存到指定目录。9). 为了避免上传文件重名,可以通过上传的文件名获取到文件后缀,然后使用时间戳+文件后缀的方式为文件重新命名。使用GD2库创建图像的步骤?1). 创建一个画布:imagecreate();2). 设置画布背景颜色,使用RGB设置颜色:imagecolorallocate();3). 设置文字颜色:imagecolorallocate();4). 在画布上书写文字:imagestring();5). 以 JPEG 格式将图像输出到浏览器或文件:【根据图片格式不同,函数还可以是imagepng()、imagegif()等】 imagejpeg();6). 清除图像资源:imagedestroy(); GD2库生成缩略图的步骤是什么?1). 读取希望生成缩略图的源图像,创建图像对象:【根据图片格式不同,函数也相应不同】$src_image = imagecreatefromjpeg();2). 获取原图像的宽度和高度$srcW,$srcH,根据缩放比例计算出新图像的宽度和高度$dstW、$dstH:3). 创建一个真色彩的图像对象,宽度和高度设置成刚才计算出的宽度和高度:$dst_image = imagecreatetruecolor($dstW,$dstH);4). 拷贝图像并调整大小: imagecopyresized();5). 将图像输出:【根据图片格式不同,函数也相应不同】 imagejpeg();6). 清除图像资源(将源图像资源和目标图像资源都清除) imagedestroy(); GD2库给图片增加水印如何做?添加简单的文本水印:利用imagestring()函数就可以在图片上写文本水印。增加一个图形水印:1). 读取希望增加水印的源图片,创建图像对象:【根据图片格式不同,函数也相应不同】$image = imagecreatefromjpeg();2). 创建一个水印图片的图像对象:$watermark = imagecreatefrompng();3). 拷贝并合并图像:imagecopymerge();4). 将图像输出:【根据图片格式不同,函数也相应不同】imagejpeg();5). 清除图像资源(将源图像资源和水印图像资源都清除)imagedestroy();什么是事务?什么是回滚?事务的作用是什么?事务就是组合起来的几个独立的sql操作。如果其中一项失败,那么就让这几个组合起来的sql操作都回退到未执行状态。这就是事务的回滚。mysql中MyISAM存储引擎的表不支持事务,只有InnoDB 存储引擎的表才支持事务,为了让事务正常执行,就需要让参与事务的所有数据表都设置成innoDB类型。事务被包装在了 BEGIN 和 COMMIT 语句之间。在没有使用 COMMIT 语句的情况下,对数据库的操作不是永久的,一旦运行了 ROLLBACK,就会被回退。只有执行了COMMIT,数据表中的信息才被改动。事务的目的就是为了保证数据的完整性。模拟SESSION机制实现数据库存放会话数据有什么作用?【备用】如果使用默认的SESSION机制,大家都知道默认的SESSION_ID是存放在COOKIE中,用户的身份是靠SESSION_ID来识别的,而COOKIE文件是存放在用户浏览器的客户端,这样就会带来一个问题,当用户在办公室选择一些商品到购物车,在准备下订单付款的时候,用户选择了支付宝在线的支付方式,恰巧办公室的电脑上面没有安装支付宝的数字证书,而在用户家里的电脑安装过数字证书,所以呢,用户就需要回家去支付。但是回家登录商城之后,发现购物车中精心挑选的商品都不存在了。这是为什么呢?问题就在家里电脑上的并没有存放SESSION_ID的cookie文件,因而就无法正确的读取服务器上对应session文件中的数据,所以无法将原来的选择的商品息读取过来。这样的购物车功能给用户的用户体验式非常糟糕的,所以我们就需要采取模拟SESSION机制使用数据库来存放会话数据。什么是无限极分类?要实现无限极分类,数据库建表是关键。表结构中至少需要三个字段,如果想避免递归循环,那么需要四个字段。id ,当前数据的唯一标识;typename ,类型名称;parentid , 当前类型的上一层父类型的id;path , 其中存储当前类型的id和它所有父级类型的id。这些id之间采用“-”隔开。当通过以下sql语句就可以实现,相同顶级类下的信息都在一起集中显示。select * from 表名 where 条件 order by path;无限极分类的原理是什么?要实现无限极分类,数据库表结构是关键。表结构中至少需要三个字段,如果想避免递归循环,那么需要四个字段。id ,当前数据的唯一标识;typename ,类型名称;parentid , 当前类型的上一层父类型的id;path , 其中存储当前类型的id和它所有父级类型的id。这些id之间采用“-”隔开。当通过以下sql语句就可以实现,相同顶级类下的信息都在一起集中显示。 select * from 表名 where 条件 order by path; 分页原理是什么?数据分页需要以下几个条件:参与分页的总条数 【$msg_count】 ,该值通过数据库查询可以获取到;每页显示的条数【$pagesize】 ,这个数值由自己定义;当前页的页码数 【$page】,该数值通过地址栏传递和接收;可以通过以上资料计算出总页数 【$pagecount】 ,此处需要借助ceil();【$pagecount = ceil($msg_count/$pagesize);】数据库查询借助sql语句中的【limit】来实现数据的变化:例如:select * from 表名 where 条件 limit $startnum , $pagesize;而$startnum = ($page-1)*$pagesize;123、 如何在smarty模板语言中使用php代码?借助于两个smarty内建函数。inluce_php 函数用于在模板中包含 php 脚本。例如:{include_php file="test.php"}php 标签允许在模板中直接嵌入 php 脚本。例如:{php}echo "这个是php内建函数的作用";{/php}124、 请列出至少五个smarty中的变量调节符并说明功能?default 例如:{$arr|default:’xxxx’} ,默认变量调节器,当变量为空时显示给定的默认值truncate 例如:{$articleTitle|truncate:10} , 切割字符串长度为指定的长度;count_characters 例如:{$articleTitle|count_characters} ,获取字符串长度;strip_tags 例如: {$articleTitle|strip_tags} ,去除字符串中的所有html标签;date_format 例如:{$smarty.now|date_format(‘’)} ,格式化时间戳。125、 写程序实现如下功能: a.如何判断一个字符串中是否存在一个字符?echo strstr('abcdefgcd' , 'cd');echo strpos('ab0defgcd' , 'cd'); b.如何判断一个字符串中一个字符出现的次数?echo substr_count('abcdefgcd' , 'cd'); c.如何去掉一个字符串的最后一个字符echo substr('abcdefgcd' , 0 , -1);126、 如何使用smarty的缓存、步骤?什么叫单模板多缓存?如果给整个网站开启缓存,那么$smarty->caching=1,此时缓存的时间为smarty.class.php中默认的时间,也就是3600秒。如果对每一个页面独立设置缓存,那么$smarty->caching=2 ,缓存时间就会跟display的参数模板页相挂钩,也就是可以实现对每个模板页设置不同的缓存时间。用法例如:if(!$smarty->is_cached('index.html')) {//此处可以执行数据库操作$smarty->cache_lifetime = 3600*6;}$smarty->display('index.html');对于例如新闻单条这样的页面,新闻的模板都是一个,如果开启缓存,那么所有的新闻单页的缓存都是一个,根本不会随着id的变化而变换内容。所以为了区分不同的页面缓存,需要使用单模板多缓存技术。具体做法是以id作为display的第二个参数来实现。此外对于具有分页的列表页,也必须在display中使用第二个参数,可以使用新闻类型id和当前页面合并成第二个参数。127、 写一个递归函数完成以下功能:向函数中传一个多维数组,对数组中所有的值做判断,如果值是’number’则设置该值为0?(提示:该题考的是递归的应用,因为传入的数组不确定是多少维的,所以需要递归判断)function recursive_array($arr) {if(is_array($arr)) {foreach($arr as $key=>$value) {if(is_array($value)) {$arr[$key] = recursive_array($value);} else {if($value=='number') {$arr[$key] = '0'; }}}}return $arr;}128、 使用jquery写一个全选的例子?//全选与取消全选function selectAll(flag) {for(var i=0; i<$("#fonds input").size(); i++) {$("#fonds input").get(i).checked=flag;}}//判断复选框已经被勾选了多少个?function checkFonds() {var count=0;for(var i=0; i<$("#fonds input").size(); i++) {if($("#fonds input").get(i).checked==true) {count++;}}alert(count);}//利用后代选择器和get()来获取指定的控件$(“div a”).get(2)129、 请说明smarty中fetch方法的功能?Fetch方法可以获取到页面所有的内容,并且赋值到一个变量中。如果第四个参数为true,则等同于display,直接输出到浏览器中。如果第四个参数为false,则不输出。Display方法就是第四个参数为true的fetch方法。Display = Fetch() + echo()130、 写出关于文件上传的相关函数? strrchr($filename , '.'); explode('.' , $filename);end($arr); strrpos($filename , '.');substr($filename , $pos+1); pathinfo($filename , PATHINFO_EXTENSION);date(‘YmdHis’) time() rand();mt_rand() move_uploaded_file()131、 如何将SESSION存放在数据库中,可以结合数据表设计说明.默认情况下php.ini中session.save_handler = files,也就是session是以文件形 式存储的。如果想更改为数据库或其它存储方式,那么需要更改设置,让 session.save_handler = user。除了在php.ini中配置外,还可以在PHP页面中单独配置,用ini_set ('session.save_handler, 'user')来设置session的存储方式,设置为用户自定义存储方式。设置好存储方式后,需要使用session_set_save_handler()函数。该函数是设置用户级别的session保存过程的函数。该函数有6个参数,这6个参数其实是6个自定义函数的名称,分别代表对session的开启,关闭,读,写 ,销毁,gc(垃圾回收)。示例代码如下:function open () { }function close() { }function read () { }function write () {}function destroy () {}function gc () {}session_set_save_handler ("open", "close", "read", "write", "destroy", "gc");session_start();现在你就可以象往常一样地使用session了。数据库结构如下:Session_id , session_value ,expire_time , 分别存储sessionid的id和值以及失效时间。132、 常用的正则表达式写法:中文:/^[\u4E00-\u9FA5]+$/手机号码:/^(86)?0?1\d{10}$/EMAIL:/^[\w-]+[\w-.]?@[\w-]+.{1}[A-Za-z]{2,5}$/密码(安全级别中):/^(\d+[A-Za-z]\w|[A-Za-z]+\d\w)$/密码(安全级别高):/^(\d+[a-zA-Z~!@#$%^&(){}][\\w~!@#$%^&(){}]|[a-zA-Z~!@#$%^&(){}]+\\d[\\w~!@#$%^&(){}])$/—————————————————————————— PHP初 ——————————————————————————order顺序var(variables)变量model典型 样式 模型module模数;模块;组件enctypeSEO搜索引擎优化(Search Engine Optimization)Search搜索Engine 引擎Optimization最佳化,最优化mod_rewrite模块重写CMS 内容管理系统(content manage system)electronic commerce(电子商务)gc(garbage collection)垃圾回收---------------Apache与WAMP安装---------------1.wamp安装apache (2.2版本) mysql(5.067版本) php(5.2版本)LAMP Linux下的安装负责版本控制 SVN一台机器能安装多个apache服务 但是只能安装一个MySQL服务-------------PHP上-------------PHP: personal home page 个人家庭主页 94年产生的 5.2.6版本ASP: active server page 93JSP: java server page类里面定义常量叫类常量 用const定义类常量必须有初始值define('','','false/true')里有三个参数,默认为false时区分大小写,反之不区分大小写在类里面叫做方法 在类外叫做函数常量默认为大小写敏感。::作用域操作符标量和非标量类型的区别:标量只能存一个数据,非标量能存多个数据(属性 变量名 类常量)区分大小写(变量 类名 系统自带函数 自定义函数)不区分大小写 当$_POST['user_name']等没加‘’是会先当作常量来编译3.函数可变函数:函数的名字是一个变量可选参数:参数有默认值递归(recursive)函数体内有一个循环体,自己调用自己,但他跟死循环有区别,死循环是没有尽头的, 他是无限循环,递归有尽头,他最终会获得一个值function pager( $page $msg_count $pagesize $url="?"){}----》$url="?"即为可选参数 数组的合并 array_merge() $arr1+$arr2两数组相加: 只要是具有相同的下标,则只保留首次出现的元素,后者舍去array_merge:索引数组会将后者的元素附加到前者后面;若是关联数组,相同下标,后者覆盖前者 explode() 取数组最后一个元素8.文件的操作 mkdir新建目录 rmdir删除目录 skandir输出指定路径下的文件或目录 fopen(资源)— 打开文件或者 URL fclose— 关闭一个已打开的文件 fgets — 一次读取一行 fgetc — 一次只读取一个字符 fgetss — 一次读取一行并过滤掉 HTML 标记 file_get_contents — 将整个文件读入一个字符串 fread-读取文件 file_put_contents— 将一个字符串写入文件 fwrite-写入文件 unlink-删除文件 pathinfo — 返回文件路径的信息array_push — 将一个或多个单元压入数组的末尾(入栈)array_unshift — 在数组开头插入一个或多个单元9.其它函数 输出控制函数:ob(output buffer) ob_flush 加密函数 md5 数学类函数:abs绝对值,rand随机数,ceil取整,floor,mt_rand生成更好的随机数 转换函数:explode 使用一个字符串分割另一个字符串,implode 时间函数:date(),strtotime (将字符串转换为时间戳) 处理地址栏: url_encode url_decode10.乱码问题 ASCII(American Standard Code for Information Interchange)81年产生 ANSI 美国国家标准学会( American National Standards Institute) utf-8(-8代表一次传输8个字符)可变字节编码(中文3个字节)(utf:Unicode转换格式(UCS Transformation Format) utf-16(-16代表一次传输16个字符) GBK. 国家标准扩展码(Guo-Biao Kuozhan)90年产生(双字节编码) GB2312 因为国际排行2312位(81年产生) BIG5 unicode (国际编码)可变字节编码 Latin_1 utf-8+ bom ISO:国际标准化组织(International Standardization Organization)11.数据库操作 数据库优化:char(查询速度快) varchar引擎:myisam(mysql indexed sequential access method)索引顺序访问方法支持事务的引擎:BDB ,innodbinnodb:是以inno开头的一家公司的商标 表类型就是表的存储引擎 dll:动态数据连接库 封装的类库修饰符:public,var,protected,private,static,final,abstract访问权限修饰符:public,private,protected public:类成员访问没有限制,多有外部成员都可以访问 protected:受保护的,不能被类外部成员访问,该类的直接子类可以访问,可以实现对成员属性的读、写操作 private:私有的,只能类里边的成员自己访问,类外部的成员都不能访问 一个属性被修饰为私有的(private),那么这个属性在类的外部是不可以读取和修改的,现在有一种方法 可以设置该属性既是私有的,还可以被类的外部成员读取即__get()和__set() 修饰class的修饰符:final,abstract(抽象)final被它修饰的类是不能被继承的定义属性必须要加修饰符:可以是public和var定义方法时可以有修饰符public,可以不写,默认为public如果父类中的方法被声明为final,则子类无法覆盖该方法; 如果一个类被声明为final,则不能被继承。final只能出现在class类和方法中方法前可以有public,private,protected,static,final,abstract修饰。 继承性:耦合性越低越好 const修饰,一定要有初始值 ( smarty的保留变量:{$smarty.now},{$smarty.const},{$smarty.post},{$smarty.get},{$smarty.cookies},{$smarty.config},{$smarty.session},){$smarty.capture} 调用属性时,如果前有$后边就不能有,后有前不能有,如:$this->abc self::$abc当用parent调用父类方法时,将方法自动转化为静态的 多态性:由继承 重写(覆盖)(重新写一遍)(override重写)造成的 php不支持重载(重复载入),php为弱变量语言(overload重载)抽象:一个类包含抽象方法就是抽象类,抽象类中不一定有抽象方法抽象类的定义abstract接口里可以有抽象类,还可以有类常量,通过interface来定义一个接口,实现多个接口时,接口中的方法不能有重名。接口中定义的所有方法都必须是public,这是接口的特性。接口里的方法必须被重写静态:static 不能与构造方法共存,static不能new对象,构造方法可以new对象,方法体中不能用$this在php5以前的版本中,当普通构造方法和__construct(魔术方法)共存在时,它会调用普通构造方法,它对__construct(魔术方法)是不识别的,在php5以后的版本中,当共存时他会先调用__construct(魔术方法)。析构方法是最后被执行的,被自动调用的方法单例(单态)singleton—————————————————————————— PHP中 ——————————————————————————2.jQuery 包括javascript框架和prototype.js框架选择器: 1.基本选择器: ①、$('#result')=jQuery('#result')=document.getElementById('result') ②、class选择器 $('.result') ③、元素选择器$('div') 2.子代选择器:$('#myform < input') 3.后代选择器:$('#myform input') 4.组合选择器:$('#myform < span < input')3.Ajax ajax的用处是用来异步js和xml 不仅可以获取xml数据,还可获得hmtl和json数据 ajax的优点:1.提升用户的体验2.占用带宽小3.减小服务器的负载 ajax就是把B页面的内容,显示到A页面的指定位置,实现异步传输 $.ajax() 返回其创建的 XMLHttpRequest 对象。 $.ajax({ url:, data:, type:, datatype:, success:function(这个参数里,存在被传回的页面的所有内容){} }); $.post('请求地址','传递参数','回调函数'); $.get('请求地址','传递参数','回调函数');post传值文件没有大小限制,保密性好,必须有form表单get传值安全性不高,有大小限制当地址栏里有中文时,用urlencode(编码 URL 字符串)urlencode — 编码 URL 字符串urldecode(解码已编码的 URL 字符串)4.会话控制 session:unset()和array() 是连同内存和session文件内容一起删除,而session_destroy只是将文件删除 cookie没有生命周期的叫会话cookie,随着浏览器的关闭,cookie消失 cookie有两种存在方式,一种是以文件形式存在,另一种是保存在内存里 cookie里面只能存字符串 会话控制主要是为了跨页面传值序列化是把其他的类型转换成字符串类型5.smarty代码重用(include,require,include_once,require_once)include require 比 require_once include_once 性能高 加载类文件用 require_once(最好) include_once6.PDO dsn(data source name) //数据源 $dsn = 'mysql:host=127.0.0.1;dbname=java1008a';die('到此结束'); 等同于 echo '到此结束';die;----------------------------------------------------------------------------------2.b/s与c/s简单比较,区别:--a、运行环境不同(广域网、局域网)--b、安全级别不同(低/高)--c、用户群不同(全部用户/局部用户)--d、系统升级不同(无缝升级/整体升级)--e、用户开启不同(浏览器/特制软件)--f、软件界面特点不同(信息流/用户体验) 比如:b/s就是网上的微博、博客;c/s就是在网吧打的网络游戏(奇迹、传奇等)3.php是什么:运行在服务器端的脚本语言--Hypertext Preprocessor--personal home page4.php语言能做什么--图形化用户界面程序--服务器端运行脚本程序3.php外部变量$_POST[]、$_GET[]; 特殊运算符 '.'是连接符 ".="是连接赋值 "@"屏蔽错误信息 $link=@mySQl_connect(主机,用户名,密码)5.流程控制(顺序、选择、循环)第三单元【字符串】1.字符串的三种定义方式(单引号、双引号、定界符)---单引号定义(转义\'和\)---双引号定义(转义\n \r \t \$ \\ \")---定界符方法<<<eof2.函数部分explode/implodesubstr()**str_replace/trim/ltrim/rtrimstrstr(str, search)获得指定字符串最开始出现到最后的内容strrchr(str, search)获得指定字符串最后出现到最后的内容strpos(str, search)获得指定字符串最开始出现的位置strrpos(str, search)获得指定字符串最后出现的位置ucfirst(str)将字符串第一个字母大写ucwords(str)将字符串的每个单词的第一个字母大写strlen(str)获得字符串长度strcmp(str1, str2)比较两个字符串大小, 返回负数表示 str1 小于 str2; 返回正数表示 str1 大于 str2; 返回零表示二字符串相同urlencode(str)替换所有非字母数字的字符,变为%后面跟两位16进制数,空格变为+号urldecode(str)对已%##编码的URL进行解析还原parse_url(str)解析完整的url转变为为数组parse_str(str,out)解析请求字符串转变为数组htmlspecialchars()转换html代码为实体代码printf/sprintf %b %d %c %x %s %f %X– b 整数转成二进位。– c 整数转成对应的 ASCII 字符。– d 整数转成十进位。– f 单倍精确度数字转成浮点数。– o 整数转成八进位。– s 转成字符串。– x 整数转成小写十六进位。– X 整数转成大写十六进位。1.数组和栈的操作 array_push(目标数组,字符串)将字符串压入数组的最后 array_pop(目标数组)将数组最后的元素弹出并返回2.数组和队列的操作 array_unshift(目标数组,字符串)将字符串放到数组的开始位置 array_shift(目标数组)删除数组的第一个元素并返回3.数组和指针的操作key() current() next() prev() reset() end()4.预定义数组($_GET $_POST $_FILES $_COOKIE $_SESSION)第六单元【其他常用函数】date(format,[timestamp])//格式化时间信息,并返回time()//返回当前时间戳信息mktime(hour,minute,second,month,day,year)mktime(小时,分钟,秒,月,天,年)//取得一个日期的 Unix 时间戳max()//取得最大值-echo max(1, 3, 5, 6, 7); // 7-echo max(array(2, 4, 5)); // 5-echo max(0, '1hello'); // 1hello-echo max('hello', 0); // hello-echo max(-1, 'hello'); // hello-echo max(array(2, 4, 8), array(2, 5, 7)); // array(2, 5, 7)-echo max('string', array(2, 5, 7), 42); // array(2, 5, 7)数组和非数组比较数组总认为最大mt_rand(65,94)//获得随机数round()//四舍五入取整flush()//输出准备区内容urlencode('张三')//返回字符串中,除了-_.之外的所有非字母数字部分为%后接两位16进制数,空格转化为+urldecode()//对已经编码的部分反编码var_dump()//输出变量的详细信息(八种数据类型数据都可以输出)chr(mt_rand(65,94))随机获得字母ord(chr(mt_rand(65,94)))将字母转化为数字basename(路径名)获得路径中文件名部分strtolower转换小写第七单元【php连接mysql】*mysql_connect(主机,用户名,密码) 打开一个到 MySQL 服务器的连接*mysql_select_db(数据库,连接数据库资源) 选择 MySQL 数据库*mysql_query("set names utf8");设定字符集 *mysql_close() 关闭 MySQL 链接*mysql_query(语句) 发送并执行一条sql语句mysql_fetch_row(结果资源)从结果集中取得一行结果(索引数组)mysql_fetch_assoc(结果资源)从结果集中取得一行结果(关联数组)*mysql_fetch_array(结果资源)从结果集中取得一行结果(索引/关联数组)mysql_fetch_object(结果资源)从结果集中取得一行结果(对象数组)mysql_errno()返回错误号码*mysql_error()返回错误信息*mysql_num_rows(结果资源)用于计算查询结果中所得行的数目*mysql_affected_rows()获得受影响的结果数目*mysql_insert_id()传回最后一次使用 INSERT 指令产生的自动增长 ID 值mysql_result(结果集,索引行,字段)指定获取结果mysql_free_result(结果资源)释放结果集mysql_num_fields(结果资源)用于计算查询结果中所得列的数目mysql_fetch_field(结果资源)从结果集中取得列的结果,以对象形式返回mysql_pconnect()永久连接数据库1.留言板建立数据库bbs,建立两张表leave_word和back_word(留言表和回复表) leave_word: 字段 数据类型 id int 主键、自增 title varchar(20) 标题 content text 内容 itime datetime 添加时间 back_word: id int 主键、自增 leave_id int 外键(留言id) content text 内容 btime datetime 回复时间4.删除留言,对无效、无用的留言实现删除功能(这时需要用get方式传递被删除留言id值)5.修改留言,对需要修改(get方式传递被删除留言id值,再利用隐藏域方式传递给接收页面)6.留言详细显示功能,有的留言内容比较多,在明细页面不可能全部显示出来(这时利用get方式传递留言id)7.在详细页面可以实现回复功能和回复留言展示,步骤:制作一个回复表单和接收数据页面 3.构造方法和析构方法 构造函数:实例化对象首先第一个需要做的事情就是构造函数。一个小孩出生到5岁之前,所有的事情都是父母帮助做的,包括起名字、穿衣服、吃饭等等。 析构函数:一个对象被使用完后需要做一些善后工作,这些善后工作是不需要人为干预的,例如资源释放、变量删除等。例如:一个小狗死后,主人非常爱惜它,就把它埋在了家后园的一颗树下。小狗被埋这件事情是主人做的,不是狗做的。这就是析构函数。 3.类的重写 子类和父类之间的事情,就是说父类有的方法,子类不但可以直接使用,还可以在子类中 重新定义具体内容,例如有一个父亲会驾驶汽车,那么他的儿子也会驾驶汽车,但他的儿子 可以不驾驶汽车,而驾驶飞机,这就是类方法的重写。D 1.final(最后的)关键字使用 该关键字修饰的类不能被继承 该关键字修饰的方法不能被重写 2.static(静态)关键字使用(类的内部、外部、子类) 实例化对象在内存中的分配有讲到大的数据在内存被分配到堆空间里边。现在有一个例子:有一个 "学生"这个类,里边有一个成员属性是"国家",标识该对象是属于哪个国家的,比如美国、英国、德国等 ,这个类在实例化对象时候,每个对象在内存中都会分配一个空间用于存放国家这个成员属性,如果 有100个对象,那么在内容中会分配100个相应的空间。如果这个类的使用对象是在"中国"境内,那么 每个对象的国家属性就会是一样的,即"中国",相应的在内存中会有100个空间存放100个相同的内容 这会造成空间浪费,其实到这里我们可以知道100个相同的内容用一个空间存放就可以,反正都是一样的, 这就产生了静态化概念"static"。 用static修饰的成员属性,该属性就不是对象的,而是类的。 3.self和parent关键字使用 在类的内部访问类中的成员(属性和方法),可以用"$this",该关键字泛指对象,这是访问一般的类 成员,如果访问的成员是用static关键字修饰的,就不能用"$this"了,因为用static修饰的类 成员是被类本身拥有,不属于任何对象了,这时候需要用"self"关键字修饰 self::成员 在类的外部访问类本身拥有的成员可以这样 类名::成员属性。 在子类中访问父类拥有的成员可以用parent关键字 parent::成员属性 4.const(常量)关键字使用 在php中可以定义常量,类外部用define定义,类内部用const定义。 常量的拥有者是类本身,类内部访问常量用 self::常量 类外部访问常量用 类名::常量 子类访问常量 parent::常量 6.魔术方法clone、__call、__autoload使用 clone:在一个项目里边我们有时候需要两个或多个完全一样的初始化对象,这时候可以使用clone技术 不用clone技术也可以,不过每个新的对象都需要初始化属性值,这样比较繁琐,也容易出错,使用clone就比较简单,克隆出来的多个对象彼此是独立的,互不相干。 $p2 = clone $p1; __call:在类的使用过程中,如果一个对象调用的方法不在类里边,那么这时候程序要报错,然后程序退 出不能继续运行。这样做用户体验非常不好,如果有一种方法可以使得程序报错完后可以继续运行,这样的程序给人更智能、用户体验更好的感觉,这时候就可以用__call public function __call($method_name,$args){echo "你访问的方法:";echo $method_name;echo "参数:";print_r($args);echo "不存在"; } __autoload:开发一个软件系统,往往里边会有很多类,在初始化类对象之前需要先include这个对 象对应的类文件。所有的类不能都放到一个文件(文件臃肿,不易维护),这样就会在程序开始处有很多的include列表,这样做非常繁琐,出现一个新的类就需要被include,有没有一种方法可以使得被include的类文件在实例化对象时候才引入,否则不动作,答案是有的,这时候可以用魔术方法__autoload function __autoload($className){include($className.'.php'); } 8.子类继承父类时候成员修饰符限制,子类的修饰级别大于父类。例如父类的修饰符是protected, 则子类修饰级别是protected或public。父类是public的,子类也必须是public的 1.抽象类 在类里边定义的没有方法体的方法就是抽象方法,有抽象方法的类被称为抽象类。抽象类不能实例化对象。 所谓没有方法体就是方法在声明时候没有花括号和里边的内容。 作用之处: 例如:我有一个类"动物",里边有方法"吃食"(还可以有许多其他的方法) 动物这个类可以有许多子类例如:狗、鱼、鸟等,这些子类有一个共性就是都有吃食这个方法 一般的解决方法是:定义3个类,里边都有吃食方法。这样实现没有问题的,但是如果其中一个 类没有吃食方法,这时候程序是不给报错的。我们现在要做的就是3个类中任何一个没有吃食方法 系统就要报错。这时候就需要用到抽象类了。 抽象类按照字面意思理解就是对3个类的进一步抽象。抽象出来吃食方法。 抽象类技术特性: a、抽象类不能实例化 b、类的成员方法是抽象的,则这个类也是抽象的 c、抽象方法体内没有实现细节,具体实现留给子类实现 d、继承抽象类的子类必须实现父类的抽象类,除非自己也是抽象类。 2.接口(插座实例) 当一个抽象类里边的全部方法都是抽象方法时候,这个抽象类就是"接口"。 接口技术特性: a、interface声明 b、全部接口方法是public的,因此可以省略 c、接口只定义方法,没有具体方法实现 d、实现类用implements实现接口,全部接口方法都要实现 e、接口可以多实现,中间用逗号分开 f、接口是对抽象类的抽象,抽象类是对类的抽象,类是对事物的抽象。 g、接口不能实例化 (1)、抽象类和接口有什么不同 抽象类只能单继承,接口可以多实现 抽象类里面可以有抽象方法和普通方法,而接口里只有抽象方法 抽象类里面可以有自己的属性,而接口里面只能有常量 接口里面的方法必须是public的,而抽象类不同 (2)、抽象类和接口的相似之处 抽象类里面的抽象方法在继承的时候必须都要重写,接口里面的方法也必须都要实现。 抽象类和接口都不能直接实例化,抽象类需要继承(extends),接口需要实现(implements)。 抽象类和接口都体现了多态的特性。3.jqueryjquery是js的封装包,里边有很多集成的函数可以让我们使用,jquery的宗旨就是写更少的代码实现更多的功能使用的方法:1.引进jquery包<script type="text/javascript" src='jquery-1.4.2.js'><script>2.测试jquery是否加载成功$(function(){alert("jquey加载成功");})3.获取页面的元素$('#div');通过id获取页面元素$('.div');通过class获取页面元素jquery中的事件1.$('#mydiv').click(function(){});鼠标点击事件【要写在onload事件里边】2.$('#mydiv').hover(function(){},function(){});鼠标移动到对象事件3.$('#mydiv').attr();获得对象属性信息4.$('#mydiv').attr('checked');查看单复选框的选定情况!5.$('#mydiv').css();获得对象的属性信息6.$('#mydiv').css(样式,值);给对象赋予样式7.$('#mydiv').addClass('trb');给元素class属性赋值trb;8.$('#mydiv').removeClass('trb');使元素失去class属性;9.$('#mydiv').submit(function(){});提交事件;10.$('#mydiv').keyup(function(){});键盘敲击事件;在项目中的使用:表单的验证什么是单一入口(单点入口)呢? 所谓单一入口就是整个应用程序只有一个入口,所有的实现都通过这个入口来转发, 比如说在上面我们就使用index.php作为程序的单点入口,当然这个入口文件的名字是可以由自己任意定义的。单点入口有几大好处: 第一、一些系统全局变量,都可以在这里定义。 比如说你要对数据进行初步的过滤,你要模拟session处理, 你要定义一些全局变量,甚至你要注册一些对象或者变量到注册器里面 第二、程序的架构更加清晰明了。
2023年10月08日
38 阅读
0 评论
0 点赞
2023-09-23
PHP编程实用技巧和示例
PHP编程实用技巧和示例可靠、可维护的代码是任何成功的 PHP 项目的支柱。为了实现这一点,我们可以遵循 SOLID 原则来编写代码。这些原则包括单一职责原则(SRP)、开闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)和依赖倒置原则(DIP)。单一职责原则(SRP)单一职责原则规定,一个类应该只有一个改变的理由。在 PHP 中,这意味着类应该具有单一职责。这样的设计可以提高代码的可维护性和可读性。不好的例子 - 混合职责class User { public function verify ( $username , $password ) { /* ... */ } public function sendEmail ( $message ) { /* ... */ } } 好的例子- 单一的职责class UserAuthenticator { public function verify ( $username , $password ) { /* ... */ } } class EmailSender { public function sendEmail ( $message ) { /* ... */ } } 开闭原则(OCP)开闭原则规定类应该对扩展开放,但对修改关闭。在 PHP 中,我们可以使用接口和抽象类来实现这个原则。通过定义接口和抽象类,我们可以在不修改现有代码的情况下扩展功能。不好的例子 - 直接修改class Square { public $side; public function __construct($side) { $this->side = $side; } } class AreaCalculator { public function calculate($shapes) { $area = 0; foreach ($shapes as $shape) { if ($shape instanceof Square) { $area += $shape->side * $shape->side; } elseif ($shape instanceof Circle) { $area += pi() * $shape->radius * $shape->radius; } } return $area; } } 好的例子 - 开放扩展interface Shape { public function area(); } class Square implements Shape { private $side; public function __construct($side) { $this->side = $side; } public function area() { return $this->side * $this->side; } } class Circle implements Shape { private $radius; public function __construct($radius) { $this->radius = $radius; } public function area() { return pi() * $this->radius * $this->radius; } } 里氏替换原则(LSP)里氏替换原则规定超类的对象应该可以用子类的对象替换,而不影响程序的正确性。在 PHP 中,遵守这一原则可以确保派生类维护其基类的契约。这样可以确保代码的一致性和可靠性。不好的例子 - 违反 LSPclass Bird { public function fly() { /* ... */ } } class Ostrich extends Bird { public function fly() { throw new Exception("鸵鸟不能飞"); } } 好的例子 - 遵循 LSPinterface Bird { public function fly(); } class Sparrow implements Bird { public function fly() { /* ... */ } } class Ostrich implements Bird { public function fly() { /* ... */ } } 接口隔离原则(ISP)接口隔离原则规定客户端不应被迫依赖于他们不使用的接口。在 PHP 中,这意味着创建更小、更集中的界面,而不是大型、单一的界面。这种设计可以提高代码的灵活性和可维护性。不好的例子 - 接口脓肿interface Worker { public function work(); public function eat(); public function sleep(); } 好的例子 - 接口隔离interface Workable { public function work(); } interface Eatable { public function eat(); } interface Sleepable { public function sleep(); } 依赖倒置原则(DIP)依赖倒置原则规定高级模块不应依赖于低级模块,但两者都应依赖于抽象。在 PHP 中,我们可以使用依赖注入和抽象来解耦类。这样可以提高代码的可测试性和可维护性。不好的例子 - 高级模块依赖于低级模块class LightBulb { public function turnOn() { /* ... */ } public function turnOff() { /* ... */ } } class Switch { private $bulb; public function __construct() { $this->bulb = new LightBulb(); } public function operate() { // Operate the bulb } } 好的例子 - 抽象和依赖注入interface Switchable { public function turnOn(); public function turnOff(); } class LightBulb implements Switchable { public function turnOn() { /* ... */ } public function turnOff() { /* ... */ } } class Switch { private $device; public function __construct(Switchable $device) { $this->device = $device; } public function operate() { // Operate the device } } 总之,编写符合 SOLID 原则的 PHP 代码对于创建可维护和可扩展的应用程序至关重要。通过遵守这些原则并实现所提供的示例,您可以确保您的 PHP 代码随着时间的推移更加健壮、灵活且更易于维护。请记住,应用这些原则可能需要改变思维方式和设计,但代码质量和可维护性方面的好处是值得付出努力的。祝您编写出优秀的 PHP 代码!
2023年09月23日
15 阅读
0 评论
0 点赞
2023-09-18
Nginx几款负载均衡第三方插件的安装与使用
Nginx几款负载均衡第三方插件的安装与使用0x01:插件说明nginx_upstream_hash :url_hash是nginx的第三方模块,nginx本身不支持,需要第三方模块。nginx在做负载均衡的时, 把转发的URL以hash的形式保存。这样可以保证同一个URL始终分给同一个real server,来提高访问速度。 ** 官网:https://github.com/evanmiller/nginx_upstream_hashnginx-upstream-fair :upstream-fair是比内建的负载均衡更加智能的负载均衡模块, 它采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。 官网:https://github.com/gnosek/nginx-upstream-fairngx_http_consistent_hash : 通过一致性哈希算法来选择合适的后端节点 官网:https://github.com/replay/ngx_http_consistent_hashhttps://www.nginx.com/resources/wiki/modules/consistent_hash/0x02:安装说明先分别下载这三款插件wget https://github.com/gnosek/nginx-upstream-fair/archive/master.zip -O nginx-upstream-fair.zip wget https://github.com/evanmiller/nginx_upstream_hash/archive/master.zip -O nginx_upstream_hash.zip wget https://github.com/replay/ngx_http_consistent_hash/archive/master.zip -O ngx_http_consistent_hash.zip解压对应的压缩包unzip nginx-upstream-fair-master.zip unzip nginx_upstream_hash-master.zip unzip ngx_http_consistent_hash-master.zip 查看旧Nginx的安装配置参数 /usr/local/nginx/sbin/nginx -V重新编译添加负载均衡模块./configure --prefix=/usr/local/nginx \ --user=nginx --group=nginx \ --with-http_secure_link_module \ --with-http_stub_status_module \ --with-stream_ssl_preread_module \ --with-http_ssl_module --with-http_image_filter_module \ --add-module=/home/huangjinjin/桌面/fastfds/nginx_upstream_hash-master \ --add-module=/home/huangjinjin/桌面/fastfds/nginx-upstream-fair-master \ --add-module=/home/huangjinjin/桌面/fastfds/ngx_http_consistent_hash-master关键编译参数如--add-module=nginx_upstream_hash-master文件夹安装nginxmake(1) 对于nginx_upstream_hash会出现以下错误ngx_http_upstream_hash_module 的多重定义 说明Nginx内部包含了一个同名的模块。需要对nginx_upstream_hash进行一定的代码修改,ngx_http_upstream_hash_module定义到nginx_upstream_hash-master目录修改ngx_http_upstream_hash_modulengx_module_t ngx_http_upstream_hash_module = { NGX_MODULE_V1, &ngx_http_upstream_hash_module_ctx, /* module context */ ngx_http_upstream_hash_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING };修改成ngx_module_t ngx_http_upstream_hash_module_ext = { NGX_MODULE_V1, &ngx_http_upstream_hash_module_ctx, /* module context */ ngx_http_upstream_hash_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING };应用这个结构体的代码一并修改。搜索ngx_http_upstream_hash_module改成ngx_http_upstream_hash_module_ext修改config配置文件ngx_addon_name=ngx_http_upstream_hash_module_ext HTTP_MODULES="$HTTP_MODULES ngx_http_upstream_hash_module_ext" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_upstream_hash_module_ext.c" have=NGX_HTTP_UPSTREAM_HASH . auto/have ~ c文件名字也改下ngx_http_upstream_hash_module.c 改成 ngx_http_upstream_hash_module_ext.c 这样 重新configure和make 才能成功(2)对于nginx-upstream-fair会出现以下错误nginx-upstream-fair/ngx_http_upstream_fair_module.c:543:28: error: ‘ngx_http_upstream_srv_conf_t’ has no member named ‘default_port’到nginx源码目录找到src/http/ngx_http_upstream.h文件 ngx_http_upstream_srv_conf_s结构添加in_port_t default_port;经过错误修复,编译成功后,把objs目录下的nginx文件拷贝到/usr/local/nginx目录即可:cp ./objs/nginx /usr/local/nginx0x03: 基本语法nginx_upstream_hashupstream backend_server { server 127.0.0.1:5000; server 127.0.0.1:5001; server 127.0.0.1:5002; hash $request_uri; hash_again 10; # default 0 }nginx-upstream-fairupstream mongrel { fair; server 127.0.0.1:5000; server 127.0.0.1:5001; server 127.0.0.1:5002; }ngx_http_consistent_hashupstream somestream { consistent_hash $request_uri; server 127.0.0.1:5000; server 127.0.0.1:5001; server 127.0.0.1:5002; }以下三种任君选择,不过nginx_upstream_hash与nginx-upstream-fair已经很久没更新了。
2023年09月18日
61 阅读
0 评论
0 点赞
1
...
35
36
37
...
112