I think the author's two examples - a logger and a database connection - should be handled differently from each other. The database connection should be passed as a parameter, and the logger should be a global variable.
One difference is that it's reasonable to add logging to nearly any function anywhere, which means that you have to either make the logger global, preemptively provide a logger parameter to almost everything, or else change a whole bunch of method signatures at once every time you need to add logging to somewhere that didn't previously have any log statements. Global variables are unfortunate, but the other options are much worse.
The second difference is that you pretty much only ever have one logger object in a process, but processes often use multiple database connections and it may matter which one is being used. For example, a caller may want to make your function's database accesses part of its transaction. Or use a unit test database instead of a real database. Or a number of other things. Omitting the parameter hides the fact that a function uses the database, which is an important thing to know about it.
You may have many different loggers, and different loggers for different parts of an app. For example, you don't want to log certain database or password related stuff explicitly as it creates a security issues.
Also it's a lot easier to test logging, or anything that you would us a global object for, if it's DI based. That said, you can always pass a config object that holds what would normally be global variables but allows you to override.
One difference is that it's reasonable to add logging to nearly any function anywhere, which means that you have to either make the logger global, preemptively provide a logger parameter to almost everything, or else change a whole bunch of method signatures at once every time you need to add logging to somewhere that didn't previously have any log statements. Global variables are unfortunate, but the other options are much worse.
The second difference is that you pretty much only ever have one logger object in a process, but processes often use multiple database connections and it may matter which one is being used. For example, a caller may want to make your function's database accesses part of its transaction. Or use a unit test database instead of a real database. Or a number of other things. Omitting the parameter hides the fact that a function uses the database, which is an important thing to know about it.