PHP面试题总结

1:mvc是是什么?相互间有什么关系?

mvc是一种设计模式,m(model)模型层,v(view)视图层,c(controller)逻辑层

客户端发起请求->控制器处理请求,如果用到数据则请求模型层->返回视图层

2:oop是什么?

oop是面向对象编程,面向对象编程是一种计算机编程架构,与之相对的是面向过程编程

oop具有3大特点:

①封装性:就是信息隐藏,就是实现类中的public,protected,private3个关键字的使用上,把类的使用和实现分开,只保留 部分接口和和方法与外部联系,大量的实现过程被封装对外不可见

②继承性:就是子类自动继承其父类的属性和方法,就是extends关键字的使用,并且可以添加新的属性和方法,可以修过已有的属性和方法,继承性增加了代码的可重用性,php只支持单继承(通过接口可以实现多继承),别担心,c#、java也是单继承,c++是多继承

③多态性:子类继承了来自父类中的属性和方法,并对其进行重写。多个子类就得到多个结果。或者对interface和abstract的实现上得到不同的实现方式,这个叫多态性。多态性增强了软件的灵活性

oop的好处:

易维护,易扩展, 效率高,质量高(两易,两高)

3:smarty是什么,有什么作用?

smarty是用php写出来的模版引擎,是业内最名气最大的那一款,它分离了逻辑代码和外在的显示;

通俗点就是我们的php视图层是html和php糅合到一起的,模版引擎就是去分离它们的;

相应的就可以设置缓存参数把对应的html代码缓存下来,生成静态页面;

不过在现在模版引擎已经慢慢的不经常用了,因为更多的项目是采用前后端分离的架构模式

4:简述一下数据库的优化?

数据库的优化可以从四方面来优化:

①从结构层:web服务器采用负载均衡服务器,mysql服务器采用主从复制,读写分离

②从存储层:采用合适的存储引擎,采用三范式

三范式:通俗讲,第一范式,关系模型中,属性不可在分,确保每一列的原子性;第二范式,满足第一范式前提下,表中每一行 的数据只能和其中一列属性相关,只要数据列中出现数据重复,就要把表拆分开来;第三范式,数据不存在传递关系,即每个属性都跟主键有直接关系而不是间接关系。

③设计层:采用分区分表,索引,表的字段采用合适的字段属性,适当的采用逆范式,开启mysql的缓存

④sql语句层:结果一样的情况下,采用效率高,速度快节省资源sql语句执行

5:php如何解决异常?

抛出异常:使用try...catch,异常的代码放在try代码块内,如果没有触发异常,则代码继续执行,如果触发异常,则抛出一个异常,catch代码块捕获异常,并创建一个包含异常信息的对象。$e->getMessage(),输出异常的错误信息。

解决异常:使用set_error_handler函数获取异常(也可以使用try()和catch()函数),然后使用set_exception_handler()函数设置默认的异常处理程序,register_shutdown_function()函数来执行,执行机制是:php把要调用的函数加载到内存中,当页面所有php语句执行完毕时,再调用此函数

6:权限关系(RBAC)的实现?

