Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

PHP: inter-class member calls are silently dropped, and language builtins (e.g. `empty()`) get mis-wired to same-name internal methods

クローズ
#3,830 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
php, python
領域
devtools

調査の方向性

Start in extract.py by comparing existing member-call resolvers with the missing PHP path, then inspect _park_unresolved_member_call and _rewire_unique_stub_nodes. Reproduce both missing member edges and builtin mis-wiring using the described PHP corpus, and verify that real calls are resolved or parked while builtin names are not rebound in graph.json.

索引モデルが issue の本文から書いたものです。

説明

Environment

  • graphify 0.9.65 (also reviewed 0.9.66/0.9.67 release notes — no PHP member-call resolver mentioned)
  • Corpus: a ~52 MB Symfony PHP bundle (11,007 nodes / 32,817 edges after extraction), --code-only mode

Problem A — PHP member calls are silently dropped

extract.py ships member-call resolvers for Swift, Python, TypeScript, C++, C#, Java… but there is no _resolve_php_member_calls. A PHP call like:

$this->emailSender->prepareAndSendEmail($action);

produces no edge at all. Empirical check on our graph: EmailSender::prepareAndSendEmail has 0 incoming edges from other files while at least two services call it — all 18 of its incoming calls edges are intra-file self-calls.

Notably, the cross-repo parking mechanism already exists (_park_unresolved_member_call -> metadata.unresolved_calls, ref #3152) but is never invoked for PHP. Our full graph contains zero parked entries with "lang": "php" — the calls are dropped with no trace instead of being parked.

Problem B — builtins get mis-wired to same-name internal methods

_rewire_unique_stub_nodes rebinds a call to the single internal method sharing the callee's name. PHP language builtins collide with that rule:

  • ~200 calls to empty() (language construct) across ~150 files are wired to an internal method ParseCollectionPaginator::empty() — including 24 false edges from two god-node services alone.
  • Same risk class for common names: execute, handle, format.

So the graph is wrong in both directions: missing edges on real inter-class calls, polluted edges on builtin names.

Impact on a real corpus

A local post-processor (tree-sitter-php, same parking format) recovered on this single bundle:

  • -454 false edges removed (builtin rewiring)
  • +1,566 real edges added (typed-property member calls, interface -> implementations)
  • 6,558 calls parked in metadata.unresolved_calls (previously dropped silently)

Suggested fix

  1. Add a PHP member-call resolver: receiver type from typed/promoted constructor properties + $this->method() self-calls; interface calls -> all implementations.
  2. Park unresolved PHP member calls in metadata.unresolved_calls (same payload format as other languages, "lang": "php") so merge-graphs can finish the edges.
  3. Never rewire a builtin callee name (empty, count, strlen, ...) to an internal method — consult a builtin list per language before rewiring.

Repro

Any PHP corpus containing $this->someTypedProperty->method(): the edge is absent from graph.json and nothing appears in metadata.unresolved_calls for the caller. Then add a second method named empty anywhere in the corpus and observe empty() calls being wired to it.

Happy to share our local post-processor (pure post-processing on graph.json, idempotent) if useful as a reference implementation.

主要言語
Python
スター
124k
フォーク
11.9k
PR マージ指標
30日以内にマージされた PR はありません

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

Graphify-Labs/graphify のほかの issue

Graphify-Labs/graphify の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。