PHP Opcache 使用

Opcache 是PHP上简单好用,立马见效的优化神器,鸟哥都推荐,那我也要用啊。

Opcache 介绍

Opcache 呢。它的目标是提供一个自由、 开放,和健全的框架用于缓存和优化PHP的中间代码。

OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能, 存储预编译字节码的好处就是 省去了每次加载和解析 PHP 脚本的开销。

PHP 5.5.0 及后续版本中已经绑定了 OPcache 扩展。 对于 PHP 5.25.35.4 版本可以使用 » PECL 扩展中的 OPcache 库。

— 摘自 PHP.net

注意,它和 Alternative PHP Cache (APC) 是一个开放自由的PHP opcode 缓存,是两个东西,别搞混了。

安装

PHP 5.5.0 及后续版本

OPcache 只能编译为共享扩展。 如果你使用 --disable-all 参数 禁用了默认扩展的构建, 那么必须使用 --enable-opcache 选项来开启 OPcache。

编译之后,就可以使用 zend_extension 指令来将 OPcache 扩展加载到 PHP 中。

PHP 5.4 以及更低版本

pecl 下载安装

运行时配置

/php/php.ini

[opcache]
; dll地址
zend_extension=php_opcache.dll

; 启用该拓展打开
opcache.enable=1

; 在cli模式页开启opcache加速 
opcache.enable_cli=1

; 可用内存, 酌情而定, 单位为:Mb
opcache.memory_consumption=128

; Zend Optimizer + 暂存池中字符串的占内存总量.(单位:MB)
opcache.interned_strings_buffer=8

; 对多缓存文件限制, 命中率不到 100% 的话, 可以试着提高这个值
opcache.max_accelerated_files=4000

; 启用,那么 OPcache 会每隔 opcache.revalidate_freq 设定的秒数 检查脚本是否更新。如果禁用此选项,你必须使用 opcache_reset() 或者 opcache_invalidate() 函数来手动重置 OPcache,也可以 通过重启 Web 服务器来清空
opcache.validate_timestamps=0

; Opcache 会在一定时间内去检查文件的修改时间, 这里设置检查的时间周期, 默认为 2, 设置为 0 会导致针对每个请求, OPcache 都会检查脚本更新。单位:秒。 
opcache.revalidate_freq=60

; 打开快速关闭, 打开这个在PHP Request Shutdown的时候回收内存的速度会提高
opcache.fast_shutdown=1

; opcache 不保存注释,减少opcode大小
opcache.save_comments=0


; 启用或禁用在共享内存中的 opcode 缓存。
opcache.file_cache_only=0

;设置不缓存的黑名单
; opcache.blacklist_filename=/png/php/opcache_blacklist

; 配置二级缓存目录并启用二级缓存。 默认值为空字符串 "",表示禁用基于文件的缓存。
opcache.file_cache=/var/www/html/php_cache/
; opcache.file_cache=/var/www/php/cache

更多配置见: php.net

配置好之后,我们运行phpinfo试试看。

如果能看到这界面,说明这个拓展装好了,

注意看到标红,这个说明命中次数,为啥7次呢,因为这个页面我刷行了7次。

使用

opcache_compile_file

该函数可以用于在不用运行某个 PHP 脚本的情况下,编译该 PHP 脚本并将其添加到字节码缓存中去。 该函数可用于在 Web 服务器重启之后初始化缓存,以供后续请求调用。

<?php
/**
* @params string $file 被编译的 PHP 脚本的路径。
* @return boolean 便已成功否
*/
function opcache_compile_file ( string $file ) : boolean

注意事项,Opcache 倾向于编译面向对象编程的代码。并且是在不运行脚本的情况下去编译,也就是它不会判断该脚本在运行时,哪些代码肯定会被执行,哪些不会被执行。也不会判断你的代码执行顺序。它会假设你的代码都会被执行,所以,一些函数的重复定义,会报错。

opcache_invalidate

该函数的作用是使得指定脚本的字节码缓存失效。 如果 force 没有设置或者传入的是 FALSE,那么只有当脚本的修改时间 比对应字节码的时间更新,脚本的缓存才会失效。

<?php
/**
 * @param string $script    缓存需要被作废对应的脚本路径
 * @param bool   $force     
如果该参数设置为TRUE,那么不管是否必要,该脚本的缓存都将被废除。
 * @return bool 成功否,如果脚本的字节码缓存失效设置成功或者该脚本本来就没有缓存,则返回 TRUE;如果字节码缓存被禁用,则返回FALSE。
 */
