Greph
Поиск кода на чистом PHP, структурный поиск и движок переписывания. Рабочие процессы grep, ripgrep и ast-grep в одном пакете Composer.
composer require greph/grephПоследний выпуск v0.2.3 MIT PHP 8.2+
# Any method call with any arguments
vendor/bin/greph -p '$obj->$method($$$ARGS)' src
# Any function declaration with a void return type
vendor/bin/greph -p 'function $name($$$PARAMS): void {}' src
# Old-style array calls
vendor/bin/greph -p 'array($$$ITEMS)' srcНа практике
Установите пакет с помощью Composer, затем выполняйте поиск и переписывание из командной строки или из PHP.
Ищите, сопоставляйте и просматривайте результат переписывания
-F выполняет поиск по точной строке, -p принимает шаблон в стиле PHP с метапеременными, например $CLASS, а -r добавляет шаблон замены. --dry-run выводит переписанные файлы без записи на диск.
Статический фасад Greph предоставляет те же операции коду PHP. Для установленных как зависимости команд vendor/bin требуется версия 0.2.3 или новее.
# Text search
vendor/bin/greph -F "function" src
# Structural search
vendor/bin/greph -p 'new $CLASS()' src
# Structural rewrite preview
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --dry-run srcuse Greph\Greph;
use Greph\Ast\AstSearchOptions;
use Greph\Text\TextSearchOptions;
$matches = Greph::searchText(
'function',
'src',
new TextSearchOptions(fixedString: true),
);
$asts = Greph::searchAst(
'new $CLASS()',
'src',
new AstSearchOptions(),
);Чистый PHP
Поиск и переписывание выполняются на PHP 8.2+ без бинарных файлов grep, ripgrep или ast-grep. Используются расширения json, ctype и tokenizer, а также zlib для кэшированного хранилища AST.
Поиск по тексту
Поиск по точной строке и регулярному выражению с режимами целого слова, без учёта регистра, контекста, подсчёта и поиска только по файлам. Вывод совместим с grep.
Поиск по AST
Структурный поиск по исходному коду PHP с $VAR и метапеременными $$$VARIADIC, повторными захватами и выводом JSON. Поддерживается только язык PHP.
Переписывание AST
Структурное переписывание с режимами пробного запуска, интерактивным и с записью. Изменяется только совпавший код; комментарии и форматирование вне совпадений остаются прежними.
Индексированные режимы
Создайте индекс текстовых триграмм, индекс фактов AST или кэшированное хранилище AST один раз и используйте его повторно. В тесте производительности проекта построение индекса фактов AST заняло 1.4 s и сократило new $CLASS() с 2.9 s до 11 ms; построение индекса триграмм заняло 12.3 s.
Обёртки rg и sg
vendor/bin/rg и vendor/bin/sg принимают распространённые флаги поиска ripgrep и ast-grep, используя один движок. Не поддерживаются: многострочный поиск, --replace, --type-add и --sort в rg; правила YAML и языки, отличные от PHP, в sg.
PHP API
Greph::searchText(), searchAst() и rewriteAst() возвращают типизированные объекты результатов, поэтому код PHP и агенты вызывают движок без дочернего процесса.
Эталонный набор данных
39 сценариев сравнивают различия между текстовым поиском, AST и выводом переписывания greph, grep, ripgrep и ast-grep. Запустите их командой composer test:oracle в клоне репозитория; CI запускает модульные и интеграционные тесты.
Почему Greph
Без нативных бинарных файлов
Поиск и переписывание выполняются внутри процесса PHP. Бинарные файлы rg, grep и sg используются только для необязательного сравнения производительности.
Один движок для всех режимов
Текстовый поиск, PHP, структурный поиск и переписывание входят в один пакет Composer. Обёртки rg и sg вызывают тот же движок, что и vendor/bin/greph.
Переписывание затрагивает только совпадения
Механизм переписывания подставляет отрисованный шаблон в диапазоны байтов совпадений. Код вне совпадений сохраняет отступы, комментарии и пустые строки.
Прогретые индексы без фонового процесса
Индексы хранятся на диске и используются повторно при следующих запусках. Профиль жизненного цикла определяет, останется ли устаревший индекс без изменений, будет обновлён во время поиска или отклонён.
Сравнение с
Greph объединяет поиск и переписывание в PHP. Эти инструменты решают схожие задачи, и некоторые возможности Greph ему недоступны.
| Инструмент | Подходит для | Отличия от Greph |
|---|---|---|
| ripgrep | Подходит дляИнструмент рекурсивного поиска по регулярным выражениям с полноценной поддержкой Windows, macOS и Linux, а также с бинарными загрузками для каждого выпуска. По умолчанию учитывает правила gitignore и пропускает скрытые и бинарные файлы. | Отличия от GrephGreph устанавливается через Composer и работает в PHP. В тесте производительности CI на корпусе WordPress rg оказался быстрее на каждом холодном текстовом запросе, например 81.62 ms против 458.82 ms при поиске по точной строке. Прогретый индекс Greph ответил на запрос подсчёта за 10.90 ms против 49.61 ms у rg. |
| ast-grep | Подходит дляСкомпилированный CLI для структурного поиска, линтинга и переписывания на основе tree-sitter. Встроенная поддержка охватывает множество языков, в том числе PHP, а файлы правил YAML позволяют задавать проверки и изменения кода. | Отличия от GrephGreph обрабатывает только PHP и не читает правила YAML. При холодном сканировании sg оказался быстрее для array($$$ITEMS) в тесте производительности CI проекта Greph. Прогретый индекс AST Greph ответил на запрос new $CLASS() за 10.89 ms против 4093.61 ms у sg. |
| Rector | Подходит дляОбновляет и рефакторит код PHP с помощью правил и наборов правил, поддерживая версии PHP от 5.3 до 8.5 и такие проекты, как Symfony, PHPUnit и Doctrine. | Отличия от GrephGreph выполняет переписывание по заданным вами шаблону и образцу. Документация исключает его использование, если изменение зависит от информации о типах, которую PHP-Parser не может получить из одного файла, или требует добавления и удаления импортов в разных файлах. |
| PHP CS Fixer | Подходит дляПриводит код к стандартам оформления с помощью встроенных наборов правил, например PER Coding Style от PHP-FIG. | Отличия от GrephGreph не переформатирует файлы. Он изменяет только код, совпавший с шаблоном, а документация рекомендует PHP CS Fixer, если вам нужен форматировщик. |
Источники, отмечено
Вопросы и ответы
Краткие ответы из документации Greph.
Нет. Greph выполняет поиск и переписывание в PHP. Внешние бинарные файлы rg, grep и sg используются только для необязательного сравнения производительности.
Только PHP. Шаблоны и исходные файлы разбираются с помощью nikic/php-parser, а любое другое значение --lang отклоняется как неподдерживаемое.
На холодном сканировании — нет. В тесте производительности CI проекта на корпусе WordPress rg и grep быстрее на каждом холодном текстовом запросе. Прогретые индексы ускоряют повторные запросы: например, индексированный подсчёт занимает 10.90 ms против 49.61 ms у rg.
Greph работает в одном процессе. Без pcntl_fork пул рабочих процессов обрабатывает каждый фрагмент в том же процессе, выдаёт тот же результат, что и -j 1, и не вызывает ошибку.
За пределами совпадений — нет. Код вне совпавших диапазонов байтов сохраняет пробелы, комментарии и форматирование. Совпавший код заново выводится по шаблону, поэтому переводы строк нормализуются, а комментарий внутри него может потеряться. Сначала запустите команду с --dry-run, чтобы вывести переписанные файлы без записи на диск.
По умолчанию в .greph-index, .greph-ast-index и .greph-ast-cache в корне индексируемого проекта. Передайте --index-dir любой подкоманде greph-index, чтобы выбрать другое расположение.
Читайте документацию Greph: справочник по CLI, PHP API, индексированные режимы, а также обёртки rg и sg.