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.