/    Sign up×
Community /Pin to ProfileBookmark

Required file (Config) Undefined Property dsn

Looking at PDO tutorials on YouTube and PHP forums trying to figure this out.
This is my Config.php

“`
$db = new Db;
class Db
{
private $host;
private $dbName;
public $user;
public $pass;

public function Connect()
{
$this->host = ‘localhost’;
$this->dbName = ‘core’;
$this->user = ‘root’;
$this->pass = ”;

try
{
$dsn = “mysql:host=”.$this->host.”;dbName=”.$this->dbName;
$pdo = new PDO($dsn, $this->user, $this->pass);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
}
catch (PDOException $e)
{
echo ‘Error: ‘.$e->getMessage();
}
}
}
“`

This is Data.php

“`
require ‘Config.php’;
$data = new Data;

class Data
{
public function __construct()
{
global $db;
try
{
$pdo = new PDO($db->dsn,$db->user,$db->pass);
}
catch (PDOException $e)
{
echo ‘Error’ . $e->getMessage();
}
}
“`

I am getting Undefined Property Db::$dsn in Data.php $dsn is a variable in Config.php, so why is it saying Undefined Property? Appreciate any help, guidance with this.

to post a comment
PHP

17 Comments(s)

Copy linkTweet thisAlerts:
@NogDogNov 21.2021 — $dsn is not a class property, it's a local variable within the __construct() method. If you want to access it as a property, you need to define it as a public property and then assign the result of your PDO instantiation to $this->dsn.

That being said, I don't see why you need both the DB class and the Data class. Let's just simplify things (and avoid using global at all cost!) an do:
<i>
</i>class Db extends PDO // Assuming all we really need is a PDO object
{
private $host = 'localhost';
private $dbName = 'core';
private $user = 'root';
private $pass = 'pass';
public function Connect()
{
$dsn = "mysql:host=".$this-&gt;host.";dbName=".$this-&gt;dbName;
try {
// now we can call the parent PDO constructor:
parent::__construct($dsn, $this-&gt;user, $this-&gt;pass);
$this-&gt;setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
echo 'Error: '.$e-&gt;getMessage();
}
}
}

Then if you do $data = new Db();, you're all set with $data being a PDO object with the desired DB connection.
Copy linkTweet thisAlerts:
@rpjd1authorNov 22.2021 — Then I don't need this

public function __construct()<br/>
{<br/>
try <br/>
{<br/>
$pdo = new PDO($dsn,$user,$pass);<br/>
} <br/>
catch (PDOException $e) <br/>
{<br/>
echo 'Error' . $e-&gt;getMessage();<br/>
} <br/>
}


in Data.php?
Copy linkTweet thisAlerts:
@NogDogNov 22.2021 — > @rpjd1#1639708 Then I don't need this...in Data.php?

Assuming that Data class is something that wants to _use_ the PDO object, I would recommend just passing that into its constructor:
<i>
</i>require 'Config.php'; // creates the $db object
$data = new Data($db); // pass it in to your Data object

class Data {
private $db;
public function __construct(PDO $db) {
$this-&gt;db = $db;
}
public some_data_thing() {
// Can now use $this-&gt;db to do any PDO stuff
}
}

This avoids the use of global, which comes with some bad baggage, while also making the Data class's dependencies clear, which helps with maintenance and testing.
Copy linkTweet thisAlerts:
@rpjd1authorNov 22.2021 — So, Config.php

class Db extends PDO <br/>
{<br/>
private $host = 'localhost';<br/>
private $dbName = 'core';<br/>
private $user = 'root';<br/>
private $pass = 'pass';

<i> </i><CODE>public function Connect()
<i> </i>{
<i> </i> $dsn = "mysql:host=".$this-&gt;host.";dbName=".$this-&gt;dbName;
<i> </i> try {
<i> </i> // now we can call the parent PDO constructor:
<i> </i> parent::__construct($dsn, $this-&gt;user, $this-&gt;pass);
<i> </i> $this-&gt;setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
<i> </i> }
<i> </i> catch (PDOException $e)
<i> </i> {
<i> </i> echo 'Error: '.$e-&gt;getMessage();
<i> </i> }
<i> </i>}</CODE>
}


