2023年php面试题

发布时间 2023-04-04 10:53:07作者: 轻鸿羽过

                                   Php面试题

1、isset和empty的区别?
Isset测试变量是否被赋值,如果这个变量没被赋值,则返回false,empty是判断变量是否为空,当赋值为0,null,’’,返回true为真。他们之间最大的区别就是当一个变量被赋值0时,empty判断它为空,而isset判断它有值不为空。
 
2、error reporting的错误级别?
函数语法:error_reporting(report_level)
如果参数 level 未指定,当前报错级别将被返回。下面几项是 level 可能的值:
值 常量 描述
1 E_ERROR 致命的运行错误。错误无法恢复,暂停执行脚本。
2 E_WARNING 运行时警告(非致命性错误)。非致命的运行错误,脚本执行不会停止。
3 E_PARSE 编译时解析错误。解析错误只由分析器产生。
4 E_NOTICE 运行时提醒(这些经常是你代码中的bug引起的,也可能是有意的行为造成的。)
 
3、语句中include和require的区别?
require("MyRequireFile.php");这个函数通常放在 PHP 程序的最前面,PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部份。
include("MyIncludeFile.php");这个函数一般是放在流程控制的处理部分中。PHP 程序网页在读到 include 的文件时,才将它读进来。
require一个文件存在错误的话,那么程序就会中断执行了,并显示致命错误include一个文件存在错误的话,那么程序不会中端,而是继续执行,并显示一个警告错误。
include有返回值,而require没有。
 
4、php转义特殊字符的函数有哪些?
php转义特殊字符的函数是:
1、addslashes(),使用反斜线引用字符串,对字符进行转义;解决sql注入问题。
2、mysql_real_escape_string(),转义SQL语句中使用的字符串中的特殊字符;
3、htmlspecialchars()。解决跨脚本攻击问题。
 
5、什么是面向对象以及特点?
(1)提到面向对象,自然会想到面向过程,面向过程就是分析解决问题所需要的步骤,然后用函数把这些步骤一一实现,使用的时候一个一个依次调用就可以了。面向对象则是把解决的问题按照一定规则划分为多个独立的对象,然后通过调用对象的方法来解决问题。当然,一个应用程序会包含多个对象,通过多个对象的相互配合来实现应用程序的功能,这样当应用程序功能发生变动时,只需要修改个别的对象就可以了,从而使代码更容易得到维护。
(2)面向对象的特点
面向对象的特点主要可以概括为封装性、继承性和多态性,接下来针对这三种特性进行简单介绍。
(3)封装是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界知道具体实现细节,这就是封装思想。
继承性主要描述的是类与类之间的关系,通过继承,可以在无须重新编写原有类的情况下,对原有类的功能进行扩展。
多态性指的是在程序中允许出现重名现象,它指在一个类中定义的属性和方法被其他类继承后,它们可以具有不同的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义。
 
6、怎样实现一个静态化常用的设计模式?
  1. 动态URL地址设置静态形式(伪静态)
  2. buffer
buffer其实就是缓冲区,一个内存地址空间,主要用于存储数据区域。
编写一个buffer.php文件,并保存,并不是直接将文件内容保存在磁盘里,而是先把内容写入到buffer中,当一个buffer写满的时候,会把buffer中的数据写入到磁盘里,这是操作系统的buffer。
  1. PHP实现页面纯静态化
纯静态化的html文件放在服务器端的磁盘。
  1. 基本方式:
file_put_contents()函数;
  1. ob函数
ob_start(); 打开输出缓冲区
ob_get_contents(void);返回输出缓冲区内容
ob_clean(void);清空输出缓冲区
ob_get_clean(void);得到当前缓冲区的内容并删除当前输出缓冲区
  1. PHP处理伪静态:正则表达式匹配
7、什么是类?有哪些特征?
在PHP中,类(Class)是变量与作用于这些变量的函数的集合,是具有相同属性和操作的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和操作两个主要部分。
通过不同的方法创建对象(传递不同数量的参数)。在PHP中就是通过类来实现的。
function我们称之为在类中被定义的函数。
在函数中访问类成员变量时,你应该使用$this->var_name。
定义好的类则必须使用new关键词来生成对象:$A_student=new Student;
 
