复习纲领
1.PHP
1.1基础语法
1.1.1关于print,echo,var_dump,printf,print_r
print:可以输出字符串,变量的值,表达式的值等,不能输出数组等复杂数据。
echo:输出字符串和数字。
var_dump:不仅仅可以输出一个或多个表达式的值,还能输出表达式的类型,长度等其他额外的信息!并且能输出复杂数据类型,比如数组!
printf:擅长输出由静态文本和其他变量所组成的“混合产物”。(前半部分是用引号括起来的字符串和占位符,后面是占位符对应的变量)
print_r:一般打印数组,只打印数组元素的下标和元素的值,不打印其他的额外的信息。
1.1.2几个全局变量
(1)$_SERVER
1.$_SERVER['HTTP_HOST'] 请求头信息中的Host内容,获取当前域名。(如:www.baidu.com)
2.$_SERVER["SERVER_NAME"] 输出配置文件httpd.conf中的ServerName,一般情况下与HTTP_HOST值相同,但如果服务器端口不是默认的80端口,或者协议规范不是HTTP/1.1时,HTTP_HOST会包含这些信息,而SERVER_NAME不一定包含。(主要看配置文件的设置)。
3.$_SERVER["SystemRoot"] 当前服务器的操作系统。
4.$_SERVER["SERVER_ADDR"] 当前运行脚本的服务器的ip地址。
5.$_SERVER["REMOTE_ADDR"] 浏览网页的用户ip。
6.$_SERVER["DOCUMENT_ROOT"] 当前运行脚本所在的根目录。
7.$_SERVER["REQUEST_SCHEME"] 服务器通信协议,是http或https。
8.$_SERVER["CONTEXT_PREFIX"] 前缀。
9.$_SERVER["CONTEXT_DOCUMENT_ROOT"] 当前脚本所在的文档根目录。
(2)$_FILES 上传文件
1.$_FILES['userfile']['name'] 客户端文件原名
2.$_FILES['userfile']['type'] 文件类型
3.$_FILES['userfile']['size'] 上传文件大小,单位为字节
4.$_FILES['userfile']['tmp_name'] 文件被上传在服务器端保存的临时文件
5.$_FILES['userfile']['error'] 文件上传的错误码
(3)$_REQUEST
(4)$_GET
(5)$_POST
(6)GLOBALS
(7)$_SESSION
(8)$_COOKIE
1.1.3 魔术方法
__tostring():将对象当成字符串使用时候自动调用
__invoke():将对象当成函数使用时自动调用
__set():当给无法访问的属性赋值的时候自动调用
__get():当获取无法访问的属性的时候自动调用
__unset():当销毁无法访问的属性的时候自动调用
__isset():但判断一个无法访问的属性是否存在时自动调用
__call():当调用无法访问的方法时候自动触发
__callstatic():当调用无法访问的静态方法时自动调用
1.1.4 魔术常量include_once、require_once与include、require的区别
(1)对错误的处理方式:include遇到错误时,其只会发出警告级别的错误,但其并不会影响后续代码的执行!require遇到错误时,其会报致命错误,而且会导致后续代码无法执行!
(2)包含次数:include_once与require_once都可以用于进行文件包含,但是其只执行一次包含!
1.1.4 作用域
全局作用域可以调用全局变量,但是不可以调用局部变量(因为函数执行完毕后,其内部的局部变量或函数要被计算机的内存所回收)。局部作用域可以调用局部变量但不可以调用全局变量。可以通过过$GLOBALS或global方式来访问全局变量。
总结:$GLOBALS[‘i’]与global $i的区别
① $GLOBALS[‘i’]与全局变量$i是同一元素,删除其中任何一个都会对另外一个产生影响!
② global $i相当于应用全局变量$i在内存中的地址,删除global $i只是相当于移除了关联关系,但是其对原变量没有任何影响!
1.1.5 常用系统函数
(1)substr($string,$start,[$length])
$start:正数 - 在字符串的指定位置开始
负数 - 在从字符串结尾的指定位置开始
0 - 在字符串中的第一个字符处开始
$length:正数 - 从 start 参数所在的位置开始算起的长度
负数 - 从字符串末端开始算起的长度
1.1.6 递归
function digui($n){
echo $n."\t";
if($n>0){
digui($n-1);
}else{
echo "<---->";
}
echo $n."\t";
}
function erfen($data,$value,$start,$end=null){
if($end==null) $end = count($data)-1;
$index = floor(($start + $end)/2);
if($data[$index]==$value) return $index;
if(data[$index]<$value) return erfen($data,$value,$index+1);
if(data[$index]>$value) return erfen($data,$value,$0,$index-1);
}
1.1.7 Http
请求包含:请求行;请求头;请求空白行
HTTP请求头详解:
• Accept :可接受的数据类型(text/html,image/png)
• Referer :请求来源
• Accept-Language :可识别的语言类型
• User-Agent :用户代理信息(描述浏览器,可以用于判断用户的浏览器类型)
• Accept-Encoding :数据压缩算法(静态化技术)
• If-Modified-Since :(html、images、css、js)数据缓存的最后修改时间
响应包含:响应行;响应头;响应内容
HTTP响应头详解:
• Date :响应时间
• Server :服务器相关信息(Apache与PHP版本)
• Last-Modified :文件的最后修改时间
• Content-Length :响应内容的字节长度
• Content-Type :响应内容的类型
• Location :重定向
• Refresh :停留N秒后跳转
• Expires、Cache-Control :缓存文件的过期时间与缓存开关
• Content-Encoding :响应内容压缩算法
错误码:
200 :服务器端已成功接收到数据并进行了处理,然后返回到客户端(正常请求)
302 :页面重定向
304 :资源已被缓存
404 :请求的服务器端资源未找到
500 :服务器端出错
1.1.8 POST和GET区别
(1)传输内容大小:
POST 根据php.ini文件配置,默认8M
GET 2K
(2)提交方式:
POST 放在请求空白行中提交的
GET 追加在URL上面的
(3)安全性:
POST 更安全
1.1.9 sort(),asort(),ksort()
(1) sort():
根据数组中元素的值,以英文字母顺序排序,索引从0递增
(2)asort():
对数组排序,保持数组的索引和单元的关联。
(3)ksort():
根据数组中索引键的值,以英文字母顺序排序。
1.1.10 几个防止sql注入函数
addslashes():转义字符串
mysql_real_escape_string();用反斜杠转义字符串中的特殊字符
htmlspecialchars():HTML实体转移
1.2面向对象
1.2.1 面向对象三大特性
(1)封装
(2)继承
(3)多态
详情参照附件。
1.2.2 类的自动加载
(1)include
(2)__autoload
(3)spl_autoload_register()
参照word文档。
1.2.3 设计模式
(1)单例模式(三私一公)
(2)工厂模式(传递不同的参数(类名)来得到不同的对象)
(3)策略模式(传递不同的参数(实例化不同的对象),调用不同的策略(方法))
1.2.4 MVC
1.3协议
1.3.1 TCP协议的三次握手
第一次握手:建立连接,客户端发送请求到服务器,进入SYN_SEND状态,等待服务器确认。
第二次握手:服务器收到请求,确认客户端的SYN,同时发送信息数据给客户端,服务器进入SYN_RECV状态。
第三次握手:客户端收到服务器的信息,向服务器发送确认包,发送完成后,客户端和服务器都进入ESTABLISHED状态,完成三次握手。
1.4进程和线程
注意:详情可以看附件文档说明。
定义:
进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的独立单位。
线程:线程是进程的的一个实体,时CPU调度分配的基本单位,它是比线程更小的能独立运行的基本单位。
差别:
进程有独立的地址空间,一个进程崩溃了后,在保护模式下不会对其他进程造成影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮。但是在进程切换时,耗费资源大,效率要差一点。但是对于一些平时进行并且又有共享某些变量的并发操作,只能用线程不能用进程。
2.Apache
3.Nginx+PhpFpm
4.Linux
4.1几个常用命令
top 对系统处理器状态的监控,显示各个进程的资源占用情况。
ps 显示系统进行在瞬间的运行状态。
df 磁盘空间占用情况。
grep 过滤文本。根据指定字符串对文件的每一行搜索,如果找到,返回该行内容。
5.MySql
5.1基础操作
5.1.1库的操作
create database [if not exists] 数据库名称 [charset utf8];//创建数据库
drop database 数据库名称;//删除数据库
show databases;//查询数据库
5.1.2表操作
创建表:
create table 数据表名称(
//定义列(表头)字段
) engine = 数据表引擎 default charset=ut8(编码格式) collate=_bin|_ci|_cs(校对集);
删除数据表: drop table 数据表名称;
更改数据表名称: alter table 原数据表名称 rename to 新数据表名称;
查询表: show tables; 查看当前数据库下的所有表
插入数据: insert into 数据表名称(字段1,字段2) values (字段1对应的值,字段2对应的值);
删除数据: delete from 数据表名称 where 删除条件;
更新: update 数据表名称 set 字段名称1=更新后的值1,字段名称2=更新后的值2 where 更新条件;
查询:select * from 数据表名称 where 查询条件;
5.2 数据引擎(MyISAM与InnoDB)
特点不同:MyISAM 擅长大批量数据的查询与写入操作,支持全文检索功能。InnoDB支持事务处理、支持行级锁,支持外键。
数据结构不同:MyISAM有框架文件,数据文件,索引文件。InnoDB只有索引文件。
5.3 char类型与varchar类型
在MySQL中,char类型与varchar类型都可以用于描述字符串,但是两者还是存在很多不同:
① char类型(定长类型,长度固定)
char类型适合存储长度固定的数据,在MySQL中,其定义时必须明确指定字符串长度,基本语法:
char(n) :n的最大值为255个字符,和字符集没有任何关系。理论上可以存取255个英文字符或255个汉字。
② varchar类型(变长类型,长度不是固定的)
varchar类型适合存储区长度不固定的数据,在MySQL中,其定义时必须明确指定字符串长度,基本语法:
varchar(n) :n代表字符数,和字符集有关。如果是latin1(拉丁文),可以存取65535个字符;如果是gbk格式,忽略其他参数,理论上能存储65535/2 = 32767(理论值);如果是utf8格式,忽略其他参数,理论上能存储65535/3 = 21845(理论值)。但是理论值不代表实际值,因为varchar类型比较特殊,在计算机底层其还需要1-2字节长度存取varchar的长度。
5.4 字段约束
--
5.5 表查询
5.5.1 联合查询
基本语法:
select */字段 from 数据表1
union [distinct|all]
select */字段 from 数据表2
union [distinct|all],默认为distinct
select */字段 from 数据表3
注意:
1.union 连接查询,如果出现重复性数据(默认去重)
2.union all 连接查询,如果出现重复性数据(人为保留)
3.如果在union联合查询时,出现了order by + union,对于每一个select查询都必须要使用圆括号进行括起来。
意义:在MySQL高级优化中,有一种优化手段叫做物理分表技术。假设我们的项目中一共有1亿条记录,如果放在一个表中,数据量就会更大。实际项目应用中,我们通过会创建10个一摸一样的数据表,然后把所有记录平均分配到这些数据表中,我们把这种就称之为“物理分表技术”。
5.5.2 交叉查询
基本语法:
select */字段列表 from 数据表1 cross join 数据表2;
返回结果:
字段 :表1中的字段数 + 表2中的字段数
记录 :表1 * 表2的笛卡儿积
5.5.3 内连接查询
基本语法:
select * from 数据表1 [inner] join 数据表2 [inner] join 数据表3 on 关联条件
定义:
内连接查询其实就是多张表进行关联查询,其多张表中关联查询后只会返回满足条件的结果,我们把这种查询就称之为“内连接查询”。
原理:
两个表中所有满足关联条件的查询结果。拿inner join左边的中的所有记录与inner join 右边的表进行匹配,如果满足on的关联条件,则显示这条记录,否则忽略这条记录。
详解:
① 首先系统默认会自动对左表进行loop遍历操作
② 每遍历一次,系统会自动拿当前遍历的记录到右表中进行数据匹配
③ 如果匹配到满足条件的结果,则保留这条数据,反之,则自动忽略该数据
由此可知,内连接查询只会返回满足匹配条件的结果,其他数据会自动忽略。
5.5.4 外链接查询
基本语法:
左外链接查询:select */字段列表 from 数据表1(左表) left join 数据表2(右表) on 关联条件;
右外链接查询:select */字段列表 from 数据表2(左表) right join 数据表2(右表) on 关联条件;
返回结果:
左表中的字段 + 右表中的字段。
左外链接查询,最终的记录数与左表中的记录是一致的。原理分析:左外连接查询,系统默认会自动保留左表中的所有记录,然后loop遍历左表中的所有记录与右表中的记录进行关联匹配,如果查询到关联结果,则返回关联数据。反之,则返回NULL。
右外链接查询,最终的记录数与右表中的记录是一致的。原理分析:右外连接查询,系统默认会自动保留右表中的所有记录,然后loop遍历右表中的所有记录与左表中的记录进行关联匹配,如果查询到关联结果,则返回关联数据。反之,则返回NULL。
5.5.5 自然连接查询
自然内连接,基本语法:
select */字段列表 数据表名称1 natural join 数据表名称2;
定义:
自然连接是一种自动连接查询,其默认会自动寻找两个关联表中的同名字段作为关联条件。在实际应用开发中,自然连接查询主要用于(内连接、外连接)
5.5.6 子查询
sql分类:
① where子查询
② from子查询
③ exists子查询
查询类别进行划分:
① 标量子查询(子查询的结果是一个固定值,如查分类下的产品信息)
如:select * from it_product where cid = (select cid from it_category where name=’成功学’);
② 列子查询(子查询的结果返回的是一个列信息,可能有多个结果)
关键字:all,any,not in,in
如:select * from it_product where cid in (select cid from it_category)
③ 行子查询(子查询的结果返回的是一个行信息)
如:select * from it_product where (cid,price) = (select max(cid),max(price) from it_product);
④ 表子查询(子查询的结果可以是一个表)
如:select * from (select * from 数据表 order by score desc;) as 别名 group by sex;
exists子查询:
基本语法:
select */字段别名 from 数据表 where exists(select */字段别名 from 数据表 where 外层表.字段 = 内层表.字段);
运行原理:
① 读取外层数据表的所有记录,然后使用loop进行遍历
② 得到每次遍历的结果后,放到exists中的子查询进行匹配过,如果匹配成功,则exists子查询返回1(真),反之则返回0(假);
③ 如果where 0就代表当前这表记录要进行忽略,如果where 1就代表这条记录是有效的,保留。
5.6 Mysql优化
5.6.1 优化切入点
存储层(数据): 存储引擎、列类型(数据类型的选择)、数据表规范(三范式与逆范式)
设计层(单台服务器): 索引、缓存、分区
架构层(多台服务器): 读写分离(核心技术主从复制)和分布式
sql语句层: 更合适的sql语句
5.6.2 读写分离
原理:mysql中有一种日志,叫做bin日志(二进制日志),会记录下所有修改过数据库的sql语句。主从复制的原理实际是多台服务器都开启bin日志,然后主服务器会把执行过的sql语句记录到bin日志中,之后从服务器读取该日志,在从服务器再把bin日志中记录的sql语句同样的执行一遍。这样从服务器上的数据就和主服务器相同了。
实现:(1)主从要开启log-bin日志
开启主服务器的bin日志:my.cnf--->log-bin=mysql-bin,设置唯一的server_id server-id=1;
(2)主服务器要授权一个账号,让从服务器使用该账号,来读取log-bin 日志的内容。
主服务器添加用户:grant 具体的权限 on 数据库.数据表 to ‘用户名’@’主机ip’ identified by ‘密码’
如:grant all on *.* to ‘user1’@’192.168.10.10’ identified by ‘456’;
(3)主从里面详细的配置过程。
开启主服务器的bin日志,主服务器要设置一个唯一的server-id的值。
给从服务器设置授权用户:grant replication slave on *.* to user@192.168.10.10 identified by ‘456’
记住主服务器里面最新的log-bin日志的名称和pos位置show master status
开启从服务器的bin日志。log-bin=mysql-bin
从服务器要设置一个唯一的server-id的值,不能和主服务器重复。
停止从服务器。stop slave
在从服务器上面执行具体如下的配置.change master to master_host=‘主服务器的ip地址’,master_user=‘主服务器上用于同步数据的账号’,master_password=‘同步账号的密码’,master_log_file=‘bin日志的文件名’,master_log_pos=bin日志中position值。
开启从服务器 start slave;
测试是否成功:show slave status
5.6.3 sql语句优化
(1)尽量选择较小的列
(2)将where中用使用比较频繁的字段建立索引
(3)select字句避免使用*
(4)避免在列上计算
(5)针对慢的语句使用explain来分析语句的具体执行情况
5.6.4 慢日志查询
参数说明:
slow_query_log :是否开启慢查询日志,1表示开启,0表示关闭。
slow-query-log-file:新版(5.6及以上版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.log
long_query_time :慢查询阈值,当查询时间多于设定的阈值时,记录日志。
log_queries_not_using_indexes:未使用索引的查询也被记录到慢查询日志中(可选项)。
log_output:日志存储方式。log_output='FILE'表示将日志存入文件,默认值是'FILE'。log_output='TABLE'表示将日志存入数据库,这样日志信息就会被写入到mysql.slow_log表中。MySQL数据库支持同时两种日志存储方式,配置的时候以逗号隔开即可,如:log_output='FILE,TABLE'。日志记录到系统的专用日志表中,要比记录到文件耗费更多的系统资源,因此对于需要启用慢查询日志,又需要能够获得更高的系统性能,那么建议优先记录到文件。
log_slow_admin_statements:是否将慢管理语句例如ANALYZE TABLE和ALTER TABLE等记入慢查询日志
日志分析工具:
在生产环境中,如果要手工分析日志,查找、分析SQL,显然是个体力活,MySQL提供了日志分析工具mysqldumpslow
-s, 是表示按照何种方式排序,
c: 访问计数
l: 锁定时间
r: 返回记录
t: 查询时间
al:平均锁定时间
ar:平均返回记录数
at:平均查询时间
-t, 是top n的意思,即为返回前面多少条的数据;
-g, 后边可以写一个正则匹配模式,大小写不敏感的;
比如:
得到返回记录集最多的10个SQL。
mysqldumpslow -s r -t 10 /database/mysql/mysql06_slow.log
得到访问次数最多的10个SQL
mysqldumpslow -s c -t 10 /database/mysql/mysql06_slow.log
得到按照时间排序的前10条里面含有左连接的查询语句。
mysqldumpslow -s t -t 10 -g “left join” /database/mysql/mysql06_slow.log
另外建议在使用这些命令时结合 | 和more 使用 ,否则有可能出现刷屏的情况。
mysqldumpslow -s r -t 20 /mysqldata/mysql/mysql06-slow.log | more
5.7 数据库的事务
事务是作为一个单元的一组有序的数据库操作。如果组中所有操作都成功,则事务成功。即使有一个操作失败,事务也不会成功。事务成功,则完成所有数据库操作,失败则回滚,所有操作均取消。四大特性:原子性,隔离性,一致性,持久性。
5.8 索引
5.8.1 索引类型
UNIQUE唯一索引:不可以出现相同的值,可以有NULL值
INDEX普通索引:允许出现相同的索引内容
PRIMARY KEY主键索引:不允许出现相同的值,且不能为NULL值,一个表只能有一个primary_key索引
fulltext index 全文索引:不常用
组合索引与前缀索引:最左原则
5.8.2 索引创建的依据
1.维度高的列创建索引
2.对 where,on,group by,order by 中出现的列使用索引
3.对较小的数据列使用索引,这样会使索引文件更小,同时内存中也可以装载更多的索引键
4.为较长的字符串使用前缀索引
5.使用组合索引,可以减少文件索引大小,在使用时速度要优于多个单列索引
5.8.3 索引优化
(1)尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
(2)可以在num上设置默认值0,确保表中num列没有null值,然后这样查询
(3)尽量避免在 where 子句中使用!=或<>,or操作符,尽量不使用in,not in,%,否则将引擎放弃使用索引而进行全表扫描
(4)尽量避免在 where 子句中进行表达式操作,函数操作,否则将引擎放弃使用索引而进行全表扫描
(5)不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算
5.9 MySQL表优化方案
5.9.1 单表优化方案
1字段:
(1)尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNED
(2)VARCHAR的长度只分配真正需要的空间
(3)使用枚举或整数代替字符串类型
(4)单表不要有太多字段,建议在20以内
(5)避免使用NULL字段,很难查询优化且占用额外索引空间
(6)用整型来存IP
2索引:
(1)在WHERE和ORDER BY命令上涉及的列建立索引,可根据EXPLAIN来查看是否用了索引还是全表扫描
(2)字符字段只建前缀索引,最好不要做主键
(3)不使用null值
3SQL:
(1)可通过开启慢查询日志来找出较慢的SQL
(2)不做列运算
(3)避免多表查询
(4)列表数据不要拿全表,要使用LIMIT来分页,每页数量也不要太大
4引擎:
(1)MyISAM
(2)InnoDB
5.9.2 读写分离
如上已经介绍。
5.9.3 缓存
6.NoSql(Redis,Memcache,MongoDB)
6.1 Memcache
6.1.1 关于memcache的常用的几个参数
-p :指定对于tcp协议监听的端口号默认为11211
-d :start/restart/stop memcache服务启动/重启/停止
-d: install/uninstall memcache安装/卸载memcache的守护进程
-u: 指定用户(只有在Linux下的root)
-m:指定memcache能够使用的最大内存默认为64M
-c:指定memcache能够处理的最大并发量,默认是1024
可以通过memcache.exe -help查看还有那些参数可以使用
6.1.2 关于memcache的命令
set:用于为某个key赋值,key不存在则创建,存在则修改
语法:set key(键名) 0|1(数据是否压缩) time(有效时间) 3字符长度
get:获取某个key的值
语法:get key
add:添加一个key并且赋值
语法:add key(键名) 0|1(数据是否压缩) time(有效时间)
delete:删除某个key
语法:delete key
incr:自增长某个值
语法:incr key num
decr:自减
语法:decr key num
flush_all:清空memcache中所有的数据
语法:flush_all
stats:查看memcache服务器性能的命令
6.1.3 存储php的数据类型
整形,浮点型,字符串型,数组,字符串,null
在memcache中每个item的key最多250个字节超出无法存储
每个item能够存储的最大数据量为1M,超出不能存储
在memcache中有一种回收机制LRU(惰性),该机制能够将memcache中get次数比较少的key回收
6.2 Redis
6.2.1 常用指令
(1)string类型。String是最简单的类型,一个 key对应一个Value,String类型是二进制安全的。Redis的 string可以包含任何数据,比如jpg图片或者序列化的对象。
set:设置键,值
语法:set 键名称 值
get:获取key对应的string值,如果key不存在返回 nil
语法:get 键值
Setnx:设置键时,先判断一下该键是否存在,如果key已经存在,返回0,nx是not exist的意思。 若键已经存在,则设置不成功,返回0 。
语法:同set
setex:设置key对应的值为string类型的value,并指定此键值对应的有效期。
语法:setex 名称 有效期 值
setrange:替换字符串中某些字符
语法:setrange 键名称 开始替换的序号 替换为的内容
mset:一次设置多个key的值,成功返回ok表示所有的值都设置了,失败返回0表示没有任何值被设置。
mset 名称1 值1 名称2 值2
msetnx:一次设置多个key的值,成功返回ok表示所有的值都设置了,失败返回0表示没有任何值被设置,但是不会覆盖已经存在的key。
getset:设置key的值,并返回key的旧值。(设置新值,获取旧值。)
getrange :获取key的value值的范围内的子字符串
mget:一次获取多个key的值,如果对应key不存在则对应返回nil。
incr:对key的值做加加操作,并返回新的值。
incrby:同incr类似,加指定值,key不存在时候会设置key,并认为原来的value是0。
语法:incrby 键 加的数字
decr:key的值做减减操作。
decrby:同decr类似,减指定值。
append:给指定key的字符串追加value,返回新字符串值的长度。
strlen:取指定key的value值的长度。
(2)hashes类型。Redis hash是一个string类型的field和value的映射表。它的添加、删除操作都是0(1)(平均)。hash特别适合用于存储对象。相较于将对象的每个字段存成单个string类型。将一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象。
hset:设置hash field为指定值,如果 key不存在,则先创建。
语法:hset 哈希名称 字段名称 值
hget:取出hash field的值。
语法:hget 哈希名称 字段名称
hsetnx:设置hash field为指定值,如果key不存在,则先创建,如果存在则返回0。
hexists:测试指定的 field是否存在。
hdel:删除指定hash的field
语法:hdel 哈希名 field
(3)lists类型。list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等,操作中key 理解为链表的名字。redis的list类型其实就是一个每个子元素都是string 类型的双向链表。我们可以通过push、pop操作从链表的头部或者尾部添加删除元素,这样list即可以作为栈,又可以作为队列。
lpush:在key对应list的头部添加字符串元素。
语法:lpush 链表名称 值内容
lrange:获取链表里面的值
语法:lrange 链表名称 0 -1(0 和 -1 表示取值范围,从头部到尾部。)
rpush:在key对应list的尾部添加字符串元素。
语法:rpush 链表名称 值内容
linsert:在key对应list的特定位置前或后添加字符串。
语法:linsert 链表名 before(/after) 值
lset:设置list中指定下标的元素值。注:下标从0开始计算
lpop:从list的头部删除元素,并返回删除元素。
rpop:从 list的尾部删除元素,并返回删除元素。
rpoplpush:从第一个list的尾部移除元素并添加到第二个list的头部。
(4)sets类型。set是集合,它是string类型的无序集合。set是通过hash table实现的、添加、删除和查找的复杂度都是0(1)。对集合我们可以取并集、交集、差集。通过这些操作我们可以实现sns中的好友推荐和blog的tag功能。
sadd:向名称为key 的set中添加元素。
语法:sadd 集合名 元素
smembers:获取集合中内容
语法:smembers 集合名称
srem:删除名称为key的set中的元素。
spop:随机返回并删除名称为key的 set中一个元素。
sdiff :返回所有给定key与第一个key的差集。
sinter:返回所有给定key的交集。
(5)sorted sets类型。sorted set是set的一个升级版本,他在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解为有两列的mysql表,一列存value,一列存顺序。操作中的key理解为zset的名字。
zadd :向名称为key的zset中添加元素。如果该元素存在,则更新其顺序。
语法:zadd 集合名 序号 内容
zrange:获取有序集合中的内容。
zrem:删除名称为key的zset中的元素member。
zincrby:如果在名称为key的zset中已经存在元素member,则该元素的score增加increment否则向该集合中添加该元素,其score的值为increment。
(6)redis常用指令
expire:设置一个key的过期时间。
move:将当前数据库中的key转移到其它数据库中。
persist:移除给定key的过期时间。
ttl:获取过期时间。
select:选择数据库。redis数据库编号从0-15,我们可以选择任意一个数据库来进行数据的存取。
dbsize:返回当前数据库中key的数目。
info:获取服务器的信息和统计。
config get:获取参数的配置。//config get *
flushdb :删除当前选择数据库中的所有key
flushall:删除所有数据库中的所有的 key
6.2.2 Redis与memcache比较说明
(1)数据类型:memcache支持的数据类型就是字符串,redis支持的数据类型有字符串,哈希,链表,集合,有序集合。
(2)持久化:memcache数据是存储到内存里面,一旦断电,或重启,则数据丢失。redis数据也是存储到内存里面的,但是可以持久化,周期性的把数据给保存到硬盘里面,导致重启,或断电不会丢失数据。
(3)数据量:memcahce一个键存储的数据最大是1M,而redis的一个键值,存储的最大数据量是1G的数据量。
6.2.3 持久化机制
(1)snapshotting(快照)默认方式
工作方式:一次性把redis中全部的数据保存一份存储在硬盘中(备份文件名字默认是dump.rdb),如果数据非常多(10-20G)就不适合频繁进行该持久化操作。
触发:在redis里面的快照方式,有触发条件的,只要满足条件,就自动触发。
save 600 1//600秒内如果有1个KEY值改变则触发
人为触发:./redis-cli -a 密码 bgsave
备份地址:可以设置保存位置,和备份的文件名,通过配置文件(redis.conf)进行修改。备份文件名字默认是dump.rdb,我们也可以自己修改。
缺点:于快照方式是在一定间隔做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。
(2)append-only file( 缩写aof)的方式
工作方式:把用户执行的每个“写”指令(添加、修改、删除)都备份到文件中,还原数据的时候就是执行具体写指令而已。
开启:在配置文件里面,把 appendonly no 改成appendonly yes即可。
触发:
appendfsync always 每次收到命令就写入磁盘。慢,但是持久化好。
appendfsync everysec 每秒强制写入磁盘一次,在性能和持久化方面做了折中,推荐。
appendfsync no 完全依赖os,性能好,持久化没有保障。
重写:执行重写可以在登录状态下执行,直接输入bgrewriteaof,也可以在未登录状态下执行。
语法:./bin/redis-cli –a 密码 bgrewriteaof
6.3 mongoDB
6.3.1 概念
(1)文档:文档是mongoDB中数据的基本单元,类似关系数据库的行, 多个键值对有序地放置在一起便是文档。
MongoDB区分大小写的数据类型。
每一个文档尺寸不能超过16M。
(2)集合:集合就是一组文档,多个文档组成一个集合,集合类似于 mysql里面的表 。
无模式是指,在同一个集合中可以包含不同格式的文档。
模式自由(schema-free):意思是集合里面没有行和列的概念。
(3)数据库:多个集合可以组成数据库。一个mongoDB实例可以承载多个数据库,他们之间完全独立。 Mongodb中的数据库和Mysql中的数据库概念类似,只是无需创建。
6.3.2 语法
(1)在集合里面插入文档
db.集合名.insert({json文档})
(2)查看集合里面的文档内容
db.集合名.find()
(3)删除数据库里面的集合
db.集合名.drop()
(4)删除数据库
db.dropDatabase()
(5)添加文档
db.集合名.insert({键1:值1,键2:值2……..})
(6)删除文档
db.集合名.remove({json条件})
(7)修改文档
db.集合名.update({条件},{新文档})
(8)查询操作
db.集合名.find({条件})
(9)添加管理员
注意:在mongodb里面的用户是属于数据库的,每个数据库有自己的管理员,管理员登录后,只能操作所属的数据库。在admin数据库中创建的用户是超级管理员,登录后可以操作任何的数据库。
use 数据库名称-->db.addUser(用户名,密码,是否只读)
(10)删除管理员
直接从system.users集合里面,删除管理员的文档信息,即可删除了该管理员。
6.3.2 主从复制
主服务器(1台):改;从服务器(可以N台):读
7.微服务(Swoole,Kafka)
8.常用算法和数据结构
8.1PHP常用算法题
8.1.1 求1-100之间的素数
function getSuShu($max=100){
$res = [];
for($i=2;$i<=$max;$i++){
$flag = true;
for($j=2;$j<$i;$j++){
if($i%$j==0){
$flag = false;
break;
}
}
if($flag){
$res[] = $i;
}
}
var_dump($res);exit;
return $res;
}
8.1.2 冒泡排序
function maopao($arr){
for($i=0;$i<count($arr)-1;$i++){
for($j=0;$j<count($arr)-1-$i;$j++){
if($arr[$j]>$arr[$j+1]){
$temp = $arr[$j];
$arr[$j] = $arr[$j+1];
$arr[$j+1] = $temp;
}
}
}
return $arr;
}
把1234567890转化为1,234,567,890?
function f1($str){
$str = strrev($str);
$str = chunk_split($str,3,',');
$str = ltrim(strrev($str),',');
return $str;
}
字符串反转
function fanzhuan($str){
}
9.前端
9.1基础语法
9.1.1无穷大的数
console.log(Number.MAX_VALUE+Number.MAX_VALUE);
console.log(10/0);
9.1.2 六种数据类型
number(int/float) string boolean null undefined object
9.1.3 js中的逻辑运算
|| 和 && 逻辑运算的结果为一个操作,可能造成短路运算
!的结果是boolean
9.1.4 几个关键字
arguments 可以在函数里边接收实参信息。
callee 在函数内部使用,代表当前函数的引用。相当于php里面的递归
console.log()可以传递一个js语法句体,可以在上下文中执行,如果加了双引号,当成字符串,原样输出
eval()传递一个被双引号包裹的js句体,可以在上下文执行,不加双引号,不会执行任何操作
9.1.5 变量
全局变量:
① 在函数外部声明的变量
② 函数内部不使用“var”声明的变量(函数调用之后起作用)
局部变量:
在函数内部声明的变量,变量前边有”var“关键字。
9.1.6 DOM操作
(1)元素节点获取
document.getElementById(id属性值)
document.getElementsByTagName(tag标签名称)
document.getElementsByName(name属性值)
(2)文本节点获取
<div>hello</div>
需要借助div元素节点再获得其内部的文本节点.
var dvnode = document.getElementsByTagName(‘div’)[0]
dvnode.firstChild
(3)兄弟节点
firstChild、lastChild:父节点获得第一个/最后一个子节点
nextSibling:获得下个兄弟节点
previousSibling:获得上个兄弟节点
childNodes:父节点获得内部全部的子节点信息
(4)父节点
节点.parentNode
9.1.7 事件
常见事件
onclick onmouseover onmouseout onkeyup onkeydown onblur onfocus onsubmit
dom1级方式设置
①<input type=”text” name=”username” onclick=”函数名称()” />
function 函数名称(){this[window]}
②<input type=”text” name=”username” onclick=”过程代码var a=10;var b=20;alert(123);this[itnode]” />
③itnode.onclick = function(){this[itnode]}
④itnode.onclick = 有名函数名称;
function 函数名称(){this[itnode]}
dom2级方式设置
itnode.addEventListener(事件类型,事件处理[,事件流]);
itnode.removeEventListener(事件类型,事件处理[,事件流]);
9.1.8 事件流
多个彼此嵌套元素,他们拥有相同的事件,最内部元素事件被触发后,外边多个元素的同类型事件也会被触发,多个元素他们同类型事件同时执行的效果称为“事件流”.
事件由里向外执行是冒泡类型,反之是捕捉类型.
9.1.9 加载事件onload
<body onload=”加载函数()”>
window.onload = 匿名/有名函数; //推荐
9.1.10 作用域链
定义:变量在当前环境now、内部环境f1、内部深层环境f2/f3....都起作用的现象形成了一个链条,这个链条就称为变量的"作用域链"。
作用:
函数可以“先使用、后声明”,原因是函数有“预加载”过程(函数声明先于其他执行代码进入内存)。本质还是函数的声明在前,使用在后。
内部环境可以访问外部环境的变量,反之不然。
变量的作用域是声明时决定的,而不是运行时。
9.1.10 闭包
定义:闭包就是一个函数,两个函数彼此嵌套,内部函数就是闭包,形成闭包条件是内部函数需要通过return给返回出来。
作用:调用其上级环境的变量信息。
9.1.11 对象
创建:
① 字面量方式创建
② 构造函数创建对象
③ Object方式创建对象
9.1.12 继承和原型链
9.1.13 正则
10.PHP框架(TP,CI,YII)
11.系统设计(负载均衡,PRC,反向代理)和常用的问题解决方案
11.1负载均衡
11.1.1 实现策略
(1)轮询,
负载均衡器把请求轮流转发给后面的web服务器。
(2)ip哈希,
同一个地址的客户端,始终请求同一台主机。
(3)最少连接
负载均衡器把请求给负载最小的哪台服务器。
11.1.2 Nginx 实现一个简单的负载均衡
(1)配置两个基于端口的虚拟主机。进入到nginx/conf/extra目录,新建一个81.conf和82.conf,两个文件。并且部署两个主机目录。
(2)在nginx.conf配置文件里面,添加一个连接池。
upstream web123{
server www.123.com:81
server www.123.com:82
}
(3)在nginx.conf配置文件里面,配置一个基于域名的(www.123.com)的虚拟主机
(4)我们在nginx.conf配置文件里面,使用include把81.conf和82.conf引入