function opcache_invalidate ( string $script [, boolean $force = FALSE ] ) : boolean

opcache_is_script_cached

此函数检查PHP脚本是否已缓存在OPCache中。这可用于更轻松地检测特定脚本的缓存“变化”。

<?php
/**
 * @param string $file  需要被检查的脚本路径
 * @return bool 如果被Opcache缓存就返回true
 */
function opcache_is_script_cached ( string $file ) : bool

opcache_reset

该函数将重置整个字节码缓存。 在调用 opcache_reset() 之后,所有的脚本将会重新载入并且在下次被点击的时候重新解析。

<?php
/**
 * @return bool 如果字节码缓存被重置成功,则返回 TRUE;如果字节码缓存被禁用,则返回 FALSE。
 */
function opcache_reset ( void ) : boolean

使用说明: 该函数不能和 opcache_compile_file 函数在同一个脚本生命周期调用。 reset 需要用脚本单独调用。

实战

<?php
// file: opcach_init.php
define('DS', DIRECTORY_SEPARATOR);
$basePath = $argv[1];
if (empty($basePath)) {
    $basePath = __DIR__ . DS . '..' . DS . 'php_project';
}
//opcache_reset();  // 不能先reset,再刷缓存,需要在另外一个脚本运行。
//sleep(2);
opcache_compile_files($basePath);
function opcache_compile_files($dir) {
    foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) as $v) {
        if(!$v->isDir() && preg_match('%\.php$%', $v->getRealPath())) {
            opcache_invalidate($v->getRealPath(), true);
            opcache_compile_file($v->getRealPath());
            echo $v->getRealPath()."\n";
        }
    }
}

PHP cli 模式下运行该命令,就会为该目录,以及子目录下php文件生成Opcache 缓存。

$ php ./opcach_init.php ./../php_project/

cachetool

官方网站github

兼容性

  • CacheTool 5.x works with PHP >=7.2
  • CacheTool 4.x works with PHP >=7.1
  • CacheTool 3.x works with PHP >=5.5.9
  • CacheTool 2.x works with PHP >=5.5.9
  • CacheTool 1.x works with PHP >=5.3.3

下载

  1. githup 下载 cachetool.phar:
  1. 从 composer 下载
$ composer require gordalina/cachetool

$ composer require gordalina/cachetool:~1.0

使用


$ php cachetool.phar --help $ php cachetool.phar apcu:cache:info --fcgi $ php cachetool.phar apcu:cache:info --fcgi=127.0.0.1:9000 $ php cachetool.phar opcache:status --fcgi=/var/run/php5-fpm.sock $ php cachetool.phar opcache:status --cli $ php cachetool.phar opcache:status --web --web-path=/path/to/your/document/root --web-url=http://url-to-your-document.root

Laravel 加速

Laravel 一时爽,上线火葬场。赶紧优化一下,不然Laravel做的项目就只剩下优雅的代码了。

好慢

是的,在Laravel开发模式下,有时候会有种在开发JSP应用的感觉一样,改一下重启一下Tomcat的那种速度。

发布到线上,访问的人一多CPU就100%了。

这篇文章就是来改进这个的,让你的Laravel应用加速。

官方推荐

以下Laravel自己优化自己的一些操作。

## 类映射加载优化 ,额,这个命令在Laravel5.6 被移除了
$ php artisan optimize
$ php artisan clear-compiled ## 清理上面的缓存

## 把配置信息 缓存一下
$ php artisan config:cache
$ php artisan config:clear  ## 清理缓存

## 把路由缓存一下
$ php artisan route:cache
$ php artisan route:clear ## 清理缓存

如果你在开发Laravel 过程中,配置没改,路由没改,那么可以把配置,和路由缓存加速一下。

composer 优化

接下来就是路由加速

来自

生成 classmap

执行命令

$ composer dump-autoload --optimize
$ composer dump-autoload -o  ## 或者是简写

这个命令的本质是将 PSR-4/PSR-0 的规则转化为了 classmap 的规则, 因为 classmap 中包含了所有类名与类文件路径的对应关系,所以加载器不再需要到文件系统中查找文件了。可以从 classmap 中直接找到类文件的路径。

权威的(Authoritative)classmap

