Is there any fundamental flaws in using this approach?
The very first thing you have to understand, is that $pdo
is a part of storage logic. That means, it should be only used inside classes that do abstract data access, be it a SQL table or a collection.
Let's look at your code,
function somefunction(){
global $pdo;
$statement = $pdo->prepare("some query");
$statement->execute();
}
What if you want to switch from MySQL to Mongo/MSSQL/PgSQL, in future?
Then you will have to rewrite a lot of code.
And for each database vendor, you will have to create a separated file with different variable. Just like this
function somefunction(){
global $mongo;
return $mongo->fetch(...);
}
By using a global state, you end up with mass code duplication, because you cannot pass parameters and thus cannot change function's behavior at runtime.
Now let's look at this,
function somefunction($pdo){
$statement = $pdo->prepare("some query");
$statement->execute();
}
Here, $pdo
is passed as an argument, thus there's no global state. But the problem still remains, you end up violating the Single-Responsibility Principle
If you really want something that is maintainable, clean and very readable, you'd better stick with DataMappers. Here's an example,
$pdo = new PDO(...);
$mapper = new MySQL_DataMapper($pdo);
$stuff = $mapper->fetchUserById($_SESSION['id'])
var_dump($stuff); // Array(...)
// The class itself, it should look like this
class MySQL_DataMapper
{
private $table = 'some_table';
private $pdo;
public function __construct($pdo)
{
$this->pdo = $pdo;
}
public function fetchUserById($id)
{
$query = "SELECT * FROM `{$this->table}` WHERE `id` =:id";
$stmt = $this->pdo->prepare($query);
$stmt->execute(array(
':id' => $id
));
return $stmt->fetch();
}
}
Conclusion
It doesn't really matter if your project is small or large, you should always avoid global state in all it forms (global variables, static classes, Singletons) - For the sake of code maintainability
You have to remember, that $pdo
is not a part of your business logic. Its a part of storage logic. That means, before you even start doing something with business logic, like heavy computations, you should really abstract table access (including CRUD operations)
The bridge that brings together your data access abstraction
and computation logic
is usually called Service
You should always pass the things function's need as parameters
You'd better stop worrying about your code and start thinking about abstraction layers.
And finally, before you even start doing any stuff, you'd firstly initialize all your services in bootstrap.php
and then start querying storage according to user's input ($_POST
or $_GET
).
Just like,
public function indexAction()
{
$id = $_POST['id']; // That could be $this->request->getPost('id')
$result = $this->dataMapper->fetchById($id);
return print_r($result, true);
}