General Programming Help
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
 
User Name:
Password:
Remember me
 
Go Back   Dev Articles Community ForumsProgrammingGeneral Programming Help

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Display Modes
 
Unread Dev Articles Community Forums Sponsor:
  #1  
Old September 17th, 2003, 12:06 PM
particleman particleman is offline
Junior Member
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2003
Posts: 6 particleman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
need help with OOP design for my site

Hello:

I am trying to develop my own personal website but I am trying to do it by following OO concepts. Now although technically it shouldnt matter what I am using since the OO design should work with anything this is what I got:
- Apache webserver, with myslq database and php on it.

The part that I am caught up in right now is in the the design of the database object. I am not sure that I have designed it properly and that I am doing alot of things incorrectly. I have split the database object into 2 classes, the first is the actual database and its properties looks like this:

1. Name: Database()
Description: The constructor. It Initializes the $server, $username, $password and $database class members

2. Name: openConnection()
Description: Opens the connection to the database server and selects the database (uses the property selectDatabase)

3. Name: selectDatabase()
Description: chooses a database to work with

4. Name: queryDatabase()
Description: queries the database and initializes the $queryResults class member to the results of the query

5. Name: returnResults()
Description: Returns the $queryResults member

6. Name: insertRecord(), deleteRecord(), & modifyRecord
Description: These properties pretty much run an SQL statement and return a message saying how many rows were affected (if the query was successful).

7. Name: displayResults()
Description: Displays the contents of the $queryResults class member by creating a new ResultsPAge (read below) object and calling its display() property.

OK that is pretty much it for the properties, the class members (or class variables) $servername, $username, $password, $dbName and $queryResults. Pretty much all of these (except the $queryResults) are initialized set by the constructor.

The other object or class that I have that goes hand in hand with the database object is the ResultsPage object and this is what I am having problems with. In essence I created the ResultsPage object in order to have a flexible way of displaying whatever results get returned from an SQL query. The main purpose of the ResultsPage is that if the number of results that are returned is very high it displays the webpage with the ability to page through the results. When I thought about it, the scope of what this does is really what a WebPage object would except that it is pretty specialized to displaying records only so it didnt quite seem to fit in the scope of a Database object (which is only supposed to connect to a database, and query it) so that is why I made it its own object. The properties in the ResultsPage object look like this:

1. Name: ResultsPage($recordSet,$pageSize)
Description: The constructor. Initializes the $recordSet, $pageSize, $numberOfPages, $numberOfRecords, and $currentPage class members

2. Name: setCurrentPage($page)
Description: Sets the class member $currentPage

3. Name: setStyles($headerStyle,$recordStyle,$recordAlterna teStyle,$buttonStyle,$frmElementStyle)
Description: This property sets all of the styles that will be sed to display the page.

4. Name: display()
Description: this is the function that creates ALL the HTML to lop through the recordset to create the page. If it happens that record paging functionality needs to be added this function also displays a record navigating form at the bottom of the page so that a user can jump from page to page.

The class members or variables for the ResultsPage class are:
$headerStyle, $recordStyle, $recordAlternateStyle, $buttonStyle, $frmElementStyle, $recordSet, $currentPage

So by now you are all probably shaking your head and saying "he should have never picked up an OOP book." As you can tell I need help.

From what I can see my main problem is the display() function of the ResultsPage object, if you were to see the implementation code for it you would see that it is about 50 lines long and it has so much embeded HTML and echo statements I dont know if I should be separating all of this or what.

The main reason why I have done it like this is because there is a specific way in which I want the results pages to look, if there are more than so many records than there is a specific way that I want it to be able to page. and dont get me all wrong, I actually managed to get it to work. But when I am creating the database object and the pageresults object on the page that the records will be displayed from it seems like I have to end up doing more work than I should. I am going to post the implementation code for the resultspage object below if you want me to post the code for the Database object I can do so as well.


ResultsPage:

PHP Code:
include_once("Form.php");
    
    class 