8、tp框架的生命周期?
(1)入口文件,
public/index.php文件
(2)引导文件,
start.php文件就是系统默认的一个引导文件。start.php引导文件首先会调用base.php基础引导文件
(3)注册自动加载
系统会调用 Loader::register()方法注册自动加载
(4)注册错误和异常机制
    执行Error::register()注册错误和异常处理机制。
(5)应用初始化
(6)URL访问检测
    5.0的URL访问必须是PATH_INFO方式(包括兼容方式)的URL地址。
(7)路由检测
(8)分发请求
建议统一使用return返回数据,而不是echo输出,如非必要,请不要使用exit或者die中断执行。
(9)响应输出
控制器的所有操作方法都是return返回而不是直接输出,系统会调用Response::send方法将最终的应用返回的数据输出到页面或者客户端。
(10)应用结束
 
9、类的自动加载怎么实现?
       A,手动include或者require.   B、spl_autoload_register()注册类到队列  C、开始实例化实用类
(1)使用__autoload方法,当程序中new一个没有直接引入的类的时候,php执行引擎会自动调用该方法。
(2)使用spl_autoload_register(),该函数可以注册给定的函数作为__autoload的实现,例如先把要加载的类作为该函数的参数注册到队列中,在调用__autoload的时候从队列中获取函数并引入,完成实例化。
(3)当使用多个spl_autoload_register方法时,php也会自动按顺序调用被注册的方法。
注:建议使用spl_autoload_register来实现类的自动加载,__autoload函数在更高版本的PHP中将被弃用。虽然性能和__FILE__魔术方法引入相对类路径的性能相近。但是自动加载机制可以防止或减少require_once,include_once在文件各处的随意使用
类的查找顺序:优先查找手动include或require进来的类,查找不到的情况下再采用类的自动加载机制;
composer的作用?
composer的下载功能就是自动完成 下载 include 这两步,当然前提是这些代码包要符合 composer 对包的定义,这些定义是在包代码的项目根目录下的 composer.json 文件里面。
是php用来管理项目依赖的工具,用来下载项目中需要使用的外部工具库或叫组件。
(1)在项目根目录新建composer.json文件,主要用于声明组建依赖关系,类的自动加载来协助composer管理。
1、当键名是autoload时则会自动加载
2、当键是require时则会下载或更新对应组件
3、composer.json文件必须都是双引号
(2)通过composer指定指令/命令安装依赖关系所需组件,并初始化自动加载信息。
php composer.phar install
 
10、tp和laravel的优缺点?
(1)提交数据的方式,Laravel在提交表单时需要在表单中加入{csrf_field}来防止跨域攻击,而TP不会。
(2)路由,Laravel必须先定义,再使用,路由文件为routes.php,哪怕没有控制器方法,只要写了路由就能够访问。TP在配置文件中开启路由后,路由格式是:'路由表达式' => '路由地址和参数'(使用路由的前提是URL支持phthinfo并且开启路由),路由可以使URL更符合SEO。
(3)中间件,Laravel的中间件,可以实现访问前后的处理,中间件就是HTTP请求到达之前经过的层,通过中间件我们可以验证用户是否登录等一些通用操作。
(4)操作数据库方式,都可以使用实例化(建立相对应的模型类)和DB:table('表名')来操作数据库,使用原生查询时不太相同,Laravel使用Db::操作('原生sql'),TP使用Db::query('原生sql');
(5)Laravel升级十分简易,而TP大版本的升级要重构代码。
(6)渲染模版方式在Laravel框架里,使用return view()来渲染模版;而ThinkPHP里则使用了$this->display()的方式渲染模版
(7)条件判断语句书写方式
Laravel框架里 if else判断语句和foreach语句 书写时必须以@if开头 以@endif结尾,如果没有则报语法错误,@foreach @endforeach同理。而TP框架则和PHP语法规则使用方式一致直接ifesle语句判断和foreach循环遍历。
 
