Is extending classes a good practice?

I have a PDO connection in my database class, and recently I used this as an extension for other classes, i.e. class Users extends Database this allows me to always maintain a connection to the database without having to have a function in my user class.

However, someone noted that I should not do this as my bad practice, why exactly this bad practice? And how can I connect to my database class in my user class without extension?

Currently, I have a database call inside my viewall() function, which I tried to put in the __construct() function, however, it insisted on having parameters

I tried the code below, but I get the error message as follows:

Fatal error: Call to undefined method Database::prepare() in E:\xampp\htdocs\attendance\class.Register.php on line 13

Any ideas on how I can call my database?

This is my code:

class.Connect.php

 <?php // Database connection PDO class Database { public function __construct() { // Connection information $host = 'localhost'; $dbname = 'attendance'; $user = 'root'; $pass = ''; // Attempt DB connection try { $this->pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //echo 'Successfully connected to the database!'; } catch(PDOException $e) { echo $e->getMessage(); } } public function __destruct() { // Disconnect from DB $this->pdo = null; //echo 'Successfully disconnected from the database!'; } } ?> 

class.Register.php

 <?php require 'class.Connect.php'; class Register { public function viewall() { $pdo = new Database(); $stmt = $pdo->prepare('SELECT * FROM users'); $stmt->execute(); $stmt->fetch(); } } $run = new Register(); $run->viewall(); ?> 
+4
source share
3 answers

A simple rule of thumb: if the extends class is different, then this class is the parent (only slightly modified or extended). You can pass this child class instead of the parent class. Example:

 class Foo { } class Bar extends Foo { } function baz(Foo $foo) { } baz(new Bar); 

This works, baz() expects Foo , but also accepts Bar , because Bar is Foo .

Now, your Users a Database ? Not. Your users are not a database. Your users are using a database. If at all, you should use composition:

 class User { protected $database; public function __construct(Database $database) { $this->database = $database; } } 

The class must comply with its responsibilities. The responsibility of the user management class is to manage user data. Part of this may be talking to the database, but this does not mean that the user management class is a database. If User extends Database , it means that it can do everything that the Database class can do (and much more). This means that you can use the User class everywhere and not the Database class, and that makes no sense. Do not share responsibility.

Now, it is still debatable whether the right structure or not, but it is going in the right direction. But you can really have a User class that represents a single user. Then you have a UserManager or UserORM or UserStorage or something else related to retrieving and storing User objects in the database. This class, in turn, uses Database to do this. This keeps the responsibilities clear and separate. The User class represents user data, the Database class interacts with the database, UserORM/Manager/whatever in the middle negotiates between them.

+8
source

Is class extension practice good?

Well, yes, if you do it right and for the right reason.

The concept of inheritance (class extension) in object-oriented programming works the same way as if you had these objects in the real world.

In the real world, when you use the Car world, then by convention you usually mean all cars, and you consider the common attributes in it, such as wheels, engine, steering, throttle, brake, etc. but there are some cars that have these attributes and some additional ones, for example, a fire truck car also has some additional attributes as an attached ladder, some tubes for throwing water, etc. The same could be taken into account for the “behavior” of certain objects, for example, a car can move, and we mean that you have a turn of the wheels on the road to move (using the car’s movement method). In addition, the firefighter may have enhanced behavior, for example, may move up and down the stairs that he has. This can be modeled using the moveLadder () method in the FireTruckCar class.

If you want to represent these concepts in PHP (OOP) classes, you can do:

class Car {

 protected $wheels; protected $engine; //Rest attributes of Car. public function __construct($wheels, $engine) { $this->wheels = $wheels; $this->engine = $engine; //Initialize more attributes. } function move(){ $this->wheels->rotate(); } //..... 

}


FireTruckCar class extends car {

 //Additional Attributes. //The attributes of Car class belong to this //one too and are accessible as private. protected $ladder; protected $tubes; public function __construct($wheels, $engine, $ladder, $tubes) { //Call the parent constructor, to initialize parent attributes parent::__construct($wheels, $engine); $this->ladder = $ladder; $this->tubes = $tubes; } function moveLadder($direction){ $this->ladder->move($direction); } //... 

}

Of course, there are many additional concepts in inheritance and in general OOP, such as method overload / override, abstract classification, etc., but I am not going to explain them here, since the point will be missed. I suggest you look for the Object-Oriented Programming Principles, although they are well aware of them.

+1
source

There are several ways to connect to the database, so you have a connection throughout the application. For good practice, you can do this easily using another class that can handle your datbase operations, and you extend all of your classes that require db operations from that class.

First change your database class a bit and pass in the arguments to connect to the database, as shown below:

 <?php // Database connection PDO class Database { public function __construct($host, $dbname, $user, $pass) { // Connection information // Attempt DB connection try { $this->pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //echo 'Successfully connected to the database!'; } catch(PDOException $e) { echo $e->getMessage(); } } public function __destruct() { // Disconnect from DB $this->pdo = null; //echo 'Successfully disconnected from the database!'; } } ?> 

Now create another class, let it ObjectModel as shown below

  class ObjectModel { protected $db public function __construct() { $this->db = new Database($host, $dbname, $user, $pass) //ofcourse you can get the db connections details and database name from a config file } // you can have more db operations functions like insert, update, delete etc } 

SO ObjectModel class will handle all your CRUD and other db operations and run queries. Now, if you want to use the $ db object, you can use it directly in the ObjectModel class, as well as in child classes of the OBjectModel, as shown below:

 class Users extends ObjectModel { public function getUsers() { //$this->db-> whatever operation you want to do you can do it using this db object } } 

Remember that ObjectModel has a database class object named $ db, so if your database class uses PDO, then your ObjectModel $ db will have all these operations, i.e. using PDO.

Hope this helps you as well, because I use such an ObjectModel class for my classes, and it saves me a lot of time to write codes again and again :).

Happy coding;)

0
source

Source: https://habr.com/ru/post/1502638/


All Articles