ResultsPage
    
{
        
// Attributes of the page
        
var $recordSet;        // array containing all of the data returned from the search
        
var $currentPage;    // page that is currently being diplayed
        
var $pageSize;        // how many records are displayed at a time in a page
        
var $numberofResults;
        var 
$numberOfPages;
        
        
//Styles
        
var $headerStyle;
        var 
$recordStyle;
        var 
$recordAlternateStyle;
        var 
$buttonStyle;
        var 
$frmElementStyle;
        
        function 
ResultsPage($recordSet,$pageSize)
        {
            if ((!empty(
$recordSet)) && (!empty($pageSize)))
            {
                
$this->recordSet=$recordSet;
                
$this->currentPage=1;    // initialize the current page to 1
                
$this->numberofResults=mysql_num_rows($this->recordSet);
                
$this->pageSize=(($this->numberofResults<=$pageSize)?$this->numberofResults:$pageSize);
                
// figure out how many pages there are
                
$this->numberOfPages=($this->numberofResults%$this->pageSize)?(ceil($this->numberofResults/$this->pageSize)):($this->numberofResults/$this->pageSize);
            }
            else
                die(
"The database results page does not have enough information to proceed."); 
        }
        
        function 
setStyles($headerStyle,$recordStyle,$recordAlterna  teStyle,$buttonStyle,$frmElementStyle)
        {
            
$this->headerStyle=$headerStyle;
            
$this->recordStyle=$recordStyle;
            
$this->recordAlternateStyle=$recordAlternateStyle;
            
$this->buttonStyle=$buttonStyle;
            
$this->frmElementStyle=$frmElementStyle;
        }
        
        function 
setCurrentPage($page,$changePage=false)
        {
            if (
$changePage$this->currentPage=$page;
            else 
$this->currentPage+=$page;
        }
        
        function 
display($headings)
        {
            
$start=(($this->currentPage-1)*($this->pageSize));
            
$end=$start+$this->pageSize;
            
// information as to what results are being viewed
            
echo "<br><br><center><font face=\"Arial, Helvetica, sans-serif\"><table width=\"60%\" border=\"0\">";
            echo 
"<tr class=\"gHeader\"><td align=\"center\"><font size=\"2\">Your search returned ";
            echo 
$this->numberofResults." result(s).</font></td>";
            if (
$this->numberOfPages>1)
                echo 
"<td align=\"center\"><font size=\"2\">Now viewing results ".($start+1)."-".$end."</font></td>";
            echo 
"</tr></table></font></center>";
            
            echo 
"<center><font face=\"Arial, Helvetica, sans-serif\"><table width=\"60%\" border=\"0\">";
            for (
$i=$start$i<$end$i++)
            {
                
mysql_data_seek($this->recordSet$i);
                
$row mysql_fetch_array($this->recordSet);
                for (
$j=0$j<count($headings);$j++)
                {
                    echo 
"<tr class=";
                    echo (
$j==0)?"\"gContentSectionGray\"":"\"gContentSection\"";
                    echo 
">";
                    echo 
"<td width=\"24%\"><b>".$headings[$j]."</b><br></td>";
                    echo 
"<td width=\"76%\">".$row[$headings[$j]]."<br></td></tr>";
                }
            }
            echo 
"<tr class=\"gContentSection\"><td colspan=\"2\">&nbsp;</td></tr>";
            echo 
"</table></font></center>";
            if (
$this->numberOfPages>1)
            {
                
// create the navigation form
                
$navForm=new Form("navFrm",$_SERVER["PHP_SELF"]);
                
/* InputField: type, name, size, default value, validation type, error message, style, events    */
                
$navForm->addElement(new InputField("hidden","currPage","","$this->currentPage"));// Keep track of the current page
                
for ($int=1$int<=$this->numberOfPages$int++)    // list for the select field
                    
$select[$int]=$int;
                    
                
$navForm->addElement(new SelectField("jumpToPage",$select,$this->currentPage,"","","","LANGUAGE=javascript onchange=\"document.navFrm.submit()\""));
                
$layout="currPage<center><font face=\"Arial, Helvetica, sans-serif\"><table width=\"60%\" border=\"0\"><tr class=\"gHeader\"><td width=\"18%\" align=\"center\">";
                if (
$this->currentPage>1)
                {
                    
$layout.="prevButton";
                    
$navForm->addElement(new InputField("submit","prevButton","","<<"));
                }
                
$layout.="</td><td width=\"66%\" align=\"center\">Page jumpToPage of $this->numberOfPages</td>";
                
$layout.="<td width=\"16%\" align=\"center\">";
                if (
$this->currentPage!=$this->numberOfPages)
                {
                    
$layout.="nextButton";
                    
$navForm->addElement(new InputField("submit","nextButton","",">>"));
                }
                
$layout.="</td></tr></table></font></center>";
                
$navForm->setLayout($layout);
                
$navForm->display();
            }
        }
    } 



Last edited by particleman : September 17th, 2003 at 12:23 PM.

Reply With Quote
  #2  
Old September 17th, 2003, 12:10 PM
particleman particleman is offline
Junior Member
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2003
Posts: 6 particleman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
and I also decided to post the code for the database object:

PHP Code:
include_once("ResultsPage.php");
    
    class 
Database
    
{
        
// Connection variables
        
var $server;
        var 
$username;
        var 
$password;
        var 
$dbName;
        
        var 
$queryResults;    // array containing the results of a query
        
var $resultsPage;    // object containing necessary information to create the results page
        
        
function Database($server,$user,$password,$db)
        {
            if ((!empty(
$server)) && (!empty($user)) && (!empty($password)) && (!empty($db)))
            {
                
$this->server=$server;
                
$this->username=$user;
                
$this->password=$password;
                
$this->dbName=$db;
            }
            else
                die(
"The database object does not have enough information to proceed."); 
        }
        
        function 
selectDatabase($db="")
        {
            if (empty(
$db)) $db=$this->dbName;
            
mysql_select_db($db);
        }
        
        function 
openConnection()
        {
            @ 
$db mysql_pconnect($this->server,$this->username,$this->password);
            if (!
$db)    // connection fails
            
{
                echo 
"Error: could not connect to the database.";
                exit;
            }
            
$this->selectDatabase();    // select the specified database
        
}
        
        function 
queryDatabase($sql)
        {
            
$this->queryResults=mysql_query($sql);
        }
        
        function 
returnResults()
        {
            return 
$this->queryResults;
        }
        
        function 
insertRecord($sqlInsert)
        {
            
$result=mysql_query($sqlInsert);
            if (
$result)    // insert was successfull
                
echo mysql_affected_rows()." record(s) inserted successfully.";
        }
        
        function 
deleteRecord($sqlDelete)
        {
            
$result=mysql_query($sqlDelete);
            if (
$result)    // delete was successfull
                
echo mysql_affected_rows()." record(s) deleted successfully.";
        }
        
        function 
modifyRecord($sqlModify)
        {
            
$result=mysql_query($sqlModify);
            if (
$result)    // modify was successfull
                
echo mysql_affected_rows()." record(s) updated successfully.";
        }
        
        function 
createResultsPage($pageSize,$headerStyle="",$recordStyle="",$recordAlternateStyle="",$buttonStyle="",$frmElementStyle="")
        {
            
$this->resultsPage= new ResultsPage($this->queryResults,$pageSize);    // create the object
            
$this->resultsPage->setStyles($headerStyle,$recordStyle,$recordAlterna  teStyle,$buttonStyle,$frmElementStyle);
        }
        
        function 
changeResultsPage($page,$changePage=false)
        {
            
$this->resultsPage->setCurrentPage($page,$changePage);
        }
        
        function 
displayResults($headings)
        {
            
$this->resultsPage->display($headings);
        }
    } 


and a page where I would use the database object would look like:

PHP Code:
include_once("Database.php");
        
    
$mydb = new Database("localhost","username","password","books");
    
$mydb->openConnection();
    
    
$query "Select title,author,isbn,price from books";
    
$mydb->queryDatabase($query);
    
$mydb->createResultsPage(2);
    if (!empty(
$_POST["currPage"])) $mydb->changeResultsPage($_POST["currPage"],true);
    
    
$headings=array("title","author","isbn","price");
    
    if (!empty(
$_POST["prevButton"]))
    {
        
$mydb->changeResultsPage(-1);
    }
    else if (!empty(
$_POST["nextButton"]))
    {
        
$mydb->changeResultsPage(1);
    }
    else if (!empty(
$_POST["jumpToPage"]))
    {
        
$mydb->changeResultsPage(1,true);
    }
    
    
$mydb->displayResults($headings); 

Last edited by particleman : September 17th, 2003 at 12:25 PM.

Reply With Quote
  #3  
Old September 17th, 2003, 12:29 PM
particleman particleman is offline
Junior Member
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2003
Posts: 6 particleman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Just a couple more things to mention here are that I know that is alot of code and I dont expect anyone to go through it and tell me what lines to change. What I want is an idea of how I could change the design to resemble more of an OO design and make it more efficient, the code is pretty much documentation to show you what I have done. There are a few more properties in the code that I didnt mention only because they werent that relevant. Either way any help at all would be appreciated.

There is another object in those pages if you have noticed it is a Form object which is used as the navigation form for the records.

Thanx in advance for any help you can give me.

Reply With Quote
  #4  
Old September 17th, 2003, 03:38 PM
dhouston's Avatar
dhouston dhouston is offline
Contributing User
Dev Articles Beginner (1000 - 1499 posts)
 
Join Date: May 2003
Location: Tennessee
Posts: 1,355 dhouston User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 7
Send a message via ICQ to dhouston
You might consider consolidating some of your query functions into one, as they do the same thing (execute and test the success of a query passed as a parameter to the function). You're probably never going to extend these functions, so why not consolidate?

In my own db class, I've got a function called query() that lets me do an ad hoc insert, update, delete, etc. basically, I expect to get nothing back from this function, and if I get anything back but true, I know I've gotten an error. I've also got a fetch() function that returns an array of row arrays. This allows me to do nifty things like

PHP Code:
foreach($db->fetch("SELECT * FROM table") as $row){
    
//do stuff to the row array



At a glance, I didn't see any really major issues with your code, though. You'd probably do better to call one a database object and the other a page object, and as a matter of lingo, I don't think you can really talk about splitting an object into two classes, as a class is simply the definition of a single object.

Reply With Quote
  #5  
Old September 17th, 2003, 04:05 PM
particleman particleman is offline
Junior Member
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Sep 2003
Posts: 6 particleman User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
dhouston: Thanx for the reply I' really new at using OO concepts in my programming.

Just a couple more questions though. I noticed that you mentioned that you had a database class. Well how do you deal with the display of the password. For instance in the bit of my code where it says
PHP Code:
 $mydb = new Database("localhost","username","password","books"); 


on the page where I would use the database object, is there a way of not SHOWING the password? I mean can I make a connection to the database wihout having the actual text password in the script, I guess something like using a DSN on an IIS server. I havent been able to find something like that whilst using a LAMP system.

Reply With Quote
  #6  
Old September 19th, 2003, 04:47 AM
kode_monkey kode_monkey is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Jul 2003
Posts: 367 kode_monkey User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 7 m 21 sec
Reputation Power: 6
Personally I put information such as passwords in a config file that is then included so you can reference the password as $password, $config ['password'] or something similar.

If all the project files are available to someone this obviously won't help but does mean you can release all the source to anyone (minus the config file) and they won't have access to the database.

It also makes changing the details much easier since they are all kept in one place.

Hope this helps,

-KM-

Reply With Quote
  #7  
Old September 19th, 2003, 06:48 AM