问题
GOAL: I'm interested in generating a DOT Format description of the class dependencies in a PHP program.
IDEA: It shouldn't be hard to write a CodeSniffer "sniff" that can detect (and emit DOT records for) the following patterns in PHP source:
class SomeClassName extends BasicClassName { // SomeClassName refers to BasicClassName
...
new OtherClassName(); // SomeClassName refers to OtherClassName
ThisClassName::some_method(); // SomeClassName refers to ThisClassName
ThatClassName::$some_member; // SomeClassName refers to ThatClassName
RandomClassName::some_constant; // SomeClassName refers to RandomClassName
...
}
But I haven't found any published sniffs to emit this information (and any other patterns indicating a "real" class dependency relationship that I may have missed).
NOTE: I specifically do not care about PHP's include() and require() statements (whose behavior I'm not convinced is even well-defined). For the purposes of this question let's assume that all PHP class resolution is handled via autoloading, and that we're looking to use only static code analysis to build the class dependency diagram.
EDIT: Unfortunately, I see no general way to deal with the following:
class ThatClassName {
...
function generateClassName() {
// something too complicated to analyze statically...
}
function foo() {
$name = $this->generateClassName();
$instance = new $name; // ThatClassName refers to ... what?
...
}
...
}
But of course it would be possible to represent this scenario in a dependency graph by showing ThatClassName with a dependency on the generateClassName() method - perhaps shown with parens to make the method name easily distinguishable from a class name. And it probably wouldn't be a bad idea to establish a convention whereby any method which generates a class name dynamically must contain an annotation (in the associated comment) which indicates every class name which might possibly be generated - these "documented dynamic dependencies" could then be automatically included in the dependency graph.
回答1:
This isn't really what PHP_CodeSniffer is designed to do; specifically because the sniffs are not supposed to output data or write to files. But, there is certainly nothing stopping you from doing this inside a sniff. It's just PHP code after all and it doesn't need to report any errors or warnings.
I haven't come across any sniffs that are doing anything like you describe, so I think you'd have to write a new one.
If you want to create a new sniff, I'd recommend starting with an abstract scope sniff. This allows you to look for T_NEW and T_DOUBLE_COLON tokens inside T_CLASS tokens. Here is an example.
Or, if you also want to look into global functions and other code outside classes, you can just look for T_NEW and T_DOUBLE_COLON tokens inside a regular sniff
If you're not sure how to get started or you just want some help writing the sniff, contact me and I can help write this with you. I'd just need to know what output you'd want for each case found, or I can just use something basic. If you want a hand, my email is: gsherwood at squiz dot net
回答2:
I wrote a tool for this: PhpDependencyAnalysis.
This is an extandable static code analysis for object-oriented PHP-Projects (>= 5.3.3) based on namespaces. It creates dependency graphs on customizable levels, e.g. on package-level or on class-level. Thus, it's usable to declare dependencies in general, but it's also usable to perform a detection of violations between layers in a tiered architecture according to compliance with Separation of Concerns, Law of Demeter and Acyclic Dependencies Principle. You can also change the output format to DOT.
Just check PhpDependencyAnalysis on GitHub.
来源:https://stackoverflow.com/questions/13337708/codesniffer-sniff-for-generating-dependency-graphs-for-php-code