And here i am again! ;)
Im developing (well, im still in planning phase) a web-app where i would give to other developer the possibility to write theyr own plugins/modules (in the way of CMS does, drupal, joomla, etc).
My problem is that i have to force the developers to use the methods i wrote for interact with databases, for many reasons (data integrity first). I dont need primarly to keep secret the database structure, but if it is possible too, is appreciate.
So, in short, my goal is:
- Keep 'protected' and not accessible from outside my classes the database connection;
- If possible (but should be a consequence of point 1) keep secret the real database structure;
The plugins/modules behavior will be implemented like the Drupal hooks.
So, an short example of my current situation:
<?php
// File dbclass.php
class DbHandler{
/*
* As simply as i could ;)
*/
private $dbLink;
public function __construct(){
$this->dbLink = pg_connect("host=127.0.0.1 user=myuser password=mypassword dbname=mydatabase");
}
public function __destruct(){
pg_close($this->dbLink);
unset($this->dbLink);
}
}
?>
and the module call:
<?php
// An general situation
require('dbclass.php');
/*
* The DbHandler consctruct function open a database connection.
*/
$init = new DbHandler();
/*
* [..i'll do something here..]
*/
/*
* Lets say this is inside a function/hook of an enabled module;
* This is the behavior i want to avoid!
* How to keep the database connection 'within' my
* DbHandler object's instance?
* p.s: in real life i do use prepared stmt
*/
$qrUsers = pg_query('SELECT * FROM users');
if(pg_num_rows($qrUsers) != 0){
echo '<h2>Query success!</h2>';
//do something
}else{
echo '<h2>Query Fail!</h2>';
}
//Actual Output: Query Success! [...]
//Desidered output: Warning: pg_query() [function.pg-query]: No PostgreSQL link opened yet in /var/www-lighttpd/dbtest.php on line xx Query Fail!
?>
I want that if the developer try to execute directly a query, it will fail, and in the example i posted, he is forced to use a method like (for example)
$users = new User();
$users -> get_all();
Im running on postgresql, but i suppose the problem is the same on Mysql.
As far as i thought, the only way i can do that is to close the connection before call all the modules hooks, and then reopen and reclose it every time a hooks need to CRUD the database. But i really dislike this solution, wont be efficient.
If someone have betters ideas, please share them with me!
p.s: my english is poor, i hope the question is clear.
EDIT: the Oddthinking solution seem to be the best for me: the opening and immediately closing the ghost connection will prevent every next pg_* or mysql_* function call. This solution, in couple with renaming the pg_* or mysql_* functions with runkit / apd with custom names will (i think) definitely avoid any uncontrolled access to the DB by the modules/plugins.