Re: database access [message #174204 is a reply to message #174202] |
Thu, 26 May 2011 16:07 |
sheldonlg
Messages: 166 Registered: September 2010
Karma:
|
Senior Member |
|
|
On 5/26/2011 11:41 AM, Jerry Stuckle wrote:
> On 5/26/2011 10:22 AM, sheldonlg wrote:
>> On 5/26/2011 9:00 AM, Jerry Stuckle wrote:
>>> On 5/26/2011 8:09 AM, sheldonlg wrote:
>>>> On 5/25/2011 5:37 PM, Jerry Stuckle wrote:
>>>> > On 5/25/2011 1:17 PM, Jivanmukta wrote:
>>>> >> I new relatively new to PHP. I need your opinion if the following set
>>>> >> of database functions make sense:
>>>> >>
>>>> >> function openDatabase() {
>>>> >> global $db;
>>>> >> try {
>>>> >> $db = new PDO('mysql:host=' . MYSQL_SERVER . ';dbname=' .
>>>> >> MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD);
>>>> >> $db->exec('SET NAMES latin2');
>>>> >> $db->exec('SET CHARACTER SET latin2 COLLATE latin2_general_ci');
>>>> >> $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
>>>> >> register_shutdown_function('closeDatabase');
>>>> >> } catch (PDOException $e) {
>>>> >> return false;
>>>> >> }
>>>> >> return true;
>>>> >> }
>>>> >>
>>>> >> function closeDatabase() {
>>>> >> global $db, $inTransaction;
>>>> >> if ($inTransaction) {
>>>> >> $db->rollBack();
>>>> >> $inTransaction = false;
>>>> >> }
>>>> >> if (!is_null($db)) {
>>>> >> $db = null;
>>>> >> }
>>>> >> }
>>>> >>
>>>> >> function queryDatabase($sql) {
>>>> >> global $db, $inTransaction;
>>>> >> $result = array();
>>>> >> try {
>>>> >> $qry = $db->query($sql);
>>>> >> if (!empty($qry)) {
>>>> >> $result = $qry->fetchAll();
>>>> >> }
>>>> >> } catch (PDOException $e) {
>>>> >> if ($inTransaction) {
>>>> >> $db->rollBack();
>>>> >> }
>>>> >> error(ERRMSG_DATABASE_OPERATION_FAILED);
>>>> >> }
>>>> >> return $result;
>>>> >> }
>>>> >>
>>>> >> function execDatabase($sql) {
>>>> >> global $db, $inTransaction;
>>>> >> $result = array();
>>>> >> try {
>>>> >> $result = $db->exec($sql);
>>>> >> } catch (PDOException $e) {
>>>> >> if ($inTransaction) {
>>>> >> $db->rollBack();
>>>> >> }
>>>> >> error(ERRMSG_DATABASE_OPERATION_FAILED);
>>>> >> }
>>>> >> return $result;
>>>> >> }
>>>> >>
>>>> >> function startTransaction() {
>>>> >> global $db, $inTransaction;
>>>> >> $db->beginTransaction();
>>>> >> $inTransaction = true;
>>>> >> }
>>>> >>
>>>> >> function commitTransaction() {
>>>> >> global $db, $inTransaction;
>>>> >> $inTransaction = false;
>>>> >> if ($db->commit()) {
>>>> >> return;
>>>> >> }
>>>> >> $db->rollBack();
>>>> >> error(ERRMSG_DATABASE_OPERATION_FAILED);
>>>> >> }
>>>> >>
>>>> >> function rollbackTransaction() {
>>>> >> global $db, $inTransaction;
>>>> >> $inTransaction = false;
>>>> >> if ($db->rollBack()) {
>>>> >> return;
>>>> >> }
>>>> >> error(ERRMSG_DATABASE_OPERATION_FAILED);
>>>> >> }
>>>> >>
>>>> >> function lockTables($tables) {
>>>> >> return execDatabase('LOCK TABLES ' . join(' WRITE, ', $tables) . '
>>>> >> WRITE');
>>>> >> }
>>>> >>
>>>> >> function unlockTables() {
>>>> >> return execDatabase('UNLOCK TABLES');
>>>> >> }
>>>> >
>>>> > Kind of, and maybe a bit overkill. But personally I'd put it all in a
>>>> > Database class. The code would be more flexible and less prone to
>>>> > errors.
>>>> >
>>>>
>>>> Further, I would not have globals. I would pass $db in via the
>>>> constructor. Likewise, I would have $inTransaction be a class variable
>>>> which gets set by the method startTransaction().
>>>>
>>>
>>> That was part of the class, Sheldon. In fact, I wouldn't even pass $db
>>> into the constructor; it (along with $inTransaction, as you note) would
>>> be class variables. That way the rest of the program is completely
>>> independent of the database (and you can have more than one database
>>> active concurrently if you want).
>>
>> If you don't pass it in with the constructor, then you need something
>> like a setDb($parameter) to set the class variable. Passing it along
>> with the constructor does not limit you to only one database
>> concurrently. After all, you could readily do
>>
>> $dbObj1 = new DatabaseClass($db1);
>> $dbObj2 = new DatabaseClass($db2);
>>
>> What passing it along inside the constructor does is (a) it saves a line
>> of code each time in the invocation process(es) and (b) uniquely
>> identifies a particular instance of the class. Since the DatabaseClass
>> _MUST_ have the db defined, there is no problem with passing it in with
>> the constructor and no reason not to do so.
>>
>
> A better way would be to pass the basic information to the constructor -
> i.e. the host, userid, password and database name. Let the constructor
> build the database object. That way it is completely encapsulated and
> the rest of the program is not dependent on a database object. If he
> later finds he wants to change database objects (i.e. maybe PDO is to
> slow and he wants to use mysqli), he can do so without changing anything
> in the rest of the program. The class is now more fully encapsulated.
>
> A very good reason for not passing it to the constructor.
Good point. It would be best to pass those three instead. Point was
that I was making is that it is best to pass what is _ALWAYS_ needed
through the constructor. Your suggestion is better.
--
Shelly
|
|
|