escaping dependency hell v2
TRANSCRIPT
![Page 1: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/1.jpg)
ESCAPINGDEPENDENCY HELL
Michael Haeuslmann - PHP UG Munich 2016Source: Escape from Hell Constantine by Rommeu
![Page 2: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/2.jpg)
ESCAPING GERMANWINTER?
Michael Haeuslmann - PHP UG Munich 2016Source: Escape from Hell Constantine by Rommeu
![Page 3: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/3.jpg)
PART I: DISCUSSION
![Page 4: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/4.jpg)
WHAT IS DEPENDENCY HELL?
![Page 5: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/5.jpg)
WHAT IS A DEPENDENCY?
... a dependency signifies a supplier/clientrelationship between model elements
where the modification of a supplier mayimpact the client model elements
- UML Specification v2.5
![Page 6: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/6.jpg)
WHY SHOULD WE CARE?
![Page 7: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/7.jpg)
MICHAEL HAEUSLMANN (@MICHAELHAEU)FREELANCER (PHPRAGMATIC.COM)
married, love to travel, board games, ...developing in PHP for ~8 yearsprofessional work in PHP (mostly legacy apps)open source for all the exciting stuff
![Page 8: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/8.jpg)
Buuuut ...
I don't want to be a freelancer anymore ...
... sooooo ...
![Page 9: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/9.jpg)
WE KNOW WE'RE INDEPENDENCY HELL.
HOW DO WE ESCAPE?
![Page 10: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/10.jpg)
COMPLEX VS. COMPLICATEDBubble Sort?
![Page 11: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/11.jpg)
COMPLEX VS. COMPLICATEDBubble Sort?
![Page 12: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/12.jpg)
COMPLEX VS. COMPLICATEDCache Invalidation?
![Page 13: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/13.jpg)
COMPLEX VS. COMPLICATEDCache Invalidation?
![Page 14: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/14.jpg)
COMPLEX VS. COMPLICATEDCache Invalidation?
![Page 15: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/15.jpg)
COMPLEX VS. COMPLICATEDCache Invalidation?
![Page 16: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/16.jpg)
COMPLEX VS. COMPLICATEDCache Invalidation?
![Page 17: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/17.jpg)
COMPLEX VS. COMPLICATEDWeb Applications?
![Page 18: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/18.jpg)
COMPLEX VS. COMPLICATEDWeb Applications?
![Page 19: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/19.jpg)
COMPLEX VS. COMPLICATEDIt doesn't have to be complicated
![Page 20: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/20.jpg)
WHAT DO WE DO ABOUT IT?Read the code and take notes? We don't want to do everything ourselves
use a tool → Managing dependencies in the right way helps with: Complexity, maintenance and understandability
![Page 21: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/21.jpg)
PART II: ANALYSE
![Page 22: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/22.jpg)
WHAT SHOULD DEPENDENCY ANALYSIS TELLUS?
Where should we start refactoring? Why does [SomeClass] always break? What does our architecture actually look like? Is our architecture the way it should be?
![Page 23: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/23.jpg)
TOOLSPHP DEPEND BY MANUEL PICHLER
many metrics many metrics hard to maintain too vague
![Page 24: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/24.jpg)
TOOLSPHP DEPEND BY MANUEL PICHLER
![Page 25: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/25.jpg)
TOOLS
detects even the sneakiest dependencies
generates dependency visualizations
hackable (grep, sed, awk, ...)
for the nerds: written using functional style
supports PHP 5.2 to 7.1
![Page 26: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/26.jpg)
FEATURES Text For quick feedback, debugging, UNIX pipes etc. Visualisations (UML & DSM & dot) Detailed dependency & architectural analysis (Metrics)
![Page 27: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/27.jpg)
DEPHPEND - TEXT OUTPUT$> wget http://phar.dephpend.com/dephpend.phar$> composer global require dephpend/dephpend:devmaster$> dephpend help text _ _____ _ _ _____ _ | | | __ \| | | | __ \ | | __| | ___| |__) | |__| | |__) |__ _ __ __| | / _` |/ _ \ ___/| __ | ___/ _ \ '_ \ / _` | | (_| | __/ | | | | | | | __/ | | | (_| | \__,_|\___|_| |_| |_|_| \___|_| |_|\__,_| version 0.1
Usage: text [options] [] ()...
$> dephpend text ~/workspace/dephpend/src
Mihaeu\PhpDependencies\Util\AbstractMap > Mihaeu\PhpDependencies\Util\CollectionMihaeu\PhpDependencies\Util\DI > Mihaeu\PhpDependencies\Analyser\Analyser...
(*) make sure XDebug is not enabled or use php -n
![Page 28: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/28.jpg)
DEPHPEND - TEXT OUTPUT$> dephpend text ~/workspace/dephpend/src noclasses | sort
Mihaeu\PhpDependencies\Analyser > Mihaeu\PhpDependencies\DependenciesMihaeu\PhpDependencies\Analyser > Mihaeu\PhpDependencies\OSMihaeu\PhpDependencies\Analyser > Mihaeu\PhpDependencies\UtilMihaeu\PhpDependencies\Analyser > PhpParserMihaeu\PhpDependencies\Analyser > PhpParser\NodeMihaeu\PhpDependencies\Analyser > PhpParser\Node\ExprMihaeu\PhpDependencies\Analyser > PhpParser\Node\NameMihaeu\PhpDependencies\Analyser > PhpParser\Node\StmtMihaeu\PhpDependencies\Analyser > PhpParser\NodeVisitor...
$> dephpend text ~/workspace/dephpend/src noclasses \ | grep e 'Analyser > .*OS'
Mihaeu\PhpDependencies\Analyser > Mihaeu\PhpDependencies\OS
![Page 29: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/29.jpg)
DEPHPEND - TEXT OUTPUTMake it yours!
#!/usr/bin/env sh
php build/dephpend.phar text ~/workspace/dephpend/src noclasses | grep \
e 'Analyser > .*OS' \
e 'OS > .*Analyser'
if [ "$?" eq 0 ]; then
echo 'Architecture violation!'
exit 1
fi
![Page 30: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/30.jpg)
DEPHPEND - TEXT OUTPUT
<?php
$output = shell_exec('dephpend text ' .'~/workspace/myMVCFramework/src noclasses');$constraints = [ 'Model.* > .*View', 'View.* > .*Model',];
if (preg_match('/('.implode(')|(', $constraints).')/x', $output)) echo 'Architecture violation'.PHP_EOL; exit(1);
![Page 31: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/31.jpg)
DEPHPEND - UML (SORT OF)dePHPend packages
$> dephpend uml ~/workspace/dephpend/src noclasses output=uml.png
![Page 32: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/32.jpg)
![Page 33: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/33.jpg)
DEPHPEND - UML (SORT OF)Symfony components
$> php d memory_limit=512M dephpend.phar uml \
~/workspace/symfony/src/Symfony/Component \
noclasses \
depth 3 \ # Symfony\Component\HttpKernel\Controller\ArgumentResolver \ # → Symfony\Component\HttpKernel
excluderegex='/Test/' \ # Symfony\Component\HttpFoundation\Tests
output=uml.png
![Page 34: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/34.jpg)
DEPHPEND - UML (SORT OF)Symfony components
![Page 35: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/35.jpg)
DEPHPEND - UML (SORT OF)Symfony HTTP Kernel
![Page 36: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/36.jpg)
DEPENDENCY STRUCTURE MATRIX(DSM)
large graphs are unreadable same data as graph diagrams (e.g. UML class diagram) quick overview for large apps
![Page 37: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/37.jpg)
DEPHPEND DSM
![Page 38: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/38.jpg)
NDEPEND EXAMPLE
![Page 39: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/39.jpg)
![Page 40: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/40.jpg)
![Page 41: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/41.jpg)
![Page 42: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/42.jpg)
![Page 43: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/43.jpg)
PART III: FIX
![Page 44: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/44.jpg)
WHAT DO WE WANT?
We want code which is ... ... easier to understand ... easier to maintain ... easier to test
![Page 45: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/45.jpg)
OBSCURE/NASTY DEPENDENCIES
Some dependencies cannot be detected by any tool (or developer):
Fake collections (array) Overuse of scalar values (int, string, ...) Temporal dependencies, etc.
![Page 46: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/46.jpg)
BE EXPLICIT!
Implicit dependencies are hard to understand/manage!function sendNewsletter( array $customers, string $message);
function sendNewsletter( CustomerCollection $customers, Message $message);
![Page 47: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/47.jpg)
WHICH ALLOCATES MORE RAM?ARRAY
$customer = [ 'id' => 123, 'name' => 'John Doe', 'city' => 'Example City',];
CUSTOM CLASSclass Customer /** @var int */ private $id;
/** @var string */ private $name;
/** @var string */ private $city;
Winner (less RAM): custom classProof: http://www.slideshare.net/patrick.allaert/php-data-structures-and-the-impact-of-php-7-on-
them-php-days-2015
![Page 48: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/48.jpg)
DON'T MAKE ME LOOK IT UP/** * @param mixed $email * @param string|Email|array $email */function addEmail($email) if (is_array($email)) // pray everything inside the array actually is an email foreach ($email as $singleEmail) addEmail($singleEmail); else if (is_string($email)) addEmail(new Email($email)); else if ($email instanceof Email) this>emails[] = email; else throw new InvalidArgumentException('Bad argument type');
![Page 49: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/49.jpg)
DON'T MAKE ME LOOK IT UPfunction addEmail(Email $email) $this>emails[] = $email;
function addEmailString(string $email) $this>addEmail(new Email($email));
function addEmailArray(array $emails) foreach ($emails as $email) /** @var Email $email */ if (is_string($email)) $this>addEmailstring($email); else if ($email instanceof Email) $this>addEmail($email); else throw new InvalidArgumentException('Bad argument type');
function addEmailCollection(EmailCollection $emails) $emails>each(function (Email $email) $this>addEmail($email); );
![Page 50: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/50.jpg)
DON'T MAKE ME LOOK IT UPfunction addEmail(Email $email) $this>emails[] = $email;
function addEmailCollection(EmailCollection $emails) $emails>each(function (Email $email) $this>addEmail($email); );
function addEmailString(string $email) $this>addEmail(new Email($email));
function addEmailArray(array $emails) foreach ($emails as $email) /** @var Email $email */ if (is_string($email)) $this>addEmailstring($email); else if ($email instanceof Email) $this>addEmail($email); else throw new InvalidArgumentException('Bad argument type');
![Page 51: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/51.jpg)
PRINCIPLES OF OO: SOLID
Single responsibility principle Open/closed principle Liskov substitution principle Interface segregation principle Dependency inversion principle
![Page 52: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/52.jpg)
DEPENDENCY INVERSIONBAD:
class CustomerRepository public function __construct() $this>db = new MySQLDatabase(new DefaultConfig());
BETTER:class CustomerRepository public function __construct(MySQLDatabase $db) $this>db = $db;
GOOD:class CustomerRepository public function __construct(Database $db) $this>db = $db;
![Page 53: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/53.jpg)
Easier to understand and test, less likely to break
![Page 54: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/54.jpg)
DEPENDENCY INJECTIONCONTAINERS
$container = new Pimple\Container();
$container['cstmrrepo'] = function ($database) return new CustomerRepository($database);;
$cstmrRepo = $container['cstmrrepo'];
Too easy? obscure dependencies using YAMLadd another 3rd party libraryadd overhead by parsing meta format/sarcasm
![Page 55: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/55.jpg)
AVOID IMPLICIT DEPENDENCIES IN FAVOR OFEXPLICIT ONES
// why not do it yourselves?class DependencyInjectionContainer
// eager load public function getCustomerRepository() : CustomerRepository return new CustomerRepository($this>otherDeps);
// OR: lazy load public function getCustomerRepository() : CustomerRepository if (null === $this>customerRepository) $this>customerRepository = new CustomerRepository($this>otherDeps); return $this>customerRepository;
$dependencyInjectionContainer>getCustomerRepository();
![Page 56: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/56.jpg)
SERVICE LOCATORclass CustomerRepository public function __construct(ServiceLocator $serviceLocator) $this>db = $serviceLocator>getDb();
new CustomerRepository($serviceLocator);
![Page 57: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/57.jpg)
Same or similar implementation, but different usage:
CHOOSE DEPENDENCY INJECTIONCONTAINERS OVER SERVICE LOCATORS
Service Locator provides access to everythingMight as well use globals...(but not really)Target class knows more than it should= more reasons to change (=break)Always choose REAL Dependency Injection
![Page 58: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/58.jpg)
'MEMBER SYMONFY HTTPKERNEL?
![Page 59: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/59.jpg)
WHERE TO GO FROM HERE?improve visualizations command for constraint checks caching better Test & CI integration
Contributions, ideas, feedback, bug reports are welcome!
![Page 60: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/60.jpg)
QUESTIONS
???LINKS
http://www.slideshare.net/michael-haeuslmann/escaping-dependency-hell
https://dephpend.comhttps://github.com/mihaeu/dephpend
![Page 61: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/61.jpg)
HOW DOES IT WORK?
STATIC ANALYSIS
Transform the code to make parsing easierInfer direct types (require, new, type hints, ...)Infer indirect types (DICs, ...)
DYNAMIC ANALYSIS
profile the applicationtrack function tracescollect all possible input values
![Page 62: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/62.jpg)
STATIC ANALYSISEasy right?
use SomeNamespace\SomeClass;
class MyClass extends MyParent implements MyInterface
/**
* @return AnotherClass
*/
public function someFunction(SomeClass $someClass) : AnotherClass
StaticClass::staticFunction();
return new AnotherClass();
![Page 63: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/63.jpg)
STATIC ANALYSISOr is it?
class MyClass
public function someMethod($dependency)
return call_user_func('globalFunction', $dependency);
![Page 64: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/64.jpg)
or:
DYNAMIC ANALYSISXDebug to the rescue!
; php.ini
zend_extension=/path/to/xdebug.so
[xdebug]xdebug.profiler_enable = 1xdebug.auto_trace=1xdebug.collect_params=1xdebug.collect_return=3xdebug.collect_assignments=1xdebug.trace_format=1xdebug.trace_options=1
# https://github.com/mihaeu/dephpend/blob/develop/bin/dephpendphptrace dynamic=/path/to/tracefile.xt S localhost:8080
![Page 65: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/65.jpg)
DYNAMIC ANALYSISTRACE START [20161019 16:59:03]1 0 0 0.000189 363984 main 1 /home/mike/workspace/dephpend/bin/dephpend 0 0
2 1 0 0.000209 363984 get_declared_classes 0 /home/mike/workspace/dephpend/bin/dephpend 80
...
11 211058 0 3.503452 4856528 strpos 0 /home/mike/workspace/dephpend/vendor/symfony/console/Formatter/OutputFormatter.php 177 2 string(15111) string(2)
...3 200813 R long 3.504303 238672TRACE END [20161019 16:59:07]
![Page 66: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/66.jpg)
DYNAMIC ANALYSIS
Parse the trace file and merge with static results
$> dephpend text src \ dynamic=/path/to/tracefile.xt \ filterfrom=YourNamespace \ excluderegex='(Test)|(Mock)'
There are no secrets at runtime!
![Page 67: Escaping Dependency Hell v2](https://reader030.vdocuments.us/reader030/viewer/2022020108/58ed9c0a1a28ab575b8b4595/html5/thumbnails/67.jpg)
@ m i c h a e l h a e u - PHP UG Munich 2016 - h t t p s : / / d e p h p e n d . c o m
CREDITSNDepend
Slide Coder Deviant Art
PDepend Artifacts scaled DSM
http://www.ndepend.com/docs/dependency-structure-matrix-dsm
http://rommeu.deviantart.com/art/Escape-from-Hell-Constantine-204115701
pdepend.org
https://erik.doernenburg.com/2010/04/dependency-structure-matrix/