Description
Description
Following this comment from @fabpot: #32392 (comment) and searching for information in the symfony repository
I've seen an attempt from @jderusse #24267. I still think the proposal was a good idea and we need a DSN component, we could even imagine a DSN contract, let me explain why:
I've looked into all of the symfony components to look for DSN usage, it seems that we use lot's of DSN and even in client project we use more and more DSN.
Lot's of symfony-linked librairies (doctrine, flysystem) use a DSN too, so instead of rechecking and reparsing the DSN all the time, we could have a simple dsn-parser
that would do the job and return a DSN parsed as a PHP array/object.
If we talk about usage in symfony:
-
In the
Cache
💾 component where are parsing two time theredis
DSN:
In the redis trait:symfony/src/Symfony/Component/Cache/Traits/RedisTrait.php
Lines 84 to 90 in 9ab4f14
And in the adapter:
symfony/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php
Lines 136 to 141 in 9ab4f14
We are also parsing a memcache DSN in the adapter.
Both of the redis check could be merged into one and an object could be passed between the two. The exception logic would be merge an a new exception would be thrown. -
In the
Messenger
📮 component we are using DSN in connections classes and in the supports method, maybe a trait comming from the dns parser would help parsing this directly. I give you the exact lines of the code that each connection classes is doing but we know that's Doctrine AMQP, and redis. As an exemple we will only take doctrine.
-
In
HttpKernel
📟 we parse a dsn too, that's the file DSN, it could be reworked to avoid parsing it in here and just getting the value without using substr:
-
In multiple places we parse
PDO
connection DSN with a throw if it's not a DSN, this could be all in the same places it will ease the maintenance and creating new adapter based on PDO:
symfony/src/Symfony/Component/Cache/Traits/PdoTrait.php
Lines 57 to 59 in 9ab4f14
And thePdoCache
it uses the PdoTrait -
In
HttpFoundation
📡 we them found that big method that is parsing all kind of connection based sql DSN, this could totally be in the new DSN parser or in an dsn-sql-adapter ;).
-
In the
Lock
🔒component we parse a DSN too in order to see what store we will instantiate:
symfony/src/Symfony/Component/Lock/Store/StoreFactory.php
Lines 54 to 64 in 9ab4f14
-
And the
Mailer
components parses DSN too, the most widely used config param of the component is a DSN, all of this could simply in the DSN parser and will throw better exception when something is wrong
symfony/src/Symfony/Component/Mailer/Transport.php
Lines 61 to 71 in 9ab4f14
As far I have looked into the code ans searched for DSN usages, I think we can really do something to avoid parsing all the DSN and having a system that will do it for us, to return the right types, the rights errors, the right scheme to have normalized error messages and interface on how we can parse DSN. It would avoid having the DSN parsed two times like in the RedisAdapter and in the RedisTrait.
Talking about symfony ecosystem (like doctrine for exemple) it will help too because since using DSN has been introduced widely when we use env var we can normalize on how we work with DSN.
Example
Like I said in the listing before, we could imagine the whole parsing logic being in the same place with a parser and them multiple connection like we've done with the mailer.
before would still be:
symfony/src/Symfony/Component/Cache/Traits/RedisTrait.php
Lines 84 to 90 in 9ab4f14
after it could looks like this (draaaft)
Either we inject the DsnParser or we use a static method that will return a Dsn Object:
Static version:
$dsn = DsnParser::parse($dsn); // will return the correct Dsn object or throw if the Dsn is invalid
$scheme = $dns->getSchema(); // will return the correct scheme
The object version is quite the same but we use the DependencyInjection to inject an instance of the DsnParser in the classe and to run parse on it.
Maybe we could even imagine a DSN component that contains all the connection that we have in symfony and all of them will be only in the DSN component, either we build a parser with different adapter either we build a whole connection object.
What do you think of this new component ?