Refactor code that was using $GLOBALS?

I’m new to using Slim 3, and have found it relatively quick to pick up – until this (major) hiccup. I have some model classes that do basic CRUD stuff with a database. The PDO DB connection lives at $GLOBALS[‘db’], which is referenced in my model classes. Apparently, Slim is completely incompatible with $GLOBALS (Please tell me this is wrong)?! I’ve made a service for the DB connection instead, but I’m still in the dark about how to actually access this in my regular old PHP classes. I’d rather not have to refactor my models in any significant manner (e.g. implementing new interfaces etc), and it seems like it shouldn’t be necessary. I’m sure I’m missing something completely obvious but the documentation doesn’t really directly address this, and I’m sure someone more familiar with Slim 3 could help me out. Thanks in advance.

Update: I see that $GLOBALS does in fact work, but I can’t initialize a PDO DB connection there… I’ve tested it with arrays and strings, no problems. What gives? My PDO connection code is fine.

Update: I have a potato for a brain. Please delete this thread. restart httpd ftw :frowning:

Try to approach this kind of issues using singleton pattern. Using patterns is a best way to solve problems

Read the link, good information. I often look for design patterns to approach a problem in the best fashion, but I don’t see the value of using the Singleton pattern here. The global pdo connection is only referenced in the abstract parent class of my models, and is established in my index.php. While someone could technically create a new connection somewhere, they could do that anyway if they didn’t know to use my singleton PDO wrapper class. Is your objection to referencing the super global $GLOBALS array? As opposed to referencing a static method of a Singleton class? Singleton or not, there is global state; I’d argue that $GLOBALS is the better place for global state to live for the sake of transparency.

I suppose that you are using a custom ORM, If using a singleton allow you to connect to the database in the index file, a then use el static function “getInstance” to use that connection without require $GLOBAL variable

I guess you could say I used a custom ORM, in that I didn’t use one at all. I had the luxury of building my models by hand for this project, so in the future I may look for an ORM that follows the same principles I did. Sometimes reinventing the wheel is the best way to learn something. I use inheritance rather than composition for generic database object functionality because php encourages it (no mixins).

I understand why avoiding global state is a good rule of thumb, but singletons just hide global state. This just seems like added complexity with zero benefits (other than lazilly connecting to the DB, which would be premature optimization for this project). I plan to use Slim’s built in dependency injection container (Pimple) for injecting services if need be, which is often recommended over using singletons. I’m just wondering why singletons are valuable in PHP when you get $GLOBALS for free, other than preventing multiple instances of a class (which isn’t a good idea for pdo connections anyway).

Some of these GoF design patterns seem like hacks that help avoid code refactoring but make it hard to have DRY, intuitive code. Some notable figures agree (Paul Graham for one). The Singleton pattern just seems like a way to use global state in a sneaky manner.

I think that there are one thousand ways to solve a problem, the right one is what it works for you. I respect you for being brave and make your own tools. I agree with you and with Paul Graham, but I preffer the sneaky way. :slight_smile:

This might be a little help.

namespace App\Utils;

use \PDO;

class dbConfig
{
    private $dblist = [
            'db1' => [
                'dsn'  => 'mysql:host=yourip;dbname=your_db_name;charset=utf8',
                'user' => 'your_user_login',
                'pass' => 'your_pass_login'
            ],
            'db2' => [
                'dsn'  => 'mysql:host=yourip;dbname=your_db_name;charset=utf8',
                'user' => 'your_user_login',
                'pass' => 'your_pass_login'
            ],
            ......
    ];
    
    public function pdo($name)
    {   
        $dbData = $this->dblist[$name];
        $pdo = new PDO($dbData['dsn'], $dbData['user'], $dbData['pass']);
        $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
        return $pdo;
    }
    
}

to use them or to call 'dbconn".

use App\Utils\dbConfig as dbConfig;

class your_class extends dbConfig{
    public function __construct()
    {
        $this->db1= $this->pdo('db1');
    }
    
    public function fetchExist($akun = null){
        try {
            $SQL = "your query code";
            $stmt = $this->db1->prepare($SQL);
            $stmt->execute();
            return $stmt->fetchAll();
        } catch (PDOException $e) {
            throw new Exception('MySQL: ' . $e->getMessage(), 501);
        }
    }}

This only can I give

Interesting approach to handling config, thanks. My actual issue was a
missing MySQL pdo driver that was added and working with php cli, but
required an Apache restart before the server reflected the change. Unless
there are issues with the number of concurrent connections (shouldn’t be
based on small user base), creating one connection per session will
suffice; using the SESSION super global is the most eloquent / terse
solution here. GLOBALS is used temporarily for testing. There’s only one
class that directly references it (I’m using the template method pattern),
so I’m not too worried about the implicit dependency