I decided to up my PHP game and learn some OOP. I am re-building my website from procedural to OOP, but since I don't want to use a full framework I fiddle with some components. As a router I use https://github.com/skipperbent/simple-php-router As templating engine I use Twig.
Before I start do more coding I just wanted to ask for your feedback whether my code is considered "good practice" or I would run in some issues while my project grows.
This is my folder structure:
- my project/ - config/ config.php # config incl. db details - public/ index.php # Frontcontroller - src/ - Controllers/ controller.php routes.php - templates/ ...
This is my front controller, public/index.php:
require __DIR__.'/../vendor/autoload.php'; require __DIR__.'/../config/config.php'; /* Load external routes file */ require __DIR__.'/../src/helpers.php'; require __DIR__.'/../src/routes.php'; require __DIR__.'/../src/Controllers/controllers.php'; use Pecee\SimpleRouter\SimpleRouter; SimpleRouter::start();
In the config file, I save the details to connect to the MySQL database in a Class, config/config.php:
class Database { protected $username = 'username'; protected $password = 'password'; protected $servername = 'localhost:3307'; protected $database = 'dbname'; }
In the controller file src/Controllers/controller.php I have my classes:
function load_twig() { $loader = new \Twig\Loader\Filesystemloader('../templates'); $twig = new \Twig\Environment($loader); return $twig; } class db_connection extends Database { public function __construct() { try { $this->dbh = new PDO("mysql:host=$this->servername;dbname=$this->database", $this->username, $this->password); $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDO_EXCEPTION $e) { echo "Connection failed"; } } public function close_db_connection() { $dbh = null; } } class Faq { public function get_faq() { $db = new db_connection(); $query = 'SELECT * FROM faq'; $statement = $db->dbh->prepare($query); $statement->execute(); $row = $statement->fetchAll(PDO::FETCH_ASSOC); $db->close_db_connection($db); return $row; } }
In the src/routes.php I define the routes for the website, e.g. for faq-section:
SimpleRouter::form('/faq', function() { $data = new Faq(); $twig = load_twig(); echo $twig->render('faq.html', ['faq' => $data->get_faq()]); });
So, when someone navigates to FAQ-Section on the website, the class Faq with method get_faq() is called. Within get_faq() I call db_connection Class with __constructor method, which establishes a new connection to the MySQL database, returns a query and the results are stored in $row variable. Afterwards connection to database gets closed. I then pass $row to Twig-Template and data are parsed in my template.
It works fine, but this is probably the easiest query I'll have on my website and I want to make sure this is the right & secure way to do things. I am the only developer and probably no one will ever see the code of the website, but performance might in the future get important and I want to make sure, to do things right from the start.
I wonder if it would make more sense to establish the db connection in the front-controller?
Thanks for your feedback.