11、什么是mvc?
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范,是将业务逻辑、数据、显示分离的方法来组织代码。
 
12、什么是依赖注入?
在PHP中,依赖注入是指对类的依赖通过构造器完成自动注入,控制器架构方法和操作方法中一旦对参数进行对象类型约束则会自动除法依赖注入,由于访问控制器的参数都来自与URL请求,普通变量就是通过参数绑定自动获取,对象变量则是通过依赖注入生成。如果是类car想调用类bus里的plane方法,就需要在类car里实例化下类bus,然后在调用plane方法,这就是类car依赖于类bus。注入了plane方法。
 
13、什么是模板引擎?
可以在PHP中应用的并且比较成熟的模板有很多,例如Smarty、PHPLIB、IPB、xingTemplate等几十种。
初始的开发模板就是混合层的数据编程。虽然通过MVC设计模式可以把程序应用逻辑与网页呈现逻辑强制性分离,但也只是将应用程序的输入、处理和输出分开,网页呈现逻辑(视图)还会有HTML代码和PHP程序强耦合在一起。
 
14、MyISAM和InnoDB的区别
主要有以下区别:
(1)MySQL默认采用的是MyISAM。
(2)MyISAM不支持事务,而InnoDB支持。InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,所以最好是把多条SQL语句显示放在begin和commit之间,组成一个事务去提交。
(3)InnoDB支持数据行锁定,MyISAM不支持行锁定,只支持锁定整个表。即MyISAM同一个表上的读锁和写锁是互斥的,MyISAM并发读写时如果等待队列中既有读请求又有写请求,默认写请求的优先级高,即使读请求先到,所以MyISAM不适合于有大量查询和修改并存的情况,那样查询进程会长时间阻塞。因为MyISAM是锁表,所以某项读操作比较耗时会使其他写进程饿死。
(4)InnoDB支持外键,MyISAM不支持。
(5)InnoDB的主键范围更大,最大是MyISAM的2倍。
(6)InnoDB不支持全文索引,而MyISAM支持。全文索引是指对char、varchar和text中的每个词(停用词除外)建立倒排序索引。MyISAM的全文索引其实没啥用,因为,它不支持中文分词,必须由使用者分词后加入空格再写到数据表里,而且少于4个汉字的词会和停用词一样被忽略掉。
(7)MyISAM支持GIS数据,InnoDB不支持。即MyISAM支持以下空间数据对象:Point,Line,Polygon,Surface等。
(8)没有where的count(*)使用MyISAM要比InnoDB快得多。因为MyISAM内置了一个计数器,count(*)时它直接从计数器中读,而InnoDB必须扫描全表。
所以在InnoDB上执行count(*)时一般要伴随where,且where中要包含主键以外的索引列。
为什么这里特别强调“主键以外”?因为InnoDB中primary index是和raw data存放在一起的,而secondary index则是单独存放,然后有个指针指向primary key。
所以只是count(*)的话使用secondary index扫描更快,而primary key则主要在扫描索引同时要返回raw data时的作用较大。
 
15、mysql的行级锁和表级锁的区别?
  1. 表锁:不会出现死锁,发生锁冲突几率高,并发低。MySQL的表级锁有两种模式:
表共享读锁,表独占写锁
  1. 行锁:会出现死锁,发生锁冲突几率低,并发高。
如果在一条select语句后加上for update,则查询到的数据会被加上一条排它锁,其它事务可以读取,但不能进行更新和插入操作
3. 注意:对MyISAM表的读操作,不会阻塞其它进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。
对MyISAM表的写操作,会阻塞其它进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。
4. 注意:尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁
合理设计索引,尽量缩小锁的范围
尽可能减少索引条件,避免间隙锁
尽量控制事务大小,减少锁定资源量和时间长度
5.lock table 表名 write 加写锁,lock table 表名 read 加读锁
 
