I've been working on a 3-tier architecture and would like some reassurance that my approach is correct as this is for a large project that hopefully will convert 10 years of spaghetti code into an organized system.
The code below has been separated into three layers and it works great so far. The API (works together with some HTML & CSS and AJAX as the presentation layer), Business Logic Layer, and a Data Access Layer. I'm using Slim as you can see for the API.
A few questions I have are:
- In general, is this a proper way to get the layers working together?
- Should the SQL query itself
"SELECT x, y, z FROM ..."
be contained in the business layer as below, or in the DataLayer, or are there times you may require SQL in both BLL and DAL? I've seen both, but restricted to BLL seems like a more logical separation. - In the example below you can see I'm getting users by
company_id
. What if I wanted bycompany_id
andisadmin
? Would best practice be to associate another route and method for that, such as/users/company/:id/admins
with another method such asgetAdminUsers()
? Doesn't seem right as I could pass parameters togetUsers($id, $isadmin)
, but not sure what is best practice here.
API
<?php
require $_SERVER["DOCUMENT_ROOT"] . '/BLL/BLL.php';
require 'Slim/Slim.php';
$app = new Slim();
$app->get('/users/company/:id', 'getUsers');
$app->get('/users/:id', 'getUser');
$app->post('/users', 'addUser');
$app->put('/users/:id', 'updateUser');
$app->delete('/users/:id', 'deleteUser');
$app->run();
function getUsers($id) {
$bll = new BusinessLayer();
$result = json_encode($bll->getAllUsersBLL($id));
echo '{"user": ' . $result . '}';
}
?>
Business Logic Layer
<?php
require_once $_SERVER["DOCUMENT_ROOT"] . "/DAL/DAL.php";
class BusinessLayer
{
var $dal;
function __construct() {
$this->dal = new DataLayer();
}
public function getAllUsersBLL($id) {
$sql = "SELECT * FROM users WHERE company_id = :id ORDER BY id";
$ret = $this->dal->query($sql, $id);
return $ret;
}
}
}
?>
Data Access Layer
<?php
class DataLayer
{
public function connect() {
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "";
$dbname = "testdatabase";
$db = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
}
public function query($sql, $id) {
try {
$db = $this->connect();
$stmt = $db->prepare($sql);
$stmt->bindParam("id", $id);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$db = null;
return $result;
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
}
?>
Any other feedback is more than welcome!