| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| phan.phar | 2026-10-15 | 14.5 MB | |
| phan.phar.asc | 2026-10-15 | 566 Bytes | |
| 6.0.11 source code.tar.gz | 2026-10-15 | 2.3 MB | |
| 6.0.11 source code.zip | 2026-10-15 | 2.7 MB | |
| README.md | 2026-10-15 | 4.0 kB | |
| Totals: 5 Items | 19.6 MB | 1 | |
Performance improvements:
- In the
'balanced'process_file_assignment, also try splitting groups of files weighing more than half or a quarter of an even share (not only more than a whole share) and use the partition with the lowest predicted maximum load: a large class hierarchy that is under a share but placed first no longer leaves one analysis process noticeably heavier than the others (on a large codebase with--processes 4, the heaviest worker went from ~25 % above the mean to a few percent) (#5601) - Speed up the loading of plugins' return type overrides and function call analyzers, which took ~10 s on a large codebase before the analysis processes were forked: the inherited copies of a method are found by walking the subclasses of its class instead of grouping every method of the code base by its defining method, the internal callable-parameter checks are generated once per declared method instead of once per inherited copy, and the analyzer for plugins checking callable arguments is built once per declared method (#5603)
- Add the option
lazy_inherited_methods(off by default): the copies of methods that a class inherits from a parent class declared in a file excluded from analysis (e.g. a test framework) are created on their first lookup instead of when the class is hydrated. On a large codebase with many test classes this cut the wall time by 22-24 % and the peak memory of the main process by ~40 % with identical results; the verification modePHAN_LAZY_INHERIT_VERIFY=1checks every lazily created copy against the copy an eager import would have made. Plugins implementingAnalyzeMethodCapabilitymust also implement the new marker interfaceAnalyzeMethodSkipsInheritedCopiesCapability(theiranalyzeMethod()may then be called late, or not at all, for inherited copies that are never used); otherwise the option disables itself (#5605)
Bug fixes:
- Keep the type of a variable unknown when it is unknown on some branches and known on others:
$x = null; if ($c) { $x = unknown(); }(or the same withtry/catch,switch, a loop, ...) used to make$xexactlynullbecause the unknown branch contributed nothing to the merged type, soPhanTypeMismatchArgument(and related issues) were reported with certainty for a value that may be anything. The merged type is nowmixed(resp.T|mixed), as the ternary operator already inferred in the same situation. This also makes the issues reported by--processes Nruns less dependent on which process analyzed the callee, since a callee's inferred return type is only known to the process that analyzed its file (#5602) - Fix
PhanParamTooManyInternalbeing reported for every call with arguments to 58 internal methods and functions that the PHP 8.2, 8.3 and 8.5 signature deltas listed with their return type only: theRandom\Randomizermethods (getBytes,getInt,pickArrayKeys,shuffleArray,shuffleBytes), the__unserializemethods of the date,SplFixedArrayand random engine classes,Random\Engine\PcgOneseq128XslRr64::jump, the PHP 8.3DOMNodemethodscontains,getRootNode,isEqualNodeandreplaceChildrenon every DOM node class,IntlGregorianCalendar::setDate/setDateTimeandcurl_share_init_persistent. The deltas now have the parameters, and a signature map entry without parameters no longer replaces the parameters known from reflection (#5604) - Fix the false positive
PhanTypeExpectedObjectOrClassNamefornew $x()when$xhas the typeobjectwithout a known class, e.g. amixedvalue narrowed bymethod_exists($x, 'run')toclass-string|object:new $obj()creates an instance of the class of$obj, whatever that class is. The expression now has the typeobject(#5606)