Wes
Wes

Reputation: 4306

Can I have circular dependencies in Composer?

I'm writing a package A that is required by some other package B which I'm not publishing for now. At some point A will be changed to use itself B. Chances are they should be both in the same package then, but I'd prefer keeping the two things separate, just for cleanness' sake, and, more importantly, because B is only a dev dependency to A.

package A requires-dev B
package B requires A

I'm curious if this is possible. I'm also curious if it's the same for:

package A requires B
package B requires A

...and...

package A requires B
package B requires C
package C requires A

... or more complex cases. What problems will I encounter?

Thank you.

Upvotes: 4

Views: 2461

Answers (2)

AeonOfTime
AeonOfTime

Reputation: 1024

An example

As Ghost said, circular dependencies create more problems than they solve. How to resolve or remove a circular dependency depends entirely on the use case, but I wanted to provide an example anyway.

I had two packages:

  • A: File system utilities
  • B: Translation tool

The translation tool (B) required the file system utilities (A) to create and save files. However, the file system utilities (B) also used the translation tool (A) because it defined texts that needed to be translated.

On principle alone, there seems to be nothing wrong with that. However, this caused a lot of issues, especially when I started adding continuous integration: composer could not resolve an installable package because of the cyclic dependency, so the tests could not run.

A solution

In my case, the solution was to make the translation tool dependency optional in the file system utilities, since it was not critical for using the package. I moved the translation tool into the suggest section in composer.json:

"suggest": {
    "name/translation": "Needed to translate localizable texts."
}

Of course making one of the packages optional may not always be possible.

Upvotes: 2

GhostCat
GhostCat

Reputation: 140523

A wider, not php-specific answer here: circular dependencies are never a good idea.

You see, you "separate" things into different packages/modules/you-name-it in order to give them a useful structure. To create a "model" that helps you dealing with the complexity of your code.

In other words: you want to define an architecture. And circular dependencies are most often seen as "bad smell" in designs.

Thus you shouldn't ask "would it work?", but "is there a better way to handle this?"

Upvotes: 4

Related Questions