Jump to content

OOP - DSN


benanamen

Recommended Posts

I am stuck on the following DI code with the DSN. Relevant lines 62, 77, 78.

 

I expect line 77 to work since the output of line 62 is exactly what works in line 78. I get

 

Fatal error: Uncaught PDOException: could not find driver in C:\Program Files (x86)\Ampps\www\dependencyinjection\DatabaseConnection.php on line 77. 

 

If I use line 78 instead, it works.

 

Anyone know what the problem is?

 

 

$connection var_dump

C:\Program Files (x86)\Ampps\www\dependencyinjection\DatabaseConnection.php:75:
object(DatabaseConnection)[2]
  private 'configuration' => 
    object(DatabaseConfiguration)[1]
      private 'host' => string 'localhost' (length=9)
      private 'port' => int 3306
      private 'username' => string 'root' (length=4)
      private 'password' => string 'mysql' (length=5)
<?php

class DatabaseConfiguration
{
    /**
     * @var string
     */
    private $host;
    /**
     * @var int
     */
    private $port;
    /**
     * @var string
     */
    private $username;
    /**
     * @var string
     */
    private $password;
    public function __construct(string $host, int $port, string $username, string $password)
    {
        $this->host = $host;
        $this->port = $port;
        $this->username = $username;
        $this->password = $password;
    }
    public function getHost(): string
    {
        return $this->host;
    }
    public function getPort(): int
    {
        return $this->port;
    }
    public function getUsername(): string
    {
        return $this->username;
    }
    public function getPassword(): string
    {
        return $this->password;
    }
}

class DatabaseConnection
{
    /**
     * @var DatabaseConfiguration
     */
    private $configuration;
    /**
     * @param DatabaseConfiguration $config
     */
    public function __construct(DatabaseConfiguration $config)
    {
        $this->configuration = $config;
    }
    public function getDsn(): string
    {
        return sprintf(
            '"mysql:host=%s;dbname=test", %s, %s',
            $this->configuration->getHost(),
            $this->configuration->getUsername(),
            $this->configuration->getPassword()
            //$this->configuration->getPort()
        );
    }
}

$config = new DatabaseConfiguration('localhost', 3306, 'root', 'mysql');
$connection = new DatabaseConnection($config);

echo $dsn = $connection->getDsn();// "mysql:host=localhost;dbname=test", root, mysql


    $pdo = new PDO($dsn);// Doesnt Work
    //$pdo = new PDO("mysql:host=localhost;dbname=test", root, mysql); //Works

    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


    $sql  = "SELECT * FROM users";
    $stmt = $pdo->prepare($sql);
    $stmt->execute();

    $result = $stmt->fetchAll();

            echo '<pre>';
            print_r($result);

Link to comment
Share on other sites

The script doesn't make sense. You somehow seem to assume that you can put PHP code into a string, and this string (magically?) turns into application code whenever you reference it.

 

This is conceptually impossible. A string is a string, not code. And the DSN string must contain the DSN, nothing else. You cannot “merge” other method arguments into it.

 

The class layout is also somewhat strange. You again seem to confuse classes and functions. A class is not a function. It's not a procedure which you use to produce a single result like a DSN string. It's an autonomous actor which takes responsibility for an entire subsystem. Going back to the job analogy: When you hire a designer, you want somebody who takes care of all design-related tasks autonomously. They should be able to think for themselves and solve a variety of complex tasks on their own. Your current approach is more like hiring one person who turns on the PC and goes home, then another person who starts Photoshop and goes home, and then you do the design yourself. That's obviously not right.

 

OOP is a lot about proper planning and much less about writing code, so maybe you should start with a class diagram rather than a PHP script. This can be helpful for seeing the bigger picture and avoiding the tunnel vision caused by years of procedural code.

Link to comment
Share on other sites

Except for the DSN string, I didn't write the code. It came from this site that is supposed to be teaching patterns http://designpatternsphp.readthedocs.io/en/latest/Structural/DependencyInjection/README.html

 

From what you see on their page, is what they show wrong? Their example of DI was incomplete lacking the actual DSN part so I had to wing it to see what it did so I could understand it.

 

As far as class diagrams, I have spent many days studying this site teaching patterns using Java that shows a diagram for every Pattern  https://www.tutorialspoint.com/design_pattern/index.htm

 

One pattern diagram they use makes sense, the builder pattern. Not sure how much is the pattern itself, or the real life example of a Fast food meal. All these shapes and animal examples everywhere just aren't cutting it for me. Is this diagram correct? (Also attached to this post) https://www.tutorialspoint.com/design_pattern/builder_pattern.htm

 

What I need to see is a complete, proper working example, otherwise I am just guessing at how it should be done. It is helpful to hear what is wrong with my attempts but seeing how something should be done would go a lot farther.

 

post-179806-0-73916100-1488127324_thumb.jpg

 

 

 

Link to comment
Share on other sites

From what you see on their page, is what they show wrong?

 

The whole chapter is bad. This doesn't teach anything about dependency injection.

 

 

 

What I need to see is a complete, proper working example [...]

 

There are thousands of reputable open-source projects on GitHub covering every single topic and complexity level. This is as real as it gets.

 

Or we can discuss your own projects, but then you need to set specific goals like “I want a wrapper for PDO”.

Link to comment
Share on other sites

The whole chapter is bad. This doesn't teach anything about dependency injection.

 

 

See, that's the problem I keep running into. I don't know enough yet to know if something is wrong. So now, I just spent the last several days trying to learn bad code. I am about ready to just give up on OOP. I have been coding for over 25 years with procedural and have not had any problems with it and any programmer with basic knowledge could jump right in and work on it. I code alone, so any "working on a team" considerations doesnt even matter.

 

Which site is the bad one? Tutorialpoint or the other one?

 

As far as my own projects, I mainly do backend DB apps so starting at the beginning I would need to know how to properly make the DB connection and from there make a query and output the data, let's say starting with a select and tabular records list. I already know to code against an Interface so I can use various DB types. I have read tons of OOP code that does a DB connection. Problem is, I don't know what is right and wrong.

Link to comment
Share on other sites

An example for a good database class is right in front of you: PDO.

 

It's so intuitive that most of the time you don't even realize that it's object-oriented. It does have a few warts, though (like the cumbersome prepare/execute sequence). So a good and even useful project would be to write a streamlined PDO wrapper.

 

For example, there should be a query() method which accepts parameters and then automatically takes care of creating a prepared statement:

$databaseConnection->query('UPDATE foo SET bar = 12 WHERE baz = :baz', ['baz' => 42]);

And the execute() method should return the statement for a more fluent interface:

$foo = $fooStmt->execute(['bar' => 42])->fetchColumn();
Link to comment
Share on other sites

@Jaques1, thanks for the reminder about PDO. So easy to forget it is actually a Class.

 

Getting back to what I am actually doing as mentioned in other threads, my focus is converting the following minimal login/registration procedural app on my repo to OOP.

 

https://github.com/benanamen/perfect_app

 

This project's sole purpose is for practice and learning OOP. Given what is seen in the repo, where is the first place to start? I assumed it would be database.php or public/registration.php, thus the subjects of my last few threads.

 

This project already contains numerous code recommendations from @Jaques1 from over the last couple years as it has proven out to be the proper way to code. I have pretty much tapped out on procedural improvements so I decide to fork and use it to learn OOP. I have already gone the TWIG templating route although it is not reflected in this repo. I didn't want to clutter the space while learning OOP.

 

Any OOP suggestions or recommendations about anything in the repo are welcome. Like most of you, I am just trying to be a better programmer.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.