0

I've recently started learning Laravel, and I noticed that the DB object is passed via use, allowing access to the object in any created methods. I'm guessing it's done by storing the database connection information as static properties, or referencing the variables internally.

Right now, in my own (non-Laravel) code, I have a PDO and MySQL object created in a file loaded on each page, which I end up importing into any functions/methods via global, but I'm realizing this can be a bit tedious. Is there a better way to do this? The only thing I can think of is to create an object with a static property that is an array of DB objects, and a static function that returns them, so I can access them as DB::use('mysql')->query or what not.

Rohit
  • 3,018
  • 2
  • 29
  • 58

2 Answers2

1

What laravel is using is called traits. It's basically a preprocessor-level shorthand for copy-paste. And yes, the variables that those particular traits access are static (also known as "global state"). Essentially, the laravel is doing it the same as you, but with more syntax sugar. It's bad.

So .. a better way.

Well, there you have three basic options:

  • use a factory to share a connection between multiple objects .. since I'm terrible and lazy, you can just read about in an older answer of mine

  • use a service location, registry or singletons (which are all anti-pattern)

  • use a system called "dependency injection container" or DI container

Now, there are DI containers available out there, but the two options I would urge you to look at would be Auryn and Symfony's DependencyInjection component. They both have pretty good manuals, but one of them is primarily reflection-based and the other is configuration-based.

And the Auryn documentation specifically covers sharing PDO instance as an example.

Now, keep in mind, that DI containers are somewhat advanced concept in general and I would recommend to start out by trying out to use factories. Especially because as you become better at application architecture, you will encounter many situations, where combining factories and DI containers is the best approach.

Any follow up questions?

Community
  • 1
  • 1
tereško
  • 58,060
  • 25
  • 98
  • 150
0

What you should look into is called autoloading. In particular with the namespaces at the top is called PSR-4 autoloading. This is all generated with composer when using Laravel. You can run composer independently from Laravel. Jeffery Way, the creator of Laravel, explains PSR-4 autoloading way better than I could. https://laracasts.com/lessons/psr-4-autoloading

Here's the documentation on using composer for autloading. https://getcomposer.org/doc/01-basic-usage.md#autoloading

Eddimull
  • 342
  • 1
  • 8
  • I've looked at PSR-4; unfortunately my current code is only partially OOP. It's PSR-1/2 compliant, but making it 3/4 compliant will pretty much be an entire rework. Instead, I'm trying to take lessons out of Laravel to implement for now until I get the time to refactor or redevelop the entire thing. Also, given right now the database connections are objects (specifically PDO and the old Mongo class), how will autoloading help? – Rohit Aug 30 '16 at 03:57
  • Hmm, okay. So chances are you have a slew of php files that get hit directly by the browser. So what you can do is have a 'master' file that gets required on all the individual pages. Inside the master file you'll have all your normally required things like session and dbconnections. Also in that master file, you'd have a line for autoloading, so when you're hitting one of your php files, you can call new someClass without having to require or include it on the page. – Eddimull Aug 30 '16 at 04:03
  • Ok, so what I was thinking of at the end of my question, something like a `DB` class with some static methods that can be used to retrieve DB connections. I have master files now, but as mentioned, they contain instances of classes... creating a master DB class seems the way to go, if a bit verbose. – Rohit Aug 30 '16 at 04:38