16、mysql的优化方式?
  1. 选择最合适的字段属性
  2. 尽量把字段设置为NOT NULL
  3. 使用连接(JOIN)来代替子查询(Sub-Queries)
  4. 使用联合(UNION)来代替手动创建的临时表
  5. 事务
  6. 使用外键
  7. 锁定表
  8. 使用索引
  9. 优化查询语句,
A不使用子查询
B避免函数索引(尽量不要使用函数)
C用in来替换or
D LIKE双百分号无法使用到索引
E读取适当的记录LIMIT M,N
F避免数据类型不一致
G分组统计可以禁止排序
H避免随机取记录
I禁止不必要的ORDER BY排序
J批量INSERT插入
 
17、哪些情况下索引会失效?
  1. 字段类型不匹配导致的索引失效
  2. 被索引字段使用了表达式计算
  3. 被索引字段使用了内置函数
  4. like 使用了 %X 模糊匹配
  5. 索引字段不是联合索引字段的最左字段
  6. or 分割的条件,如果 or 左边的条件存在索引,而右边的条件没有索引,不走索引
  7. in、not in 可能会导致索引失效
18、数据库主从复制延迟的原因及解决方案?
原因:t1时刻,主库执行完事务,并写入binlog
t2时刻,从库接收主库的binlog(IO线程),并写入中继日志
t3时刻,从库的SQL线程执行SQL语句,完成事务
主从延迟,就是从库执行完成到主库执行完成中间的时间差大于(t3-t1)
开启三个线程:dump线程,IO线程,sql线程
解决方案:
1)主从服务器的硬件差异。从库机器性能差,无法及时同步主库数据,只需要更换新的设备或设备保持一致即可。
2)从库的读压力大。一般主库“写”,从库“读”。大量“读”请求命中从库,会大量消耗从库系统资源,进而影响从库的同步速度。此时可以构建一主多从架构,共同分担“读”请求的压力。
3)大事务。如果事务在主库执行15分钟,在从库同步也至少15分钟,造成主从延迟。如果可以,事务分批进行。
4)网络延迟。网络通信状况也会影响主从复制(影响从库的IO线程获取主库binlog),只能升级带宽,优化网络。
5)从库过多。从节点一般3-5个最佳。
mysql的主从复制是怎么同步的?是推还是拉?
  1. MySQL 主从复制是基于主服务器在二进制日志跟踪所有对数据库的更改。因此,要进行复制,必须在主服务器上启用二进制日志。
  2. 过程:
a.从库生成两个线程,一个 I/O 线程,一个 SQL 线程;
b.I/O 线程去请求主库的 binlog,并将得到的 binlog 日志写到 relay log(中继日志) 文件中;
c.主库会生成一个 log dump 线程,用来给从库 I/O 线程传 binlog;
d.SQL 线程会读取 relay log 文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致;
  1. 首先, MySQL 的复制是“推”的,而不是“拉”的。“拉”是指 MySQL 的备库不断的循环询问主库是否有数据更新,这种方式资源消耗多,并且效率低。“推”是指 MySQL 的主库在自己有数据更新的时候推送这个变更给备库,这种方式只有在数据有变更的时候才会发生交互,资源消耗少。如果你是程序员出身,你一定会选择“推”的方式。
19、如何保证数据的高可用性?
  1. 平时开发建议使用row格式
使用 row 格式的 binlog 时,数据不一致的问题更容易被发现。而使用 mixed 或者 statement 格式的 binlog 时,数据不一致不容易发现。如果过了很久才发现数据不一致的问题,很可能这时的数据不一致已经不可查,或者连带造成了更多的数据逻辑不一致。所以平时开发建议多使用row格式
  1. 建议使用可靠性优先策略
主备切换的可用性优先策略会导致数据不一致。 因此,大多数情况下,都建议使用可靠性优先策略。毕竟对数据服务来说的话,数据的可靠性一般要优于可用性的。
  1. 尽量减少主备延迟
在满足数据可靠性的前提下,MySQL 高可用系统的可用性,是依赖于主备延迟的。延迟的时间越小,在主库故障的时候,服务恢复需要的时间就越短,可用性就越高。
 
