mactron Posted February 14, 2020 Share Posted February 14, 2020 Hi! I'm new here I'm following an online course where we building CMS using OOP PHP and PDO. I read some articles and watched a few youtube tutorials and to be honest, I'm pretty confused. Some of the developers suggest using function __construct(PDO $connection) inside the class. Their code looks something like that: private PDO $connection; function __construct(PDO $connection) { $this->connection = $connection; connect.php class dbh{ private $host = "localhost"; private $user = "root"; private $pwd = ""; private $dbname = "cms"; protected function connect() { $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname; $pdo = new PDO ($dsn, $this->user, $this->pwd); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); return $pdo; } } function.php // not a whole code class CategoriesData extends dbh{ public function getAllCategories() { $sql = "SELECT * FROM categories_tbl"; $stmt = $this->connect()->query($sql); while ($row = $stmt->fetch()){ echo $row['category_name'] . '<br>'; } } public function getCategoryName() { $sql = "SELECT category_name FROM categories_tbl"; $stmt = $this->connect()->prepare($sql); $stmt->execute(); $category = $stmt->fetch(PDO::FETCH_OBJ); if($category == null) { return null; }else { return $category->category_name; } } public function getCategoryDetials() { $sql = "SELECT * FROM categories_tbl"; $stmt = $this->connect()->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll((PDO::FETCH_OBJ)); return $result; } public function addCategory ($filter_name, $filter_title, $filter_description, $filter_slug) { $sql = "INSERT INTO categories_tbl (category_name, category_title, category_description, category_slug) VALUES (?, ?, ?, ?)"; $stmt = $this->connect()->prepare($sql); $stmt->execute([$filter_name, $filter_title, $filter_description, $filter_slug]); } public function deleteCategory($delete_category_id) { $sql = "DELETE FROM categories_tbl WHERE category_id = ?"; $stmt = $this->connect()->prepare($sql); $stmt->execute([$delete_category_id]); } } } Quote Link to comment Share on other sites More sharing options...
Barand Posted February 14, 2020 Share Posted February 14, 2020 Do not create a connection every time you want to execute a query. connecting probably takes longer than the query so you more than double the execution time you will soon run out of connections certain functions (such as lastInsert() ) are valid only in the current connection Create the connection (once per script unless more than one server is used), store in $this->connection, or similar, and use that each time for the function calls. Quote Link to comment Share on other sites More sharing options...
mactron Posted February 14, 2020 Author Share Posted February 14, 2020 (edited) Honestly speaking I don't know how to use this function inside my class. Did I miss something? Is my code above completely wrong? Please note: The code works like a charm I just don't understand the concept of using function __construct(PDO $connection). Any advice is appreciated! Thanks! Edited February 14, 2020 by mactron Quote Link to comment Share on other sites More sharing options...
ginerjm Posted February 14, 2020 Share Posted February 14, 2020 Have you done any reading on how classes work and how they act when first opened? When one makes a call such as "$myclass_hdl = new MYClass()" one does an "instantiation" of that class and assigns a handle that you continue to use to make further calls to that class and its methods and values. What happens with that "new" call is the construction of a class instance. Whatever you need to do to establish one occurrence (instance) of your class happens at this time. Reading the manual might improve your understanding. Quote Link to comment Share on other sites More sharing options...
mactron Posted February 15, 2020 Author Share Posted February 15, 2020 Hi, is this correct way? I'm on the right path? Thanks! class PostsData extends dbh{ private $conn; public function __construct() { $this->conn = new dbh(); $this->conn = $this->conn->connect(); } public function getPosts() { $sql = "SELECT * FROM posts_tbl"; $stmt = $this->connect()->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll((PDO::FETCH_OBJ)); return $result; } public function addPost($filter_author, $filter_title, $filter_txt) { $sql = "INSERT INTO posts_tbl (post_author, post_title, post_txt) VALUES (?, ?, ?, ?)"; $stmt = $this->connect()->prepare($sql); $stmt->execute([$filter_author, $filter_title, $filter_txt]); } } $post = new PostsData(); $posts = $post->getPosts(); foreach ($posts as $post) { echo $post->post_title; } Quote Link to comment Share on other sites More sharing options...
Barand Posted February 15, 2020 Share Posted February 15, 2020 You are still connecting in each of your functions instead of just once. Try <?php class dbh{ private $host = "localhost"; private $user = "root"; private $pwd = ""; private $dbname = "cms"; protected $conn; // make available to subclass public function __construct() { $this->conn = $this->connect(); } private function connect() { $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname; $pdo = new PDO ($dsn, $this->user, $this->pwd); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); return $pdo; } } class PostsData extends dbh{ public function getPosts() { $sql = "SELECT * FROM posts_tbl"; $stmt = $this->conn->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll((PDO::FETCH_OBJ)); return $result; } public function addPost($filter_author, $filter_title, $filter_txt) { $sql = "INSERT INTO posts_tbl (post_author, post_title, post_txt) VALUES (?, ?, ?)"; $stmt = $this->conn->prepare($sql); $stmt->execute([$filter_author, $filter_title, $filter_txt]); } } $post = new PostsData(); $posts = $post->getPosts(); foreach ($posts as $post) { echo $post->post_title . '<br>'; } ?> 1 Quote Link to comment Share on other sites More sharing options...
mactron Posted February 15, 2020 Author Share Posted February 15, 2020 Your code works, but I don't have a clue with how many connections. Thanks! Quote Link to comment Share on other sites More sharing options...
Barand Posted February 15, 2020 Share Posted February 15, 2020 (edited) Your method creates a connection each time you run a query. That method creates a single connection for each object and uses it for all the queries in the object. Better still would be to create a single connection for the page and pass that one connection to each new object when it is created. At the top of each page, have require 'db_inc.php'; // <--- CONTAINS ----- # const HOST = "localhost"; # const USER = "root"; # const PWD = ""; # const DBNAME = "cms"; # # function pdoconnect() # { # $dsn = 'mysql:host=' . HOST . ';dbname=' . DBNAME; # $pdo = new PDO ($dsn, USER, PWD); # $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); # $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); # $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); # return $pdo; # } # $connection = pdoconnect(); // create connection then your code becomes <?php class dbh { protected $conn; public function __construct($connection) { $this->conn = $connection; } } class PostsData extends dbh{ public function getPosts() { $sql = "SELECT * FROM posts_tbl"; $stmt = $this->conn->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll((PDO::FETCH_OBJ)); return $result; } public function addPost($filter_author, $filter_title, $filter_txt) { $sql = "INSERT INTO posts_tbl (post_author, post_title, post_txt) VALUES (?, ?, ?)"; $stmt = $this->conn->prepare($sql); $stmt->execute([$filter_author, $filter_title, $filter_txt]); } } $post = new PostsData($connection); // pass connection to new object $posts = $post->getPosts(); foreach ($posts as $post) { echo $post->post_title . '<br>'; } ?> Edited February 15, 2020 by Barand 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.