The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. September 21, 2019, 12:56:30 PM

Login with username, password and session length


Pages: [1] 2
  Print  
Author Topic: DB class  (Read 5273 times)
nutballs
Administrator
Lifer
*****
Offline Offline

Posts: 5627


Back in my day we had 9 planets


View Profile
« on: January 23, 2008, 09:57:42 PM »

I know someone (td i think) just suggested we work a bit on getting a good DB class going, but im an impatient bastard and I am still busy trying to make my framework. So....

can someone help me to refine this class that I am trying to wrap my baby-fucked brain around...
This is a very simplified class, only opening the database connection. I just need to make sure I am heading in the right direction.

Code:
class database
{
public $conn;

function __construct() {
       $GLOBALS['database'] = &$this;
       opendb('server','database','username','password');
    }

public function opendb($server,$database,$username,$password)
{
    $db = mysql_connect( $server, $username, $password,true) or die('Could not connect to database server.' );
    mysql_select_db($database, $db) or die('Could not select database.');
    $this->conn = $db;
}

}
the result in theory would be an ability to access the connection from any other class, via the $globals array. make sense? so what am i doing that is fataly wrong, if i am doing such a thing? it physically works though.
Logged

I could eat a bowl of Alphabet Soup and shit a better argument than that.
vsloathe
vim ftw!
Global Moderator
Lifer
*****
Offline Offline

Posts: 1669



View Profile
« Reply #1 on: January 24, 2008, 07:22:03 AM »

Looks good to me. I try not to use any PHP5 specific stuff so that my code will work on shared hosting, but it looks like you don't care about that.
Logged

hai
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #2 on: January 24, 2008, 08:38:53 AM »

Couple thoughts NB -

although putting the global reference to the object in the constructor looks interesting, this makes the class a singleton (or at least it should be) because if you accidentally create it twice, you'll overwrite the handle of the first one. The simplest fix here would be:

Code:
<?php

__construct
()
{
if ($GLOBALS['database'])
throw new Exception('Recreating the database object! Bad Nutballs! Bad Nutballs!');

// now proceed on as you had...
}
?>



But that being said, I'm just not a fan of doing that because it locks me into a single usage of that class. I do something very similar, but in my primary code instead so that I can create more DB instances if I wish. For example:

$db = new dbConnection('127.0.0.1', 'username', 'password', 'database');
$GLOBALS['utilDB'] = &$db;

I often have multiple database connections open (think master detail) and maintain a single "utility" database system wide but then create others as I need them.

Note also that I put the connection parameters right into the constructor - this is because I wanted to infer that a db connection is bound to ... erm ... it's connection. If I need to do something as weird as connect to two different databases then I create two different connections rather than re-using, because the code is harder for me to read. However, those params on the constructor do not force an "open" of the db yet... there is a flag set in the constructor that says "connected = false" and the actuary methods (query, singleAnswer etc) first check to see if the object is connected before executing. This makes it so that I can include a DB object every page pull with almost no overhead - regardless of if I use it or not - because it won't actually connect until it is needed.

<edit>I forgot - my base class for dbConnect is in the php repository... perhaps that's what you're thinking of, unless that one is really inadequate - in which case, I'd really love to know it so I can grow it</edit>
« Last Edit: January 24, 2008, 08:41:12 AM by perkiset » Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
m0nkeymafia
Expert
****
Offline Offline

Posts: 240


Check it!


View Profile
« Reply #3 on: January 25, 2008, 02:11:16 AM »

I believe we should set a standard of making errors talk about yourself in the third person.

i.e.
"m0nkeymafia is displeased at your lack of skill"
Logged

I am Tyler Durden
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #4 on: January 25, 2008, 04:47:54 AM »

That's SO kaptain of you
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
m0nkeymafia
Expert
****
Offline Offline

Posts: 240


Check it!


View Profile
« Reply #5 on: January 25, 2008, 05:25:13 AM »

That's SO kaptain of you

m0nkeymafia is confused!  Huh?
Logged

I am Tyler Durden
nutballs
Administrator
Lifer
*****
Offline Offline

Posts: 5627


Back in my day we had 9 planets


View Profile
« Reply #6 on: January 25, 2008, 07:56:19 AM »

i must have been multitasking when I posted this. I do what you suggested perk, creating the object with the database vars. I don't know why I had them hard coded into the class. This is what I actually have.
   function __construct($s,$d,$u,$p) {
       $GLOBALS['database'] = &$this;
       $this->opendb($s,$d,$u,$p);
      }
« Last Edit: January 25, 2008, 07:59:17 AM by nutballs » Logged

I could eat a bowl of Alphabet Soup and shit a better argument than that.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #7 on: January 25, 2008, 08:16:20 AM »

@ MM - The Kaptain used to talk 3rd person for every post, it was hilarious

@NBs - figured you did, thought that was pseudo code. Still recommend the "don't instantiate if already created" bit tho...
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
nutballs
Administrator
Lifer
*****
Offline Offline

Posts: 5627


Back in my day we had 9 planets


View Profile
« Reply #8 on: January 25, 2008, 08:23:26 AM »

i agree. thats the kind of thing I usually leave out because i am in a rush/lazy/confused and regret later. adding now... to all my classes that use the $GLOBALS.

although this did make me realize something. My db class could not instantiate more than once anyway to connect to more than 1 db i think? because I use the $GLOBALS.
$GLOBALS['database'] = &$this;
is set the first time the object is created, so if i tried to make another object, $dbother, then it would lose the first object pointer stored in $GLOBALS['database'] because the new pointer would be written.