20、删库如何恢复到分钟级别?
  1. 查询是否开启 binlog 日志的 sql 脚本。
  2. 查看binlog存放日志文件目录
  3.   show variables like '%datadir%';
恢复数据步骤:
  1. 在mysql 安装目录 bin 目录中放入插件 my2sql,然后给 mysql 赋权限。
  2. 创建一个空文件夹 “tmpdir”,然后给个 777 的权限。
  3. 将binlog文件下载到本地,然后转换成sql格式,找到对应的节点(pos点),节点名(pos点)是纯数字的时间戳,根据节点可以恢复指定时间段的数据。
  4. binlog 文件格式转换,首先保证本地数据库与生产环境数据库版本要一致,然后输入以下命令(不要有换行符号):
  5. 在bin目录,输入以下命令(不要有换行):
./my2sql -user root -password 123456 -host 127.0.0.1 -port 3308 
-mode file -local-binlog-file ./mysql-bin.000038  -work-type 2sql 
-start-file mysql-bin.000038  -start-pos 606463342  -
stop-file mysql-bin.000038 -stop-pos 651675557  -output-dir ./tmpdir
  1. 将提取出的文件,在文本编辑器中打开,检查对应的 sql 是否正确且完整,要注意 delete 与 rollback语句 。
  2. sql 审查没问题了,然后在库里面将 sql 文件执行下就好了,推荐使用 navicat 15 工具,选运行 sql 文件来执行sql,到此,数据就算恢复完成了。
21、redis和Memcached的区别到底是什么?
  1. Redis是一个开源的内存数据结构存储,用作数据库,缓存和消息代理;
  2. Memcached是一个免费的开源高性能分布式内存对象缓存系统,它通过减少数据库负载来加速动态Web应用程序。
  3. Redis与Memcached相比,比仅支持简单的key-value数据类型,同时还提供list,set,zset,hash等数据结构的存储;redis支持数据的备份,redis支持数据的持久化,
  4. 总体来讲,TPS方面redis和memcache差不多,要大于mongodb。
  5. 内存使用效率对比:
使用简单的key-value存储的话, Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。
  1. 数据结构
Redis支持字符串,散列,列表,集合,有序集,位图,超级日志和空间索引;而Memcached支持字符串和整数。
  1. 执行速度
Memcached的读写速度高于Redis。
  1. Redis是单线程的;而Memcached是多线程的。
  2. 数据一致性(事务支持)
Memcache 在并发场景下,用cas保证一致性
redis事务支持比较弱,只能保证事务中的每个操作连续执行
mongoDB不支持事务
 
22、什么是缓存击穿,穿透,雪崩?
(1)缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会被打到数据库上。
解决:
1,缓存空对象
2、布隆过滤器
(2)缓存击穿是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db,属于常见的“热点”问题
解决:
1.预先设置热门数据,提前存入缓存
2.实时监控热门数据,调整key过期时长
3.二级缓存:对于热点数据进行二级缓存,并对于不同级别的缓存设定不同的失效时间。
4.设置分布式锁
(3)大量的应用请求无法在Redis缓存中进行处理,紧接着应用将大量请求发送到数据库层,导致数据库层的压力激增
击穿与雪崩的区别即在于击穿是对于特定的热点数据来说,而雪崩是全部数据。
 解决:
1、差异化设置过期时间
2、不设置过期时间
3、服务降级
 
23、接口的数据加密怎么实现?
  1. 使用token进行加密解密,提高接口安全性
  2. 使用RSA配合签名进行加密解密
a.首要需要安装openSSL,使用下面的地址,找到适合自己电脑的安装包下载,按照提示安装即可。
b.打开OpenSSL文件夹下的bin目录,点击openssl.exe,打开命令窗口
c.开始生成RSA的私钥,输入一下命令之后看到提示信息表示生成成功
d.利用私钥文件生成RSA公钥文件
e.前面说过我们最终使用的RSA文件是需要经过PKCS#8编码的,之前生成的RSA文件只是用来生成公钥文件的。
 