$ composer dump-autoload --classmap-authoritative
$ composer dump-autoload -a 

执行这个命令隐含的也执行了 Level-1 的命令, 即同样也是生成了 classmap,区别在于当加载器在 classmap 中找不到目标类时,不会再去文件系统中查找(即隐含的认为 classmap 中就是所有合法的类,不会有其他的类了,除非法调用)

注意事项
如果你的项目在运行时会生成类,使用这个优化策略会找不到这些新生成的类。

使用 APCu cache

$ composer dump-autoload --apcu

使用这个策略需要安装 apcu 扩展。
apcu 可以理解为一块内存,并且可以在多进程中共享。
这种策略是为了在 Level-1 中 classmap 中找不到目标类时,将在文件系统中找到的结果存储到共享内存中, 当下次再查找时就可以从内存中直接返回,不用再去文件系统中再次查找。

在生产环境下,这个策略一般也会与 Level-1 一起使用, 执行composer dump-autoload -o –apcu, 这样,即使生产环境下生成了新的类,只需要文件系统中查找一次即可被缓存 , 弥补了Level-2/A 的缺陷。

Opcache 加速

PHP 5.5 都默认打包了该扩展。在配置中启用即可。

下面是一个简单的默认配置:

/etc/php/7.3/fpm/conf.d/10-opcache.ini

; configuration for php opcache module
; priority=10
zend_extension=opcache.so

opcache.enable=1

opcache.memory_consumption=128

opcache.interned_strings_buffer=8

opcache.max_accelerated_files=4000

opcache.revalidate_freq=60

WordPress 加速

自建的Wordpress打开那么慢,想查个资料等半天,那我为啥不去百度呢?停停停,那我还自建什么站,找个写作平台入住就完事了呗。回来,我们还是优化一下自己的博客站点吧。

转圈圈

一访问自建的Wordpress博客,就是——爱的魔力转圈圈。那么如何优化加速自己的博客网站呢。

静态资源 缓存

通过 nginx 配置, 把WordPress里面的jscsspng, jpeg, gif, woff等资源,开启浏览器缓存。

文件路径: /etc/nginx/sites-enabled/wp.www.conf

server {

        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)
        {
            expires      1d;
        }

        location ~ .*\.(js|css)
        {
            expires      1d;
        }
}

CDN加速

还可以把这些静态资源放到CDN上,这样加载js,css,png…这些资源就不用和我们html一起挤那根小水管了。

启用Opcache

为Wordpress运行的环境开启Opcache,在php-fpm 中配置, cli 中配置,只影响 php 明亮行程序。

文件路径: /etc/php/7.3/fpm/conf.d/10-opcache.ini

; configuration for php opcache module
; priority=10
zend_extension=opcache.so

opcache.enable=1

opcache.memory_consumption=128

opcache.interned_strings_buffer=8

opcache.max_accelerated_files=4000

opcache.revalidate_freq=60

一些插件

使用WordPress插件加速。这些插件放链接了,自己了解。

WP Fastest Cache 插件

wp fastest cache

WP Optimize 插件

WP Optimize

版本管理 Hg Mercurial 使用

Hg,Mercuial 常用命令,以及常见问题一览

背景

由于最近公司即将从Mercurial版本管理迁移到GitLab上,特此写下此文纪念一下。

什么是 Hg Mercurial

Mercurial在IT界是跨平台的分布式版本控制软件,主要由Python语言实现。主要是命令行程序操作,图像化呢也有。由于该软件命名中文翻译是——水银,为了输入命令时方便,用元素命名Hg来作为调用程序的关键字。

目前网络上提供托管服务的有bucket