err. i gotta rethink that. for my other classes, they are pure singletons, and I want it that way, but for the DB class, singleton is not acceptible. 99% of the time it should be, but there is that 1% that I should be prepared for.
Logged

I could eat a bowl of Alphabet Soup and shit a better argument than that.
nutballs
Administrator
Lifer
*****
Offline Offline

Posts: 5627


Back in my day we had 9 planets


View Profile
« Reply #9 on: January 25, 2008, 11:20:41 AM »

ok actually to make it a non-singleton (though it technically still is) I added the ability to set the reference name as you construct it. This is my actual code, unmodded, so its using other classes you are not aware of obviously.

Code:
$database = new database($config->dbserver,$config->dbdatabase,$config->dbuser,$config->dbpassword,'database1');
$database = new database($config->dbserver,$config->dbdatabase,$config->dbuser,$config->dbpassword,'database2');

function __construct($s,$d,$u,$p,$name) {
//Server,database,username,password,$GLOBALS name
if ($GLOBALS[$name])
{
$messages = &$GLOBALS['messages'];
$messages->adderr('database.class.php $GLOBALS[\''.$name.'\'] is being constructed more than once.');
}
else
{
$GLOBALS[$name] = &$this;
$this->opendb($s,$d,$u,$p);
}

    }
Logged

I could eat a bowl of Alphabet Soup and shit a better argument than that.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #10 on: January 26, 2008, 12:16:01 PM »

Way better. That looks good man
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
nutballs
Administrator
Lifer
*****
Offline Offline

Posts: 5627


Back in my day we had 9 planets


View Profile
« Reply #11 on: January 26, 2008, 04:53:34 PM »

the only problem is references from within other classes, specifically my ApplicationSpecific class. Since the object is created in the main document, the name of the $GLOBALS is not knows to the classes which might depend on it. However, since the database is never used by any of my other base classes, I guess it doesnt matter. and if it does, I will just create a local instance.
Logged

I could eat a bowl of Alphabet Soup and shit a better argument than that.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #12 on: January 28, 2008, 12:48:48 PM »

Two ways to handle that - either use generic names that you always rely on (I use utilDB) or use an array that is held by GLOBALS that has a list of available dbs ie:

Code:
<?php
$db 
= &$GLOBALS['utilDB'] = new dbConnection($host$user$pass$db);
$GLOBALS['dbHash']['utilDB'] = 'utilDB';
?>


Now if you iterate through GLOBALS['dbHash'] you'd have the names of all global DBs you'd created. If you had your own "standard" list of db objects, then if an object encountered one that was missing it could create it. I realize that second line looks a little weird, but it enables you to look 2 different ways for stuff, because of both the trueness of "dbHash/utilDB" and if you iterate using a foreach($GLOBALS['dbHash'] as $name=>$value) you can get them all.

Sorry, probably not terribly lucid, still pretty whupped from this weekend.


/p
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
nutballs
Administrator
Lifer
*****
Offline Offline

Posts: 5627


Back in my day we had 9 planets


View Profile
« Reply #13 on: January 28, 2008, 04:52:53 PM »

no that makes sense. I think however, for my purposes, I am OK with strong-naming of the handles because of what this is actually being used for, which is a strict framework to build sites in. Basically i have a bunch of "consistent" classes that are always available (if used of course) and then I have 1 giant application class (though there may be subclasses) that contains every single site specific piece of code. The rest then is generic, and as such, can be upgraded globally, and if it works in 1 place, it will work in all places. The database stuff will never be used by the framework classes, except if the entire database connection is created and destroyed within the class. So as a result, something like a traffic tracking class will have its own personal database object, named something random to prevent collisions and will never be accessed from outside that class. The only time that a database object will need to be accessed from more than 1 class/scope, is the MAIN junk, ie, the page level code, and the application class which is always custom so it is not an issue. So... i think I have my framework. YEAY!
Logged

I could eat a bowl of Alphabet Soup and shit a better argument than that.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #14 on: January 28, 2008, 06:01:19 PM »

Right on, 'grats NBs! I know how that was for me when I finally felt like I had my basic framework installed and could go forward again - it's great.

Contrarian thought: I use 1 DB connection almost exclusively and recommend it, here's why:

I had a site that used many connections and I got slammed with traffic... and prompty started getting MySQL connection failures. The problem is that when you create a new connection, it's literally a new connection and you're using up MySQL connection handles. Since PHP is not threaded, it is fair to say that you're only doing one thing at any given time... so most of the time you can distill your work down to doing this or that with the DB at any given moment... and poof, you only need one DB connection. When you need a master/detail or more then you can use more, but making a personal protocol of trying to use only one DB connection at a time you'll minimize impact on your server.

Where I have FK referential integrity tables that are small and such, I'll check my cache to see if I already have it, if not, go read all rows for <that> query, then store it as a hashed array in the persisent memory cache rather than going to the DB as well - this REALLY improves my performance.

As I get deeper into my class libs I am more likely to let "everyone have their own connection" which is a perfectly fine MO, except when you may get the shit beaten out of you by the engines... which is exactly what took me down.

Just another ,
/p
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
Pages: [1] 2
  Print  
 
Jump to:  

Perkiset's Place Home   Best of The Cache   phpMyIDE: MySQL Stored Procedures, Functions & Triggers
Politics @ Perkiset's   Pinkhat's Perspective   
cache
mart
coder
programmers
ajax
php
javascript
Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks


Valid XHTML 1.0! Valid CSS!