基于角色权限的访问控制(Role-Based Access Control

简单实现:①首先创建用户表:id name auto(保存格式是:控制器-方法)

②后台创建一个基类控制器,控制器里封装一个构造方法,用户登录成功后,使用框架封装好的session函数获取对应的sessionId,通过用户id获取数据表中的auth数据,使用explode函数进行分割获取数据 ,得到登录者具有的控制器和方法,也可以把它们组装成字符串,使用in_array函数进行判断是否在一个定义好的数组中,以此判断是否具有控制器和方法的访问权限

7:登录的实现?

登录分两种普通登录和第三方登录,主要介绍下第三方登录,第三方登录主要实用的是author协议,比如qq第三方登录,首先是站点会引导用户跳转到qq的登录授权界面,当用户 输入qq和密码成功登录后会自动跳转到我们站点设置好的回调页面,并附带一个code参数,接着我们使用code再次请求qq的授权页面,就可以从中获取到一个 access_token(访问令牌),通过这个 access_token,我们可以调用qq提供给我们的接口,比如 获取open_id,可以获取用户的基本信息。获取后我们需要拿到用户的授权信息和open_id和我们平台的普通用户进行绑定,这样便实现了第三方登录

8:接口安全方面是怎么处理的 ?

①利用http中的post请求方式

②定义好前后端的验证规则:一般的是固定参数+附加参数进行数字签名(进行按照key的字母a-z顺序排列)(加上一个双方规定好的key),使用md5进行加密的到签名sign。也可以加个时间戳进行验证请求时间范围(比如5分钟有效),服务器得到数据后利用同样的规则进行解密验证

9:用的什么技术实现短信发送,在哪调用

主要用的是第三的短信接口,在申请接口的时候进行相应的信息配置,然后在我们站点需要用到短信验证的地方进行调用,我们通常在用户注册的使用使用到短信验证

10:写过接口?如果定义接口?

这里的接口有两层含义:①数据型接口,Interface定义,是一种语法结构,是一种结构规范,规范实现类的格式,团队比较大时用到

②应用型接口:俗称api(application interface)数据对外访问的一个入口,按照客户端需要的数据进行设计,主要以json、xml的格式进行返回,并配有文档

11:redis如何防止高并发问题?

首先解释一下什么是并发:高并发是互联网分布式系统架构设计中必须考虑的因素之一,它通常指,通过设计保证系统能够同时并行处理很多请求

另外并发和并行的区别:

  • 你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行
  • 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发
  • 你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行

并发:你有处理多个任务的能力,不一定同时(一个CPU轮流)

并行:有同时处理多个任务的能力(多个CPU同时)

并发关乎结构,并行关乎执行

回到问题上,redis本身是单进程,再多的command的都是 one by one执行的,其实没有所谓的高并发问题,我们指的高并发是指使用的时候出现get和set操作问题

redis是单线程机制的nosql数据库,基于key-value,数据可持久化落盘,单线程的先天性基因决定了,高并发对一个键的操作会排列处理,如果并发量很大,可能造成后来的请求超时。如在远程访问redis的时候,因为网络等原因造成高并发访问延迟返回的问题

解决办法:

在客户端将连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。

服务器角度,利用setnx变向实现锁机制。

12:支付宝支付流程怎么实现?

①首先一个支付宝账号,接下来向支付宝申请在线支付业务 ,签署协议。协议生效后支付宝一方给网站合作伙伴ID,和安全校验码,有了这两样东西就可以按照支付宝接口文档开发支付接口了,中间主要涉及到一个安全问题。

②整个流程是这样的,我们网站通过post传递相应的参数(订单的总金额,订单号)到支付页面;

③支付页面把一系列的参数经过处理,以post的方式提交个支付宝服务器,支付宝服务器进行验证,并对接收的数据进行处理;④把处理后的结构返回给我们网站设置的异步和同步回调地址,通过相应的返回参数,来处理相应的业务逻辑,比如返回的参数代表支付成功,更改订单状态

13:什么是单点登录?

单点登录SSO(Single sign on),就是指在一个多系统共存的系统环境下,用户在一处登录后,就不用在其他系统中进行登录而能获得所有系统的信任

实现:第一次访问系统时候,因为没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份校验,如果通过校验,应该返回给用户一个认证凭证--ticket,作为自己的认证凭证;应用系统接收到请求之后会把ticket送到认证系统进行校验,检验ticket的合法性,如果合法则顺利访问其他系统

应用技术点:

①多个站点共用一个数据验证系统

②主要通过跨域请求的方式来实现验证及session处理

14:如何处理负载,高并发?

从低成本,高性能和高扩展性的角度来分析和提出解决方案

①html的静态化  

②图片服务器的分离   把图片单独存储,尽量减少图片等大流量的开销,可以放到相关的平台上,如七牛等

③数据库的集群和库表散列及数据库缓存(利用redis,memcache进行数据缓存)

④负载均衡 利用服务器apache和nginx的设置来实现

⑤镜像 把不同的请求发送到多个镜像端

15:封装一个简单的框架

框架基于mvc模型,模型层,控制器层,视图层;路由的分配的单个入口文件,模版引擎的应用,单例模式,工厂模式应用;第三方的类库的引入等

16:session和cookie区别

①cookie是放在客户端浏览器中的,session是存放到服务器中的

②cookie不安全,因为cookie可以被脚本获取,进行cookie欺骗

③session是存放到服务器端,相对于cookie比较安全,但是因为放到服务器端,当访问量增多时,会比较占用服务器性能

④单个cookie保存数据不能超过4k,很多很多浏览器限制一个站点最多保存20个cookie

所以对应登录的重要信息保存到session中,其他信息可以放到cookie中 

17:echo ,print print_r的区别?

echo可以同时输出多个值,它是一种语言结构,是php的内部指令,不是函数,因此不能作为表达式的一部分使用

print()函数,打印一个值,此函数有返回值,如果成功打印则返回true,否则返回false,只能打印简单类型的数据类型变量

printf()函数,输出格式化的字符串

print_r()函数,可以打印复杂的数据和简单的数据,有返回值

var_dump()函数,判断变量的类型与长度,并输出变量的数值,显示出数据的结构

18:单双引号的区别?

①单引号比双引号速度快

②双引号可以解析所有的特殊字符,单引号只能解析部分特色字符

19:get和post的区别?

①get从服务器获取数据,post向服务器传送数据

②get是把参数数据队列加到提交表单的action属性所指的url中,值和表单内各个字段一一对应,在url中可以看到。post请求是http post机制,将表单内各个字段与其内容放置在html header内一起传送到action属性所指的url地址。用户 看不到

③get传递的数据量较小,不能大于2kb。post传递的数据量较大,一般默认不做限制

④post比get的安全型高,效率上get比post快

20:修过session的生成时间

①配置文件中php.ini,session.gc_maxlifetime = 1440 //默认时间

②代码层面     

$lifeTime = 24*3600;  //保存一天

session_set_cookie_params($lifeTime);

session_start();

21:常用魔术常量(8个)

魔术(magic),常量我们知道是定义好之后不可变,直到销毁;但是这里的php预定义的常量会随着所除位置值发生变化,所以也可以称为魔术变量

__LINE__:文件中的当前行号

__FILE__:文件的完整路径和文件名。如果用在被包含的文件中,则返回被包含的文件名

__DIR__:文件所在的目录,如果用在被包含 的文件中,则返回被包含的文件所在的目录

__FUNCTION__:用在函数内部,返回函数被定义时的名字(区分大小写)

__CLASS__:用在类内部,返回类被定义时的名字(区分大小写)

__METHOD__:用在类的方法中,返回该方法被定义时的名字(区分大小写)

__NAMESPACE__:当前命名空间的名称,此常量是在编译时定义的

22:常用超全局变量(9个)

$GLOBALS:存储全局作用域中的变量

$_SERVER:获取服务器相关信息

$_REQUEST:获取POST和GET请求的参数

$_POST:获取表单提交的 POST请求参数

$_GET:获取表单请求的GET请求参数

$_FILES:获取上传文件的变量

$_ENV:获取 服务器端环境变量的数组

$_COOKIE:获取浏览器cookie的数据

    浏览器cookie的操作

设置cookie:setcookie(name,value,expire,path,domain);

获取cookie:$_COOKIE['user'];

删除cookie:setcookie('user','',time()-3600);//设置过期时间

$_SESSION:服务端session的 操作

使用session前一定要 session_start()启动session

存储session:$_SESSION['name'] = 'what';//数组操作 

销毁session:unset($_SESSION['views']);//销毁一个 

session_destroy()和unset($_SESSION);//销毁所有

23:魔术方法(13个)

__construct()

实例化对象的时候被调用

__destruct()

当删除一个对象或者对象操作终止时被调用,大意就是说只要类中包含这个方法,那么程序结束或者主动去删除实例化的对象 时 都会调用 这个方法

__call()

对象调用某个方法,如果方法存在,则直接调用,如果方法不存在,那么就会调用__call()方法

__get()

读取一个对象的属性时, 若属性存在,则直接返回属性值;如果不存在,则会调用__get()方法

__set()

设置对象的属性时,若属性存在,则直接赋值,如果不存在,则会调用__set()函数

__toString()

打印一个对象的时候被调用,如echo $obj或者print $obj

__clone()

克隆对象的时候被调用。如:$t=new Test(); $t1=clone $t;

__sleep()

serialize之前被调用,如果对象比较大,想删减一点东东再序列化,可以考虑此函数

__wakeup()

unserialize时被调用,做些对象的初始化工作

__isset()

检测一个对象的属性是否存在时被调用,如isset($c->name)

__unset()

unset一个对象的属性时被调用,如unset($c->name)

__set_state()

调用var_export时,被调用。用__set_state的返回值作为var_export的返回值

这里介绍一下var_export()函数的用法:此函数当$str = var_export($arr,true);可以得到保留数据结构的字符串数据,把相应的字符串数据转变成数组则  $arr = eval("return $a;"); 主要用于存储数据库得到的数组数据信息和file_put_content配合使用

__autoload()

实例化一个对象时,如果对应的类不存在,则该方法会被调用;目前看来只有这个方法是放到类外部的 

24:常用的数组函数

 ①数组的基本函数

数组的键名和值

array_values($arr); 获得数组的值

array_keys($arr);获得数组的键名

array_flip($arr) ; 数组中的值与键名互换(如果有重复,前面的会被后面的覆盖)

in_array('str',$arr);在数组中检索str

array_search('str',$arr) ; 在数组中检索apple,如果存在返回键名

array_key_exists('str',$arr) ; 检索给定的键名是否存在数组中

isset($arr['str']) ; 检索给定的键名是否 存在数组中

②数组的分段和填充

数组的分段

array_slice($arr,0,3);可以将数组中的一段取出,此函数忽略键名

array_splice($arr,0,3,array('black','marron'));可以将数组中的一段取出,与上一个函数不同在于返回的序列从原数组中删除

分割多个数组

array_chunk($arr,3,true);可以将一个数组分割成多个,true为保留原数组的键名

填充数组

array_pad($arr,5,'x');将一个数组填充到指定的长度

③数组与栈

④数组与队列

⑤数组的排序

通过元素值对数组排序

sort($arr);由小到大的顺序排列,忽略键名的数组排序

rsort($arr);由大到小的顺序排序,忽略键名的数组排序

asort($arr);由小到大的顺序排序,保留键名的数组排序

arsort($arr);由大到小的顺序排序,保留键名的数组排序

通过键名对数组进行排序

ksort($arr);按照键名的正序排序

krsort($arr);按照键名的逆序排序

⑥数组的计算

数组元素的求和 

array_sum($arr);对数组内部的所有元素求和运算

数组的合并

array_merge($arr1,$arr2);合并两个或者多个数组(规则如下:相同的字符串键名,后面覆盖前面,相同的数字键名,后面的附加的后面)

$arr1+$arr2,两个或者多个数组相加,(规则是 ,相同的键名只保留前一个,无论键名是数字还是字符串)

array_merge_recursive($arr1,$arr2);递归合并操作,如果数组中有相同的字符串键名,这些值被合并到一个数组中去;如果一个值本身是一个数组,按照相应的键名把它合并为另一个数组。当数组具有相同的数组键名时,后一个值将不会覆盖原来的值,而是附加到后面

25:常用的字符串函数

包含8大类的字符串类型函数:

①字符串长度的函数

strlen()和mb_strlen(),后者需要开启mbstring扩展

②比较字符串 

strcmp(),strcasecmp(),strspn(),strcspn()

③分割连接反转

str_split(),split(),explode(),implode()

④html与字符串相互转化

htmlspecialchars(),strip_tags(),get_html_translation_table(),addcslashes(),htmlentities()

⑤填充和剔除字符串

trim(),ltrim(),rtrim(),str_pad(),chunk_split()

⑥统计字符串和单词个数

count_chars(),str_word_count()

⑦查找替换截取

strpos(),str_replace(),substr_replace(),substr(),strstr()

⑧大小写处理

strtolower(),strtoupper(),ucfirst(),ucwords()

借鉴网站:https://blog.csdn.net/u011330276/article/details/79597200

猜你喜欢

转载自blog.csdn.net/mazhaer/article/details/80742339