24、nginx和apache的区别?
(1)二者最核心的区别在于apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程 。nginx处理静态文件好,耗费内存少.但无疑apache仍然是目前的主流,有很多丰富的特性.所以还需要搭配着来.当然如果能确定nginx就适合需求,那么使用nginx会是更经济的方式。
(2)nginx的负载能力比apache高很多。最新的服务器也改用nginx了。而且nginx改完配置能-t测试一下配置有没有问题。
(3)apache重启的时候发现配置出错了,会很崩溃,改的时候都会非常小心翼翼现在看有好多集群站,前端nginx抗并发,后端apache集群, 配合的也不错。
(4)nginx处理动态请求是鸡肋,一般动态请求要apache去做,nginx只适合静态和反向。
(5)从经验来看,nginx是很不错的前端服务器,负载性能很好,nginx,用webbench模拟10000个静态文件请求毫不吃力。 apache对php等语言的支持很好,此外apache有强大的支持网络,发展时间相对nginx更久,bug少但是apache有先天不支持多核心处理负载鸡肋的缺点,建议使用nginx做前端,后端用apache。大型网站建议用nginx自代的集群功能。
(6)大部分情况下nginx都优于APACHE,比如说静态文件处理、PHP-CGI的支持、反向代理功能、前端 Cache、维持连接等等。在Apache+PHP(prefork)模式下,如果PHP处理慢或者前端压力很大的情况下,很容易出现Apache进程数 飙升,从而拒绝服务的现象。
(7)Apache在处理动态有优势,Nginx并发性比较好,CPU内存占用低,如果rewrite频繁,那还是Apache吧!
(8)一般来说,需要性能的web 服务,用nginx 。如果不需要性能只求稳定,那就apache 吧。
 
25、nginx实现高并发的原理?
  1. nginx高并发原理(多进程+epoll实现高并发)
(1)Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程
(2)每个子进程只有一个线程,采用的 IO多路复用模型epoll,实现高并发
  1. epoll能实现高并发原理
(1)epoll() 中内核则维护一个链表,epoll_wait 方法可以获取到链表长度,不为0就知道文件描述符准备好了
(2)在内核实现中 epoll 是根据每个 sockfd 上面的与设备驱动程序建立起来的回调函数实现的
(3)某个 sockfd 上的事件发生时,与它对应的回调函数就会被调用,来把这个 sockfd 加入链表,其他处于“空闲的”状态的则不会
(4)epoll上面链表中获取文件描述,这里使用内存映射(mmap)技术, 避免了复制大量文件描述符带来的开销
 
26、linux基础命令?
1、cd:切换目录命令
cd /home
2、ls :列出目录的文件信息
ls -l
3、cat :查看文件全部内容
cat test.txt
4、tail :查看文件指定行数内容
tail -n 10 test.txt
5、touch:创建文件
touch test.txt
6、mkdir:创建文件夹
mkdir testdir
7、cp:复制文件或文件夹
cp test.txt > newtext.txt
8、mv :移动文件或文件夹
mv test.txt > /dir
9、rm:删除文件或文件夹
rm test.txt
rm -rf testdir
10、find:查找文件
find / -name test.text
11、vi:编辑文件
vi test.txt
12、rename:文件重命名
rename test.txt  newtext.txt
13、chmod:文件权限修改
chmod 777 text.txt
14、history:最近历史执行过的命令
history
15、wget:下载网络资源文件
wget http://xzwk.cn/test.txt
16、top:查看资源实时用量情况(CPU、内存)
top
17、logout:注销
logout
18、reboot:重启
reboot
19、shutdown: 定时关机
shutdown -s -t 3600 //3600秒后关机
20、poweroff: 立即关机
poweroff
 
27、什么是防盗链?
了解防盗链之前先了解下http referer这个属性,http referer是请求头中的一部分,当浏览器向web服务器发出请求时,一般会带上这个属性用来表明网页的来源,比如我在qq空间里添加朋友的空间链接,那么当有人点击我空间里的这个链接调到朋友的qq空间时,referer的值就是我空间的url。防盗链的基本原理就是根据请求头中referer属性得到网页来源,从而实现访问控制在nginx里的location里设置。
 
