phpgrep
针对PHP代码的语法感知grep工具。
这个仓库用于开发库和命令行工具。 更多实用工具和即用型配方可以在phpgrep-contrib仓库中找到。
概述
phpgrep
既是一个库也是一个命令行工具。
该库可以在Go程序中用于执行语法感知的PHP代码匹配, 而二进制工具可以在你喜欢的文本编辑器或终端模拟器中使用。
它与PhpStorm中的结构化搜索和替换非常相似,但更适合独立使用。
在很多方面,它受到了github.com/mvdan/gogrep/的启发。
另请参阅:"phpgrep:语法感知的代码搜索"。
快速开始
如果你使用VS Code,你可能会对vscode-phpgrep扩展感兴趣。
从最新版本下载phpgrep
二进制文件,将其放在$PATH
下的某个位置。
运行-help
命令以验证一切正常。
$ phpgrep -help
用法:phpgrep [标志...] 目标 模式 [过滤器...]
其中:
标志是在-help中列出的命令行参数(见下文)
目标是要搜索的文件或目录名称的逗号分隔列表
模式是描述要匹配内容的字符串
过滤器是与模式绑定的可选参数
示例:
# 查找带有单个变量参数的f调用。
phpgrep file.php 'f(${"var"})'
# 与上一个示例类似,但在整个目录中递归搜索,
# 并且变量名限制为$id、$uid和$gid。
# 同时使用-v标志使phpgrep输出更多信息。
phpgrep -v ~/code/php 'f(${"x:var"})' 'x=id,uid,gid'
# 在2个文件夹中运行phpgrep(递归)。
phpgrep dir1,dir2 '"some string"'
# 仅打印匹配项,不显示位置。
phpgrep -format '{{.Match}}' file.php 'pattern'
# 仅打印赋值的右侧。
phpgrep -format '{{.rhs}}' file.php '$_ = $rhs'
# 忽略项目中的vendor源代码。
phpgrep --exclude '/vendor/' project/ 'pattern'
可以通过-format标志模板进行自定义输出格式化。
{{.Filename}} 包含匹配的文件名
{{.Line}} 匹配开始的行号
{{.MatchLine}} 包含匹配的源代码行
{{.Match}} 整个匹配字符串
{{.x}} $x子匹配字符串(可以是任何子匹配名称)
输出颜色可以通过"--color-<name>"标志配置。
使用--no-color禁用输出着色。
退出状态:
0 如果有匹配
1 如果没有匹配
2 如果发生错误
# ... 输出的其余部分
创建一个测试文件hello.php
:
<?php
function f(...$xs) {}
f(10);
f(20);
f(30); // 哈!
f($x);
f();
在该文件上运行phpgrep
:
$ phpgrep hello.php 'f(${"x:int"})' 'x!=20'
hello.php:3: f(10);
hello.php:5: f(30); // 哈!
找到2个匹配项
我们找到了所有带有单个参数x
的f
调用,其中x
是不等于20的int
字面量。
接下来要学习的是${"*"}
匹配器。
假设你需要匹配所有带有null
参数的foo
函数调用。
foo
是可变参数函数,所以不知道该参数可能在哪个位置。
这个模式可以匹配任意位置的null
参数:foo(${"*"}, null, ${"*"})
。
阅读模式语言文档以了解更多关于如何编写搜索模式。
阅读用户手册以了解更多关于phpgrep
命令行参数的信息,并获得一些关于如何使用它的见解。
使用方法
本节包含现成可用的phpgrep
模式。
srcdir
是目标源目录(也可以是单个文件名)。
有用的使用方法
# 查找至少有1个重复键的数组。
$ phpgrep srcdir '[${"*"}, $k => $_, ${"*"}, $k => $_, ${"*"}]'
# 查找可以应用`$x ?: $y`的地方。
$ phpgrep srcdir '$x ? $x : $y' # 使用`$x ?: $y`代替
# 查找可以应用`$x ?? $y`的地方。
$ phpgrep srcdir 'isset($x) ? $x : $y'
# 查找可以用$x == $y替换的in_array调用。
$ phpgrep srcdir 'in_array($x, [$y])'
# 查找潜在的运算符优先级问题。
$ phpgrep srcdir '$x & $mask == $y' # 应该是($x & $mask) == $y
$ phpgrep srcdir '$x & $mask != $y' # 应该是($x & $mask) != $y
# 查找函数参数放错位置的调用。
$ phpgrep srcdir 'stripos(${"str"}, $_)'
$ phpgrep srcdir 'explode($_, ${"str"}, ${"*"})'
# 查找没有括号的new调用。
$ phpgrep srcdir 'new $t'
# 查找所有没有{}的if语句主体。
$ phpgrep srcdir 'if ($cond) $x' 'x!~^\{'
# 或者不使用正则表达式。
$ phpgrep srcdir 'if ($code) ${"expr"}'
# 查找所有错误抑制运算符的使用。
$ phpgrep srcdir '@$_'
# 查找所有与null的非严格(==)比较。
$ phpgrep srcdir '$_ == null'
其他使用方法
# 查找所有至少有一个以_id结尾的变量参数的函数调用。
$ phpgrep srcdir '$f(${"*"}, ${"x:var"}, ${"*"})' 'x~.*_id$'
# 查找第二个参数为整数字面量的foo调用。
$ phpgrep srcdir 'foo($_, ${"int"})'
从源码安装
你需要Go工具来从源码安装phpgrep
。
要在你的$(go env GOPATH)/bin
下安装phpgrep
二进制文件:
go get -v github.com/quasilyte/phpgrep/cmd/phpgrep
如果$GOPATH/bin
在你的系统$PATH
中,之后phpgrep
命令应该可用。