Download Latest Version 6.0.11 source code.zip (2.7 MB) Google Add to Preferred Sources
Home / 6.0.11
Name Modified Size InfoDownloads / 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 mode PHAN_LAZY_INHERIT_VERIFY=1 checks every lazily created copy against the copy an eager import would have made. Plugins implementing AnalyzeMethodCapability must also implement the new marker interface AnalyzeMethodSkipsInheritedCopiesCapability (their analyzeMethod() 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 with try/catch, switch, a loop, ...) used to make $x exactly null because the unknown branch contributed nothing to the merged type, so PhanTypeMismatchArgument (and related issues) were reported with certainty for a value that may be anything. The merged type is now mixed (resp. T|mixed), as the ternary operator already inferred in the same situation. This also makes the issues reported by --processes N runs 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 PhanParamTooManyInternal being 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: the Random\Randomizer methods (getBytes, getInt, pickArrayKeys, shuffleArray, shuffleBytes), the __unserialize methods of the date, SplFixedArray and random engine classes, Random\Engine\PcgOneseq128XslRr64::jump, the PHP 8.3 DOMNode methods contains, getRootNode, isEqualNode and replaceChildren on every DOM node class, IntlGregorianCalendar::setDate/setDateTime and curl_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 PhanTypeExpectedObjectOrClassName for new $x() when $x has the type object without a known class, e.g. a mixed value narrowed by method_exists($x, 'run') to class-string|object: new $obj() creates an instance of the class of $obj, whatever that class is. The expression now has the type object (#5606)
Source: README.md, updated 2026-10-15