28、有用过预处理么?
用过,PDO 类中,有个 prepare 方法可以实现预处理,PDOStament 类中的 excute方法可以执行预处理,预处理的参数分为两种,一种是:字符串占位符,另一种是?占位符,:字符串占位符在执行预处理传递参数时传入的是关联数组,而?占位符传递的是索引数组。两者不能混合使用,但一般推荐使用:字符串占位符。
 
29、php传值与传引用的区别是什么?
传值在函数范围内,改变变量值的大小不会影响到函数外的变量值;传引用在函数范围内,对值的任何改变在函数外也有所体现,传引用传的是内存地址。这里有一点需要注意,将一个变量 = 赋值给另一个变量时,不会立即为新变量分配内存空间,而是在原变量的zval中给refcount加1。 只有当原变量或者发生改变时,才会为新变量分配内存空间,同时原变量的refcount减 1 。当然,如果unset原变量,新变量直接就使用原变量的zval而不是重新分配。&引用赋值时,原变量的is_ref 变为1,refcount 加1.  如果给一个变量&赋值,之前 = 赋值的变量会分配空间。
 
30、事务的隔离级别有哪些?
数据库事务的隔离级别有4个,由低到高依次为Read uncommitted(读未提交)、Read committed(读已提交)、Repeatable read(可重复读取)、Serializable(序列化),后三个级别可以逐个解决脏读、不可重复读、幻象读这几类问题。
1、Read uncommitted(读未提交):
如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。这样就避免了更新丢失,却可能出现脏读。也就是说事务B读取到了事务A未提交的数据。
2、Read committed(读已提交):
读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。该隔离级别避免了脏读,但是却可能出现不可重复读。事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
3、Repeatable read(可重复读取):
可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,即使第二个事务对数据进行修改,第一个事务两次读到的的数据是一样的。这样就发生了在一个事务内两次读到的数据是一样的,因此称为是可重复读。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。这样避免了不可重复读取和脏读,但是有时可能出现幻象读。(读取数据的事务)这可以通过“共享读锁”和“排他写锁”实现。(这是数据库的默认隔离级别)
4、Serializable(序列化):
提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。序列化是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻像读。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
 
31、如何实现session共享?
服务器间Session同步定时同步各个服务器的session信息,此方法可能有一定延时,用户体验也不是很好。使用主-从服务器的架构,当用户在主服务器上登录后,通过脚本或者守护进程的方式,将session信息传递到各个从服务器中,也可以手工把session文件存放的目录改为nfs网络文件系统,从而实现文件的跨机器共享(使用nfs或windows文件共享都可以,或者专用的共享存储设备)。这样,用户访问其它的从服务器时,就可以读到session信息。
缺点:比如速度慢、不稳定等,另外,如果session信息传递是主->从单向的,会有一些风险,比如主服务器down了,其它服务器无法获得session信息。
 
31、MySQL查询的生命周期包括?
创建连接、解析SQL、检查权限、优化查询、执行查询(与存储引擎进行交互)、返回结果给应用程序或客户端
 
32、Git 常用命令速查?
git branch 查看本地所有分支。
git status 查看当前状态。
git commit 提交。
git branch -a 查看所有的分支。
git branch -r 查看远程所有分支。
git push origin master 将本地项目给提交到服务器中
git pull 本地与服务器端同步
git push (远程仓库名) (分支名) 将本地分支推送到服务器上去。
git init 本地初始化
 
33、斐波拉契数列代码?
function search($n){
if($n == 1){
$search = [0];
$search_once = $search[$n-1];
}else if($n == 2){
$search = [0,1];
$search_once = $search[$n-1];
}else{
$search = [0,1];
for($i = 3;$i<=$n;$i++){
$num = $search[$i-2] + $search[$i-3];
$search[] = $num;
}
$search_once = $search[$n-1];
}
return $search;
}
 
print_r(search(8));