[wiki](https://zh.wikipedia.org/wiki/Mercurial

作者我呢,用过svn,git,最后才接触hg,用来的感觉吧。命令像git,但没git那么复杂,说他像svn呢,感觉这软件比较年轻。

基本操作

## 帮助
$ hg help

## 初始化:
$ hg init

## 查看状态,会展示对改动了哪些被跟踪文件,新增未跟踪文件,冲突文件
$ hg status

## 查看远程仓库地址
$ hg paths

## 查看当前分支
$ hg branch

## 查看日志
$ hg log

内容管理

## 从远程仓库克隆到本地
$ hg clone ssh://code@code.example.com/repository

## 新增文件
$ hg add "file-name"

## 在做了更改后
$ hg commit -m 'change description...'

## 推送该分支的更改到远程仓库
$ hg push -r "version_number"

## 从远程仓库拉取
$ hg pull

## 将拉到本地远程仓库的内容和本地仓库合并
$ hg fetch

## 撤销对当前文件的修改
$ hg revert "file-name"

## 撤销上一次提交,并将上一次提交的内容,放入待提交区
$ hg rollback 

特别说明一下 hg rollback只能回滚一次。意思是:如果你提交了两次,运行rollback两次,也只能回滚最近的那一次。

分支管理

## 创建分支
$ hg branch "new_branch_name"

## 切换到该分支
$ hg update "branch_name"

## 将这个分支合并到当前分支上
$ hg merge "other_branch_name"

## 推送该分支的改动到远程仓库
$ hg push -b "branch_name"

这分支操作,SVN的感觉

草稿

hg草稿管理

## 将当前的被跟踪的改动存到草稿,并命名
$ hg shelve --name "draft_name"

## 展示当前项目的草稿
$ hg shelve --list

## 将这个保存在草稿内的改动应用到当前项目
$ hg unshelve "draft_name"

类比git stash, 使用该功能需要开启拓展 shelve

对比

## 查看当前对跟踪文件的改动
$ hg diff

## 查看当前版本对于"version_number" 版本的不同
$ hg diff -r "version_number"

## 查看ver2相对于ver1的改动
$ hg diff -r "ver1" -r "ver2"

拈来

## 将该版本的提交记录直接复制过来, 命令成功后,会在当前分支生成一个提交记录!
$ hg graft -r "rev"

就是 git cherry-pick

补丁 导入

## 将当前已跟踪文件的更改导入 ./code.patch 文件内
$ hg diff > code.patch
## 将文件内改动应用到当前项目
$ hg import code.patch --no-commit

你可把这个功能当保存草稿用,也能离线推送编辑给别人

其他

hg日志查看

## 查看最新版本
$ hg tip

## 查看日志,并附上分支图
$ hg log -G

## 查看这次提交的日志
$ hg log -r "version_number"

hg 使用了自增自然数,和hash字符共同管理版本号,集svn,git版本号于一身,这下你挑不出毛病了吧

## 查看上一个版本提交日志
$ hg parent

配置

全局配置文件放在~/.hgrc,当前项目的配置文件放在./.hg/隐藏目录内。远程仓库的路径记录在./.hg/hgrc内。

提交用户

配置提交时署名

## file ~/.hgrc
[ui]
username = zhang3 <zhang3@example.com>

拓展管理

hg的拓展管理使用ini格式文件管理,内部拓展只需要写上拓展名就像开关一样,使用第三方拓展需要指明拓展文件路径。


[extensions] shelve = strip = my_ext = ~/my_ext.py

常见问题

hg 与 GUI 工具运行环境冲突

  1. 'hg status' failed with code 255: 'abort: repository requires features unknown to this Mercurial: sparserevlog ! 这个是 sparse-revlog 相关的报错

注意后面那句话 see https://www.mercurial-scm.org/wiki/MissingRequirement, 访问后你可以看到不通版本之间兼容性问题。
如果用了可视化工具如:SourceTree, TortoiseHg。 需要调整配置。

这里拿 SourceTree 举例说明:

  1. Hg 改了配置文件,没生效

如果你在使用SourceTree, TortoiseHg等这样的可视化版本管理工具,一般会自带一个hg软件,要注意改动路径。

Hg 多头问题

产生的原因,往往是提交代码时,没有 hg pull. 操作时提示: abort: push creates new remote head ** on branch **, 解决方案有:

  1. 不管他,hg update -b,hg push -b 等命令替换为 hg update -r,hg push -r,也就是指定推送某个 commit,这样就能避免多个头分支同名时,hg 不知你具体要推哪个分支,直接指定版本号,就可以继续工作了。
  2. 删除 多出来的”头”
$ hg strip -r (需要移除的提交版本号)`

Hg 如何回滚已提交的代码

hg rollback 只能回滚一次未提交到远程的 commit,不得不说 rollback 的运行环境真苛刻。

我们可以这样,为刚刚提交的 commit 创建一个相反的 patch,然后导入patch

## 创建 patch, 例如: hg diff -r 46643 -r 46591 > rollback_commit.patch
$ hg diff -r (rollback commit version) -r (你需要回滚的提交的上一个提交版本号,同一个分支上) > rollback_commit.patch
## 导入 rollback patch
$ hg import  rollback_commit.patch --no-comit
## 查看反向提交的改动
$ hg status

好的,你在工作区就能看到待提交的回滚改动了。检查没问题提交到远程,就完成这个rollback了.

如何快速熟悉项目

如何快速上手一个项目,是每个程序员都会遇到的问题,我来分享一下,我是如何做的

前言

现在好多文章,在教大家如何面试,跳槽。跳了之后呢,如何快速熟悉项目,通过试用期呢。

大家在入职都会面对一个问题,就是熟悉项目。那么熟悉

相信大家都在看到一座代码大(shi)山放到自己面前,都不知从何下手。如果有老同事讲解,健全的文档供查阅,那么入手起来就很方便。但就我入职以来多年经验,大部分公司的项目文档不全。你一入职,老同事就甩手(对,你是去接锅的);除了HR姐姐的入职培训,没有更多的信息;这种情况下,该如何快速入手项目呢。

这里代码部分拿PHP项目举例,其他语言的读者也可借鉴思想。

何谓熟悉了项目

一个项目,它的存在就是为了解决问题,那么熟悉项目就是,了解他能解决什么问题。

那么就需要向这个 项目提问–发起请求。再看我们能得到什么样的回答–响应。

那么我们能提什么问题呢?比如,Android APP问:现在手机手机壳是什么颜色?我要根据这个颜色变换壁纸。显然向项目提出这样的我问题,项目是不能回答的。

那么我们得到了什么回答(响应)呢,我得到了它返回给我的参数。哦不仅仅是这些,这背后它查阅了什么数据,或者更改了什么数据,还给其他项目发送了请求,或者消息,这都是这项目的响应。

所以熟悉项目我们要知道:

  • 可以解决什么问题
  • 解决问题过程中做了什么?

把项目当黑盒

这里我们抽象一下,参考 冯·诺伊曼结构

冯·诺伊曼结构-百度百科图

不论我们的http服务,Api服务,Rpc服务,都可以抽象成如上模型。

http服务的输入就是http请求,运算器是php-fpm程序,控制其表现的是php代码,储存是磁盘,内存,或是redis,输出是http响应

Rpc服务的输入就是TCP报文, 运算器是php常驻程序。

MySQL服务也能这样抽象,输入是MySQL格式编码的TCP报文,运算器,控制器是MySQL程序,存储是磁盘,内存。输出也是TCP报文, 然后在php程序解码出数据。

那么熟悉项目就是可抽象为:

  • 了解系统的I/O

什么是输入输出

一个项目运算器,控制器,就是这个项目的程序代码。存储器就是数据。这就好比一个线团,不知从哪开始理,如果你立马就能看懂咋回事,那么这篇文字你看到这里就可以关了。

在抽丝剥茧时,我们会先找到一个线头作为开始,而代码,就需要找到输入。

网页,APP是项目里所见即所得的输入,也是最容易理解的,从这个方向输入可以看到用户用例。

php我么这里把它作为运算器,php代码作为控制器。

php内部自己实现了一个Zend虚拟机,能编译php代码成opcode并运行。可以把它比做运算器

产生的日志,图片等文件写入,作为项目里面的存储器

数据,不论本地还是远程的,我们都作为输出。(输出数据保存,输出数据查询请求)。特别是关系型数据库,从关系结构可推测出系统建模。

一个具体的项目对用户提供服务,在多服务的架构里,同样它也会是一个请求发出者,此时它发出的请求作为输出。例如:Rpc请求,Redis操作。

自己熟悉项目时,第一时间就开始啃代码是很难的,这是把它当作一个黑盒,从什么样输入,会得到什么样的输出,开始理解系统,只有这中间代码做了什么不用第一时间关心。

就像TDD一样,接到的是需求,不那么关心中间实现过程。这样的参数输入能得到那样的数据返还,这个代码的happy-path就算过关了。

所以接下来,我开始从项目,输入,输出,存储开始给大家讲解快速熟悉项目。

输入

有哪些输入呢?

http请求,tcpwebsocket, 自定义rpc请求。还有消息,cron都是输入。

这里我联想到ServerLess,只关心输入输出

输出

SQL,Redis, Curl, RPC,文件写入,应用对外发出的请求都是输出。

配置日志记录

Http 日志

  • 在浏览器端开启请求记录

例:

这里只是抓了http请求,还有个websocket容易被忽略,可以通过WS标签过滤查看。

在浏览器端开启产看http请求是相较于抓包,避免了添加https证书问题。

  • 在服务端开启日志记录
## file: /etc/nginx/nginx.conf

http {
...
    ## 这是默认的日志
    log_format main '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';
    ##  注意这里新增了一个 $request_body
    log_format log_requets '$remote_addr - $remote_user [$time_local] '
                       '"$request" "$request_body" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';
...
}

nginxaccess_log会记录GET请求以及参数,POST请求就需要额外配置,这里我们新增了一种日志格式——log_requets

## file: /etc/nginx/conf.d/www.conf
server
{
...
    root  /usr/share/nginx/html/xiunobbs/;

    ## 这里使用新的格式日志
    access_log  /var/log/nginx/access_xiuno.log log_requests;
    error_log /var/log/nginx/error_xiuno.log;
...

例:

图中最后一行POST,日志请求记录了提交的内容。

消息队列和Cron输入

消息队列一般要通过查日志记录来查阅。cron这块除了一般的Linux crontab,还有一些专门的cron管理工具。这点需要询问IT运维部门得知。

SQL日志

MySQL举例,数据库软件会有日志记录,为了debug,我们把一般的操作日志打开。这样就能,记录所有提交到该数据库的sql记录。

## file /etc/mysql/my.cnf
general_log_file        = /var/log/mysql/mysql.log
general_log             = 1
log_output              = FILE

配置好,重启数据库,再运行项目就能记录代码的SQL操作了。

例:

至于bin-log,这个只记录编辑操作,不记录查询操作。

Redis日志

monitorredis的调试命令,输入后,当前窗口会返回redis处理的每一个命令,它能帮助我们了解在redis上发生了什么操作。redis是没有任何配置能够将操作命令记录到日志。

Redis 能够记录一些服务状态改变日志,以及慢日志。

登陆到redis-cli,然后键入monitor,\n

这里我们可以用这个命令将日志操作日志记录到文件里。

nohup redis-cli monitor > /var/log/redis/redis_op.log 2>&1 &

Memecached日志

在启动memcaced是带上参数-vv

memcached -vv

通过如下配置把Memcached的日志记录到文件里。

memcached -m 64 -l 0.0.0.0 -p 11211 -u memcache -vv > /var/log/memcached.log 2>&1

RPC 日志

如果该Web项目依赖了RPC,需要也需要进行记录。

日志汇总

捕获到以上日志后,就能知道这个Web项目,接收到到了什么请求,查了什么DB,操作了Redis什么,请求了什么RPC

但是在3个窗口来回切换,有些不便,接下来我们想办法让他们在展示在一个窗口内。

tail -f -q /var/log/nginx/access_xiuno.log   /var/log/mysql/mysql.log /var/log/redis/redis_op.log /var/log/memcached.log

效果如下:

好的这里就是通过日志,配置请求来熟悉代码。

AOP日志

好了到这里,这篇文章就快结束了,什么,以上日志方式你都没发实现,Http网关,数据库,消息队列都是运维在负责,他们做的日志级别不够,或者没有收集。以上都搞不定。

那就要祭出大招,PHP-AOP,这个利器了。在不影响原代码逻辑,注解方式侵入代码,无需DBA,运维配合就能通过PHP代码,完成Requst,MySQL请求,Redis请求的日志记录。

详情看我的文章:PHP7中使用AOP

这里就不做展开了。哦,如果你要熟悉的代码是 函数式编程风格,那么这个Go!AOP就无能为力。动手该代码加日志吧。

文档和代码的关系

Jira/RedMind/Tower/禅道/Teambition 等也存有很多信息,不过这太依赖于公司制度和员工态度,有的人全是口头交流,软件只是用来记录状态的;有的员工事无巨细都记录在案,经手过的任务,都自带Wiki。

代码,于任务管理工具之间的联系,一般是在提交记录或分支名命名带有任务ID号。这样可以通过代码找到任务ID,再查阅当时的备注信息。

最后

通过如上操作,你已能够通过日志,了解到这段代码做了什么,梳理出主要业务。快速上手。至于参数校验,逻辑判断,最总都会落实到I/O操作的不同上。

祝愿你早日熟悉公司业务,扛起大梁。