您现在的位置:宠物狐狸 > 宠物美容 > 文章内容

关于PHP商城系统性能优化

宠物狐狸

2019-06-11

关于PHP商城系统性能优化

  最近在研究商城系统源码,在想怎么去更好的优化,一般来说,性能优化可先从大的方向开始考虑,从对影响性能比较大的因素来考虑,比如现在使用,性能可以成倍提高,这些都是客观因素,类似现在网上的开源商城,类似DSmall开源商城系统这类,基本都能支持高版本PHP,最后考虑的应该是PHP语法细节上。

  部署环境  单台服务器常用apache+php和nginx+php-fpm方式部署,我们一直使用apache+php方式,据说现在用nginx+php-fpm部署方式性能比apache+php性能好,可考虑一试。 另外就是像nginx+swoole等,也是可选项。   集群是在此基础上,使用nginx/lvs/云上lbs等反向代理作为负载均衡前端。

PHP集群部署在可靠性的基础上,PHP集群处理性能比单台服务器有N倍提高(但作为服务的整体性能并不一定有N倍提升)。 所以简单地可以认为,通过集群扩展服务器,可以使PHP服务性能得于提升。

  扩展使用  PHP扩展除了使用方便,还是提升性能的亲密伙伴。 主要应用有三点:  1).开启opcode的缓存,来避免重复的编译。

可以使用APC,eAccelerator,XCache等PHP扩展,我们使用xcache。

这种只要安装即可的事。

  2).使用扩展提供的方法(或PHP标准库的方法),扩展实现的效率比PHP代码中的高。 但实际上满足我们项目的扩展方法有限,很多基础方法需要时一步封装,除非有能力自己开发扩展。 可考虑使用扩展实现的PHP框架,如phalcon、yaf。

  3).本地缓存,也常用扩展来支持,比如xcache。

本地可使用缓存扩展,缓存一些配置数据、元数据或主数据,不用每次都从数据库或文件中读取。   另,PHP版本上,现在可以考虑升到PHP7……  3.文件加载和操作  这是非常重要的优化建议,尽量减少文件的读写,文件操作包括:文件读、判断文件是否存在、判断文件大小,特别是对于磁盘,减少文件操作即减少寻道时间,读取时间。 减少一个文件操作,比优化N个CPU指令(request/request_once,echo/print,单引还是双引)、内存的性能效果要好得多。

  实际应用中,关注以下几个地方:  1).把.htaccess的内容写到apache配置中。 平时我们都是通过.htaccess作为文件放置到PHP项目的根目录中,作为URL重写配置等。

这就造成每次HTTP请求,都要先读取.htaccess,多了一次文件操作。

通常.htaccess文件内容也不需要修改,因此可考虑在apache中配置,并禁用.htaccess文件。   2).PHP程序中,减少file_exists等文件操作函数的使用。

在路由框架中,判断要引用的文件是否存在,如果不存在则显示错误,存在则执行文件里的类方法。

  为什么不直接request$invoke[path]呢?其实我们访问的路径(文件),正常的话都是存在的,所以没必要使用file_exists判断是否存在。 但是访问到不存在的文件怎么呢?用set_error_handler方式全局处理。 但是我只想对当前引用文件错误做特殊处理,把错误处理留在自己的框架中,不使用用户的全局的错误处理呢?  在require前,重新设置一个错误处理方法A,并会返回之前设置的错误处理方法;当require文件不存在时,会执行A,require正常时,重新把用户的error_handler设置回去。   还有一个就是日志的处理,可能每次操作日志都要判断一下日志是否存在(不存在即创建)和获取日志大小(分隔日志文件),一般来说,日志文件存在的可能性大,所以直接获取文件大小即可,通过获取日志文件大小一个方法filesize,同时可判断文件是否存在,不存在创建文件即可。 这就减少一个文件操作方法的使用。

如何使用filesize即可获取大小,又可判断文件是否存在,又不离开当前流程,正常执行下去呢?大家可以思考一下,因为filesize一个不存在的文件是会报错误的哦。

  总之,只要是文件存在的可能性或者命中率高,就可考虑不要使用file_exists。

  3).类的加载中,使用精确加载并缓存,不要遍历目录文件的方式。 如果在一个请求中,只加载且只加载一次需要的类文件是最好的。   4).将文件缓存转成内存缓存。   4.框架的选取  除了上面说的PHP扩展框架,还有很多其它非扩展实现的PHP框架,像thinkphp,laravel,这些框架是通用的,封装好、功能全,但自身会损耗一定的性能,主要原因我认为是加载的文件太多、定义的方法变量、检测的东西太多、执行的流程太长。

但既然用了,这个得接受,能做的是在语法细节、代码逻辑上进行优化。

仅就代码执行(没有外部调用,数据库连接等),框架的执行时间远远大于应用代码执行时间,如果你还用上smarty模块引擎,性能必大打折扣。

但是除了性能上考虑,还有很多其它因素值得利用这些成熟框架的。 如果觉得性能是要考虑的方面,可以选择轻量一点、偶合性小的框架、或只选取需要的组件。

  5.功能组件的使用  组合使用,需要对整个框架有一个认识和把控。   1).如果可以选用组件,第一个选择的就是路由组件了,能方便地路由到指定控制器方法即可,不要做多余的事,少用正则匹配,约定优于配置。

  2).类加载功能。

上面说的,按需精确加载并缓存,一次请求有且只require一次。 我们项目类的加载很原始,require_onceandnew。

  3).参数校验和安全处理。 实际上这个也是相对耗费性能的过程,但为了安全还是有必要的。 能做到按需参数处理最好,但是有时为方便,还是会在入口处全局处理安全过滤,参数校验就可以在控制器方法中处理。   4).session,简单地通过配置保存到Redis/memcache等缓存中,或者存到cookie中。

但是根据默认的机制,session初始化(读取)和请求结束(写回),会产生两次网络操作。

根据我们应用场景分析,session内容是不常变的,在不变的情况下可考虑只读而不写回(因此也就有不能更新session修改时间的问题),这就要自己实现PHP会话的接口了,只有当有session修改时,变更的时候才回写session存储,这样,少一个网络操作可省多少时间啊。

有些实现得不好的,在一个请求中多次连接或多次操作存储的,就不可取了。 另外,结合cookieSession,即把session加密存到cookie中,对session的处理也会减少很多耗时。   5).视图模板引擎。 如果是API类接口服务,直接返回数据,如果是网页,那就需要使用模板引擎了。

模板引擎也是很耗费性能的主,当然,喜欢原生态的方式,那是最高效的,像smarty这种,大而全,性能低效,而且很多功能我们都用不上。 我们使用模板引擎,最核心的是html与PHP分离,然后才是变量与语法的处理。

所以,要享受模板引擎的分离好处,又追求性能,那可以参考tmd_tpl。 只实现分离,语法上使用PHP语法,因为如果要自己实现一套语法,需要大量的查找和替换。 同样在模板引擎中,可以进一步合并多个视图文件为一个,减少文件操作等方式来优化。   6).数据库方面。

使用PDO,ORM使用方便但也有一定耗时,数组作为数据对象最高效,一般用短连接,使用单例连接对象或连接池(有些扩展可支持)。