PHP常见问题
Posted 落之梦紆sec
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP常见问题相关的知识,希望对你有一定的参考价值。
一.get,post 的区别
1、GET在浏览器回退时是无害的,而POST会再次提交请求。
3、GET请求会被浏览器主动cache,而POST不会,除非手动设置。
4、GET请求只能进行url编码,而POST支持多种编码方式。
5、GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
6、GET请求在URL中传送的参数是有长度限制的,而POST没有。
7、对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
8、GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
9、GET参数通过URL传递,POST放在Request body中。
10、GET产生一个TCP数据包,POST产生两个TCP数据包
二、require,include 区别
require是无条件包含也就是如果一个流程里加入require,无论条件成立与否都会先执行requireinclude有返回值,而require没有(可能因为如此require的速度比include快) 包含文件不存在或者语法错误的时候require是致命的错误终止执行,include不是
三、常见的 HTTP 状态码以及含义
1xx消息:这一类型的状态码,代表请求已被接受,需要继续处理。由于HTTP/1.0协议中没有定义任何1xx状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送1xx响应。
2xx成功:这一类型的状态码,代表请求已成功被服务器接收、理解、并接受200 OK:请求已成功,请求所希望的响应头或数据体将随此响应返回。实际的响应将取决于所使用的请求方法。在GET请求中,响应将包含与请求的资源相对应的实体。在POST请求中,响应将包含描述或操作结果的实体
202 Accepted:服务器已接受请求,但尚未处理。最终该请求可能会也可能不会被执行,并且可能在处理发生时被禁止。
204 No Content:服务器成功处理了请求,没有返回任何内容
4xx客户端错误:这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个HEAD请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容
400 Bad Request:由于明显的客户端错误(例如,格式错误的请求语法,太大的大小,无效的请求消息或欺骗性路由请求),服务器不能或不会处理该请求
401 Unauthorized:类似于403 Forbidden,401语义即“未认证”,即用户没有必要的凭据。[32]该状态码表示当前请求需要用户验证。该响应必须包含一个适用于被请求资源的WWW-Authenticate信息头用以询问用户信息。客户端可以重复提交一个包含恰当的Authorization头信息的请求。
403 Forbidden:服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个HEAD请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息。
404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。405 Method Not Allowed:请求行中指定的请求方法不能被用于请求相应的资源。
408 Request Timeout:请求超时5xx服务器错误:表示服务器无法完成明显有效的请求。[56]这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个HEAD请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。这些状态码适用于任何响应方法500 Internal Server Error:通用错误消息,服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。没有给出具体错误信息
502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应
503 Service Unavailable:由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是暂时的,并且将在一段时间以后恢复。
504 Gateway Timeout:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。注意:某些代理服务器在DNS查询超时时会返回400或者500错误。
四、session 与 cookie 的区别和联系
区别:1. 存放位置:Session 保存在服务器,Cookie 保存在客户端。2. 存放的形式:Session 是以对象的形式保存在服务器,Cookie 以字符串的形式保存在客户端。3. 用途:Cookies 适合做保存用户的个人设置,爱好等,Session 适合做客户的身份验证4. 路径:Session 不能区分路径,同一个用户在访问一个网站期间,所有的 Session 在任何一个地方都可以访问到。而 Cookie 中如果设置了路径参数,那么同一个网站中不同路径下的 Cookie 互相是访问不到的。5. 安全性:Cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗,考虑到安全应当使用 session6. 大小以及数量限制:每个域名所包含的 cookie 数:IE7/8,FireFox:50 个,Opera30 个;Cookie 总大小:Firefox 和 Safari 允许 cookie 多达 4097 个字节,Opera 允许 cookie 多达 4096 个字 节,InternetExplorer 允许 cookie 多达 4095 个字节;一般认为 Session 没有大小和数量限制。关系:Session 需要借助 Cookie 才能正常工作。如果客户端完全禁止 Cookie,Session 将失效!Session 是由应用服务器维持的一个 服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的 SessionID, 用该 SessionID 为标识符来存取服务器端的 Session 存储空间。而 SessionID 这一数据则是保存到客户端,用 Cookie 保存的,用户提交页面时,会将这一 SessionID 提交到服务器端,来存取 Session 数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用 Cookie,那么 Session 也会失效。session存在于服务器端,cookie存在于用户端。之前说如果禁用了cookie那么session就使用不了了,可以说这是正确的,也可以说这是错误的。因为禁用了cookie,session_id就不能保存,而服务器正是根据session_id来判断用户的session,所以说这是正确的。经过测试,当我们禁用cookie时,刷新页面session_id会改变,说明session_id是用cookie保存的。用户禁止cookie,服务器仍会将sessionId以cookie的方式发送给浏览器,只是浏览器不能存储了而已,我们可以用其他方法获取这个 sessionID。解决cookie禁用然后引用session的方法。1.修改 php.ini session.use_cookies =0 //设置客户端是否使用cookie来保存session值 该参数的值不影响上述机制的进行。但是为了验证该机制,这里把该参数设为0,排除cookie携带seesionid的可能 session.use_only_cookies =0 //是否只使用cookie来保存session值 该参数为1时,上述机制失效。设置session.use_trans_sid =1或者编译时打开打开了--enable-trans-sid选项 这样他会在每个url后面自动加上PHPSESSID的值,然后正常使用session就可以了。2.在url后面加上session_id的值或者保存session_id的值于数据库或redis中,然后在下一次要调用session前,运行session_id($session_id),还有这条语句要在session_start()前。
五、获取上级目录的方法
六、数据库主从复制,读写分离
* 什么是主从复制 主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;*
主从复制的原理:
1.数据库有个bin-log二进制文件,记录了所有的sql语句。
2.只需要把主数据库的bin-log文件中的sql语句复制。
3.让其从数据的relay-log重做日志文件中在执行一次这些sql语句即可。
* 主从复制的作用
1.做数据的热备份,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
2.架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问频率,提高单机的I/O性能
3.主从复制是读写分离的基础,使数据库能制成更大 的并发。例如子报表中,由于部署报表的sql语句十分慢,导致锁表,影响前台的服务。如果前台服务使用master,报表使用slave,那么报表sql将不会造成前台所,保证了前台的访问速度。
* 主从复制的几种方式:
1.同步复制:所谓的同步复制,意思是master的变化,必须等待slave-1,slave-2,...,slave-n完成后才能返回。
2.异步复制:如同AJAX请求一样。master只需要完成自己的数据库操作即可。至于slaves是否收到二进制日志,是否完成操作,不用关心。mysql的默认设置。
3.半同步复制:master只保证slaves中的一个操作成功,就返回,其他slave不管。这个功能,是由google为MYSQL引入的。
* 关于读写分离 在完成主从复制时,由于slave是需要同步master的。所以对于insert/delete/update这些更新数据库的操作,应该在master中完成。而select的查询操作,则落下到slave中。
七、高并发的解决方案
web服务器优化 :负载均衡 流量优化:防盗链处理 将恶意请求屏蔽, 前端优化:减少http请求、添加异步请求、启用浏览器缓存和文件压缩、cdn加速、建立独立的图片服务器、 服务端优化: 页面静态化、并发处理、队列处理、 数据库优化:数据库缓存、分库分表、分区操作 、读写分离、负载均衡
八、什么是 Redis 穿透和雪崩
**缓存穿透**:就是访问redis中一个不存在的key的时候,会直接穿过缓存,去数据库中进行查询.如果是黑客,进行恶意攻击的时候,每次都请求超过2000个/秒的时候,这个时候mysql基本上就挂了.
解决办法是:每次从数据库中查询到一个不存在的key的时候,就写一个空值到缓存库中,有恶意攻击的时候,直接从缓存中取到这个空值.
**缓存雪崩**:就是每秒有5000个请求过来时候,redis缓存库崩了,然后这些请求瞬间落在了mysql数据库上,直接导致数据库死机.
解决方案就是:
事前:提高缓存库的高可用, 使用主从结构加哨兵 cluster集群
事中:使用ehcache+hystrix限流组件(当请求量非常巨大的时候,就调用自己开发好的一个降级饿组件,返回一些默认值,如友情提示,或者空白值)
事后:做持久化,尽快恢复缓存集群,一旦恢复,自动从磁盘上读取数据,恢复内存中的数据.
九、Redis 如何防止高并发?
其实redis是不会存在并发问题的,因为他是单进程的,再多的命令都是一个接一个地执行的。我们使用的时候,可能会出现并发问题,比如获得和设定这一对。Redis的为什么 有高并发问题?Redis的的出身决定
Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对redis进行并发访问时会出现问题。发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。
同时,单线程的天性决定,高并发对同一个键的操作会排队处理,如果并发量很大,可能造成后来的请求超时。在远程访问redis的时候,因为网络等原因造成高并发访问延迟返回的问题。
解决办法 在客户端将连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。服务器角度,利用setnx变向实现锁机制。
十、如何处理负载、高并发
1、html静态化 其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。
2、图片服务器分离 把图片单独存储,尽量减少图片等大流量的开销,可以放在一些相关的平台上。
3、数据库集群和库表散列及缓存 数据库的并发连接为100,一台数据库远远不够,可以从读写分离、主从复制,数据库集群方面来着手。另外尽量减少数据库的访问,可以使用缓存数据库如memcache、redis。
4、镜像 尽量减少下载,可以把不同的请求分发到多个镜像端。
5、负载均衡:Apache的最大并发连接为1500,只能增加服务器,可以从硬件上着手,如F5服务器。当然硬件的成本比较高,我们往往从软件方面着手。
负载均衡 (Load Balancing) 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力,同时能够提高网络的灵活性和可用性。目前使用最为广泛的负载均衡软件是nginx、LVS、HAProxy。
**Nginx的优点是:**工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是它目前广泛流行的主要原因之一,Nginx单凭这点可利用的场合就远多于LVS了。Nginx对网络稳定性的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势之一;相反LVS对网络稳定性依赖比较大,这点本人深有体会;Nginx安装和配置比较简单,测试起来比较方便,它基本能把错误用日志打印出来。LVS的配置、测试就要花比较长的时间了,LVS对网络依赖比较大。可以承担高负载压力且稳定,在硬件不差的情况下一般能支撑几万次的并发量,负载度比LVS相对小些。Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx会把上传切到另一台服务器重新处理,而LVS就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而不满。Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP也是近几年非常流行的web架构,在高流量的环境中稳定性也很好。Nginx现在作为Web反向加速缓存越来越成熟了,速度比传统的Squid服务器更快,可以考虑用其作为反向代理加速器。Nginx可作为中层反向代理使用,这一层面Nginx基本上无对手,唯一可以对比Nginx的就只有 lighttpd了,不过 lighttpd目前还没有做到Nginx完全的功能,配置也不那么清晰易读,社区资料也远远没Nginx活跃。Nginx也可作为静态网页和图片服务器,这方面的性能也无对手。还有Nginx社区非常活跃,第三方模块也很多。
十一、Mysql 中有哪几种锁
- MyISAM支持表锁,InnoDB支持表锁和行锁,默认为行锁
- 表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低
- 行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高
十二、SQL 语句优化有哪些方法
(1)Where子句中:where表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING最后。(2)用EXISTS替代IN、用NOTEXISTS替代NOTIN。(3) 避免在索引列上使用计算 (4)避免在索引列上使用ISNULL和ISNOTNULL(5)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 (6)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描 (7)应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
以上是关于PHP常见问题的主要内容,如果未能解决你的问题,请参考以下文章