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
إعادات كتابة بنيوية مع أوضاع التشغيل التجريبي والتفاعلي والكتابة. لا يتغير سوى الكود المطابق؛ وتبقى التعليقات والتنسيق خارج التطابق كما هي.
الأوضاع المفهرسة
أنشئ مرة واحدة فهرسًا نصيًا لثلاثيات البايتات (trigram)، أو فهرس حقائق 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 والوكلاء المحرّك دون عملية فرعية.
مجموعة اختبار Oracle
تقارن 39 سيناريو فروق مخرجات greph النصية وAST وإعادة الكتابة مع grep وripgrep وast-grep. شغّلها باستخدام composer test:oracle داخل نسخة مستنسخة من المستودع؛ ويشغّل CI مجموعتي اختبارات الوحدات والتكامل.
لماذا Greph؟
لا حاجة إلى ملفات تنفيذية أصلية
يجري البحث وإعادة الكتابة داخل عملية PHP. ولا تُستخدم ملفات rg وgrep وsg التنفيذية إلا للمقارنات الاختيارية في المعايير المرجعية.
محرّك واحد لكل الأوضاع
يضمّ Composer البحث النصي والبحث البنيوي في PHP وإعادة الكتابة في حزمة واحدة. تستدعي أغلفة rg وsg المحرّك نفسه الذي تستخدمه vendor/bin/greph.
إعادة الكتابة تقتصر على التطابقات
يدمج محرّك إعادة الكتابة القالب المعروض في نطاقات البايتات المطابقة. ويحافظ الكود خارج التطابق على المسافات البادئة والتعليقات والأسطر الفارغة.
فهارس جاهزة دون خدمة خلفية
تُخزّن الفهارس على القرص ويُعاد استخدامها في عمليات التشغيل اللاحقة. ويحدد ملف تعريف دورة الحياة ما إذا كان الفهرس القديم سيُترك كما هو، أو يُحدّث أثناء البحث، أو يُرفض.
مقارنة مع
يُبقي Greph البحث وإعادة الكتابة ضمن PHP. تحل هذه الأدوات مشكلات متقاربة، وتنفذ Greph بعض ما لا تنفذه هذه الأداة.
| الأداة | مناسب لـ | الاختلاف عن Greph |
|---|---|---|
| ripgrep | مناسب لـأداة بحث تعبيرات نمطية تكرارية، مع دعم أصيل كامل على Windows وmacOS وLinux وملفات ثنائية للتنزيل مع كل إصدار. وتحترم قواعد gitignore وتتخطى الملفات المخفية والثنائية افتراضيًا. | الاختلاف عن Grephيثبّت Greph عبر 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. | الاختلاف عن Grephيعيد Greph الكتابة انطلاقًا من نمط وقالب تكتبهما. وتوضح وثائقه أنه غير مناسب للتغيير المعتمد على معلومات الأنواع التي لا يستطيع PHP-Parser حلها من ملف واحد، أو الذي يتطلب إضافة عمليات استيراد أو إزالتها عبر الملفات. |
| PHP CS Fixer | مناسب لـيصحّح الكود ليتوافق مع معايير الترميز، مع مجموعات قواعد مدمجة مثل أسلوب الترميز PER الخاص بـ PHP-FIG. | الاختلاف عن Grephلا يعيد Greph تنسيق الملفات. فهو يغيّر الكود المطابق للنمط فقط، وتشير وثائقه إلى 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.