Data.php

require 'Config.php';<br/>
$data = new Data($db);

class Data<br/>
{<br/>
public function __construct(PDO $db)<br/>
{<br/>
$this-&gt;db = $db;<br/>
}<br/>
public some_data_thing() {<br/>
// Can now use $this-&gt;db to do any PDO stuff<br/>
}<br/>
}


__construct(PDO $db) doesn't match __contruct($dsn, $this-&gt;user, $this-&gt;pass) in Config.php

Notice: Undefined variable: db

Fatal error: Uncaught TypeError: Argument 1 passed to Data::__construct() must be an instance of PDO, null given
Copy linkTweet thisAlerts:
@NogDogNov 22.2021 — The function name for the DB class needs to be __construct() (with double leading underscores), as you are overriding the constructor of the parent PDO class.
Copy linkTweet thisAlerts:
@NogDogNov 22.2021 — PS: Using this forum's ... tags around your code blocks works much better than the &lt;/&gt; button in the edit window (which really is only useful for making a bit of text mono-spaced within a sentence, unfortunately).
Copy linkTweet thisAlerts:
@rpjd1authorNov 23.2021 — The method name for the Db class has double leading underscores. The __construct() in Config has 3 PDO arguments, so shouldn't the parent method look like this?
__construct(PDO $dsn, PDO $user, PDO $pass)
Copy linkTweet thisAlerts:
@NogDogNov 23.2021 — No, I'm calling the parent constructor via parent::__construct() within the child class's constructor, and at that time I'm using the values derived from the child class's properties as the 3 params to the parent.

Frankly, if the only reason for that Db class is to have those connection credentials, I might leave it out all together and just have them set in your config script as either $_ENV elements or just constants, then use them to directly create a PDO object. No big deal either way, but it might make it a bit simpler to configure things as/when any of those values change, or you want to have different values for different environments, etc.
Copy linkTweet thisAlerts:
@rpjd1authorNov 30.2021 — The code in my Db class (Config.php)
<i>
</i>try
{
$dsn = "mysql:host=".$this-&gt;host.";dbName=".$this-&gt;dbName.";charset=".$this-&gt;charset;
$pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE =&gt; PDO::ERRMODE_EXCEPTION));
return $pdo;
}
catch (PDOException $e)
{
echo 'Error: '.$e-&gt;getMessage();
}


This is the constructor in my Data class (Data.php)
<i>
</i>public function __construct()
{
$pdo = new PDO($this-&gt;dsn,$user,$pass, array(PDO::ATTR_ERRMODE =&gt; PDO::ERRMODE_EXCEPTION));
}

This line is giving me Undefined Property for dsn, Undefined variable for user and pass,

and Fatal error: Uncaught PDOException: invalid data source name
Copy linkTweet thisAlerts:
@NogDogNov 30.2021 — > @rpjd1#1640039 This line is giving me Undefined Property for dsn, Undefined variable for user and pass

Then they have not been defined in that context -- but without seeing the class definition, I cannot be sure exactly why. But this is all trying to resolve a problem that shouldn't need solving: creating a database connection in more than one place. I _strongly_ recommend creating your PDO object once, and then passing it in to any class or function that needs to use it. You almost always do not want to create multiple database connections within one PHP script.
Copy linkTweet thisAlerts:
@rpjd1authorDec 01.2021 — I found a PHP tutorial on YouTube that works without using a PDO constructor or a connection class. I can work it for the time being.

This is the Config.php containing Db class
<i>
</i>class Db extends PDO
{
private $host;
private $dbName;
private $user;
private $pass;
private $charset;

<i> </i>public function Connect()
<i> </i>{
<i> </i> $this-&gt;host = "localhost";
<i> </i> $this-&gt;user = "root";
<i> </i> $this-&gt;pass = "";
<i> </i> $this-&gt;dbName = "dbName";
<i> </i> $this-&gt;charset = "utf8mb4";
<i> </i>
<i> </i> try
<i> </i> {

<i> </i> $dsn = "mysql:host=".$this-&gt;host.";dbName=".$this-&gt;dbName.";charset=".$this-&gt;charset;
<i> </i> $pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE =&gt; PDO::ERRMODE_EXCEPTION));
<i> </i> return $pdo;
<i> </i> }
<i> </i> catch (PDOException $e)
<i> </i> {
<i> </i> echo 'Error: '.$e-&gt;getMessage();
<i> </i> }
<i> </i>}
}


It's my understanding, using a connection class as above requires a constructor in the class that queries the database which is executed automatically when an object of the class is created.

In my webpage I have included Logic.php

I create a logic object $logic = new Logic;

Then I call a method in the Logic class $logic-&gt;MethodName();

If I do the same in Logic.php, include Data.php

create a Data object $data = new Data;

Then call a method in the Data from the Logic class $data-&gt;MethodName();

I get Undefined variable: data

This is confusing.
Copy linkTweet thisAlerts:
@NogDogDec 01.2021 — > @rpjd1#1640074 It's my understanding, using a connection class as above requires a constructor in the class that queries the database which is executed automatically when an object of the class is created.

Not sure I follow.

Unless you're dealing with multiple databases, you only ever need one database connection. Since a PDO object is created with a database connection, you only need one PDO object in that case. So, what is the purpose of having this Db class that is extending PDO (and thus creates a PDO object by default), if inside of it you have a method that creates _another_ PDO object? If the only reason is so that you can have your connection parameters built into it, then you can make it much simpler, as I suggested before:
[code=php]
class Db extends PDO {
private $host = "localhost";
private $user = "root";
private $pass = "";
private $dbName = "dbName";
private $charset = "utf8mb4";
public function __construct() {
$dsn = "mysql:host={$this->host};dbName={$this->dbName};charset={$this->charset}";
parent::__construct($dsn, $this->user, $this->pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
}
}

// use it:
try {
$pdo = new Db();
} catch (PDOException $e) {
die('Error: '.$e->getMessage());
}
[/code]

Now you can either use $pdo directly in your script, or pass it in as a parameter to any class or function that needs to talk to that database connection.
Copy linkTweet thisAlerts:
@rpjd1authorDec 01.2021 — Thanks. My only problem is calling a method in the Data class.

If I create a Data object in Logic.php, (Data.php is included in Logic.php) then from the Logic class

$registered = $data-&gt;MethodName();

I get Undefined variable data.

I did the same thing to call a Logic method from my webpage, no issues.
Copy linkTweet thisAlerts:
@NogDogDec 01.2021 — If you go back to https://www.webdeveloper.com/d/397887-required-file-config-undefined-property-dsn/4 I showed you how to pass your Db PDO object into any class that needs to use it. Then within that class you refer to $this-&gt;db (or whatever you prefer to name that class property) when you need to interact with your PDO object.
Copy linkTweet thisAlerts:
@ginerjmDec 01.2021 — I just don't get the supposed "need" to create a class to implement something as simple as a database connection. Granted I am not an OOP guy but in this topic I see an awful lot of effort to simply connect to a db. Years ago I wrote a short block of code implementing a function that I then include in any script that needs a db. Call the function assigning its result to a var and use that everywhere I need it. I added a parm to the function to select the actual db name and another to alter the defined PDO options that I deem necessary and I can do anything with it.

I do hope the OP finally resolves this. Then I hope he looks at how much time he put into this effort and wonders why.
Copy linkTweet thisAlerts:
@NogDogDec 01.2021 — @ginerjm#1640078 Yep, at least as I see it, the Db class is only a convenience(?) to deal with the configuration stuff -- and that can as easily be defined in the config php file, or a separate config.json file imported by it, whatever. Ultimately, whichever way you do it, just create ONE pdo object, and then pass it in to anything else that needs to use it, whether it's a class/object or a procedural function (or even lambda function). Don't keep creating more PDO objects whenever you want to talk to the database.
Copy linkTweet thisAlerts:
@itzeazy21Dec 02.2021 — Thank you for the [details](https://www.itzeazy.com/ownership-transfer-of-car-bike-bangalore.html)
×

Success!

Help @rpjd1 spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 4.23,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...