Page 1 of 1

My attempt at making classes for OOP

Posted: Tue Mar 27, 2007 1:11 am
by wildwobby
Well this is my first attempt at making classes for an OOP project.

How is my style so far? what should I change before I do too much?

Code: Select all

<?php
//classes
class DB{
        var $db_HOST = "localhost";
        var $db_USER = "tim";
        var $db_PASS = "skyway";
        var $database = "fusionairways_sys";
        var $sqlerror = "SQL IS OUT!!";
        var $dbc ;
        
        //connection
        function __construct()
        {
            $this->connect_db();
        }
    
        function connect_db()
        {
            $this->dbc = mysql_connect($this->db_HOST,$this->db_USER,$this->db_PASS);
            $m = mysql_select_db($this->database,$this->dbc);
            return($dbc);
        }
          
        //query method
        function query_db($query,$print = false)
        {
            $sql = $query;
            if((!empty($sql)) && ($print == true))
            {
                echo $sql;
            }                
            $sts = mysql_query($sql,$this->dbc) or print mysql_error($this->sqlerror);
            return($sts);
        }
    
        //close db
        function close_db()
        {
            mysql_close($this->dbc);
        }
        
        //last insert id created
        function id_db()
        {
            return mysql_insert_id($this->dbc);
        }
        
        //get number affected rows from last query
        function affecte_db()
        {
            $tmp = mysql_affected_rows();
            return($tmp);
        }
      
        //get number of rows
        function num_rows($q)
        {
            $tmp = mysql_num_rows($q);
            return($tmp);
        }
        
        //get number of fields
        function num_fields($q)
        {
            $tmp = mysql_num_fields($q);
            return($tmp);
        }
        
        //get mysql info
        function db_info()
        {
            return mysql_info($this->dbc);
        }
        
        //fetch methods
        function fetch_db_row($fetched)
        {
            return mysql_fetch_row($fetched);
        }
        
        function fetch_db_array($fetched)
        {
            return mysql_fetch_array($fetched);
        }
        
        
        function fetch_db_assoc($fetched)
        {
            return mysql_fetch_assoc($fetched);
        }
        
        function fetch_db_object($fetched)
        {
            return mysql_fetch_object($fetched);
        }
        
        
        
        //makeup from query to table view
        // class.inc.css must be declaired in docuement
        function get_table($query,$names='',$url='',$extrafields='') //names array of fieldnames | $url array 1. fieldindex 2. url
        {
            if($_GET['line']=="1")
            {
                $lijn = "DESC";
            }
            else
            {
                $lijn = "ASC";
            }
            
            if(isset($_GET['orderby']))
            {
                $order = " ORDER BY `".$_GET['orderby']."` ".$lijn;
            }
            else
            {
                $order = "";
            }
            //" ORDER BY ".$_GET['orderby']." ".$lijn
            
            $query = str_replace(";","",$query.$order);
            
            
            $sql = mysql_query($query);
            if(!$sql)
            {
                echo "query could not be executed";
                die();
            }
            
            unset($code);
            $code .= "<table class=\"sqltable\" cellspacing=\"1\">\n";
            $code .= "    <tr>\n";
            
            
            //sortable by url
            $replace = array("?orderby=".$_GET["orderby"]."&","&orderby=".$_GET["orderby"]."&","line=".$_GET['line'],"?");
            $replace1 = array("?orderby=".$_GET["orderby"]."&","&orderby=".$_GET["orderby"]."&","line=".$_GET['line']);
            $with = array("","","","");
            $with1 = array("","","");
            if($uri = str_replace($replace,$with,"?".$_SERVER['QUERY_STRING']))    {
                if(strlen($uri)>0)    {
                    $replaced = "1";

                }
                else    {
                    $replaced = "2";
                }
            }
            
            
            $fw_uri = str_replace($replace1,$with1,$_SERVER['REQUEST_URI']);
            
            if($replaced == "1")
                $order = "&orderby=";
            else
                $order = "?orderby=";
            
            if($_GET['line']=='0')
                $lijn = "1";
            else
                $lijn = "0";
            
            
            
            //fieldnames
            if($extrafields!='')
            {
                $code .= str_repeat("<td>&nbsp;</td>",count($extrafields));
            }
            
            if($names === '')
            {
                for($i=0;$i<=(mysql_num_fields($sql)-1);$i++)
                {
                    $meta = mysql_fetch_field($sql,$i);
                    $code .= "        <td><a href=\"".$fw_uri.$order.str_replace(" ","+",$meta->name)."&line=".$lijn."\">".$meta->name."</a></td>\n";
                }
            }
            else
            {
                for($i=0;$i<=(mysql_num_fields($sql)-1);$i++)
                {

                    $meta = mysql_fetch_field($sql,$i);
                    $code .= "        <td><a href=\"".$fw_uri.$order.str_replace(" ","+",$meta->name)."&line=".$lijn."\">".$names[$i]."</a></td>\n";
                }
            }
            $code .= "    </tr><tr>\n";
            
            
            //datafields
            while($row_data = mysql_fetch_row($sql))
            {
                if($extrafields!='')
                {
                    for($q=0;$q<=(count($extrafields)-1);$q++)
                    {
                        if($extrafields[$q][2]==1)
                        {
                            $id = $row_data[$extrafields[$q][3]];
                        }
                        else
                        {
                            $id = "";
                        }
                        
                        if(substr_count($url[1],"?")===1) {
                            $ch = "&";
                        }
                        else {
                            $ch = "?";
                        }
                        
                        $code .= "<td><a href=\"".$extrafields[$q][1].$id."\">".$extrafields[$q][0]."</a></td>\n";
                    }
                }
                
                for($k=0;$k<=(mysql_num_fields($sql)-1);$k++)
                {
                    if(!empty($url[1]))
                    {
                        if($url[0]==$k)
                        {
                            if(substr_count($url[1],"?")===1) {
                                $ch = "&";
                            }
                            else {
                                $ch = "?";
                            }
                            $code .= "        <td><a href=\"".$url[1].$ch.$url[3]."=".$row_data[$url[2]]."\">".$row_data[$k]."</a></td>\n";
                        }
                        else
                        {
                            $code .= "        <td>".$row_data[$k]."</td>\n";
                        }
                    }
                    else
                    {
                        $code .= "        <td>".$row_data[$k]."</td>\n";
                    }
                }
                if($l<(mysql_num_rows($sql)-1))
                {
                    $code .= "    </tr><tr>\n";                    
                }
                $l++;
            }
            
            
            $code .= "</tr>\n";
            $code .= "</table>\n";
            
            return($code);
        }
        
        //makeup from query to table view (one record)
        // class.inc.css must be declaired in docuement
        function overview_table($query,$fieldnames='')
        {
            $sql = mysql_query(str_replace(";"," ",$query)."LIMIT 1;");
            
            if(!$sql)
            {
                echo "Cant preform query";
                die();
            }
            
            if(!empty($fieldnames))
            {
                if(((mysql_num_fields($sql)) != (count($fieldnames))))
                {
                    echo "array not equal to query";
                    die();    
                }
            }
            
            
            
            $code = "";
            $code .= "<table class=\"sqloverview\" cellspacing=\"1\">\n";
            
            if($fieldnames==='')
            {
                while($data_row = $data_row = mysql_fetch_row($sql))
                {
                    for($k=0;$k<=(mysql_num_fields($sql)-1);$k++)
                    {
                        unset($meta);
                        $meta = mysql_fetch_field($sql,$k);
                        $code .= "    <tr>\n        <td class=\"sqloverview_namefield\">".$meta->name."</td>\n        <td class=\"sqloverview_datafield\">".$data_row[$k]."</td>\n    </tr>\n";
                    }
                }
            }
            else
            {
                while($data_row = $data_row = mysql_fetch_row($sql))
                {
                    for($k=0;$k<=(count($fieldnames)-1);$k++)
                    {
                        $code .= "    <tr>\n        <td class=\"sqloverview_namefield\">".$fieldnames[$k]."</td><td class=\"sqloverview_datafield\">".$data_row[$k]."</td></tr>\n";
                    }
                }
            }            
            
            $code .= "</table>\n";
            return($code);
        }
}

class Disp{
	function __construct(){
		$db = new DB;
	}
	function getRoster(){
		$names[] = "Callsign";
		$names[] = "Name";
		$names[] = "Hours";
		$names[] = "Rank";
		if(isset($_GET['order'])){
			foreach($names as $value){
				if(strtolower($_GET['order']) == $value){
					$order = strtolower($value);
				}
			}
		} else {
			$order = "callsign";
		}
		if (isset($_GET['dir'])){
			if ($_GET['dir'] == "ASC"){
				$dir = "ASC";
			} else {
				$dir = "DESC";
			}
		}	
		$query = "SELECT callsign, name, hours FROM pilots ORDER BY $order $dir";
		$result = $db->query_db($query);
		$roster = $db->fetch_db_array($result);
		// Check ORDER BY if all same rank
		$query2 = "SELECT minhr, rankname FROM ranks ORDER BY minhr DESC";
		$result2 = $db->query_db($query2);
		$ranks = $db->fetch_db_array($result2);
		$i = $db->num_rows($result2);
		// start display block
		$block = array();
		$block .= "<table class=\"sqltable\" cellspacing=\"1\">\n";
		$block .= "<tr>\n";
		foreach($names as $value){
			$block .= "<td><b>".$value."</b></td>";
		}
		$block .= "</tr>";
		while($roster){
			while($ranks){
				if($ranks['minhr'] <= $roster['hours']){
					$rankname = $ranks['rankname'];
					$rankimage = "<img src=\"/images/ranks/\"".$rankname.".gif\" alt=\"$ranks['rankname']\"";
					break;
				}
			}
			$block .= "<tr><td>".$roster['callsign']."</td><td>".$roster['name']."</td><td>".$roster['hours']."</td><td>".$rankimgsrc."</td></tr>";
		}
		// End table
		$block .= "</table>";
		// display table
		return $block;
	}
	
	function getFleet(){
		// Code Here.
	}
	function getRoutes(){
		// Code Here.
	}
	function getProfile($pid){
		// Code Here.
	}
}

class Admindisp{
	function __construct(){
		$db = new DB;
	}
	function getPireps(){
		// Code Here.
	}
	function getPilots(){
		// Code Here.
	}
	function getInactive(){
		// Code Here.
	}
	function getUnverified(){
		// Code Here.
	}
	function getRoutes(){
		// Code Here.
	}
}

class Admin{
	function __construct(){
		$db = new DB;
	}
	function activate($pid){
		// Code Here.
	}
	function aPirep($pirepid){
		// Code Here.
	}
	function addFleet($name){
		// Code Here.]
	}
	function addRoute($origin, $dest, $nm, $aircraft){
		// Code Here.
	}
	function changeStatus($pid, $status){
		// Code Here.
	}
}
?>

Posted: Tue Mar 27, 2007 1:17 am
by feyd
It's good practice to always explicitly disclose the access modifiers and remember that "var" is deprecated now.

Under OOP terms, the result set from a query would often be a separate object. Sometimes even a record from result set would be an object too.

Posted: Tue Mar 27, 2007 1:21 am
by wildwobby
Ok so that means put like public or private infront of each function and classes?

And just not use var? just declare it without it?

Can you explain how I would modify my code to make another object for the query result?

Posted: Tue Mar 27, 2007 1:29 am
by feyd
Public, protected and private are the access modifiers. They should be stated for each method and property. Typically, you never want a property to be public and rarely do you want one to be protected.

Similarly for methods, you only want the methods that you would want a user to access to be listed as public. Methods a descendant will use are often public, but there are times when protected makes sense too.

Also, remember the final and const keywords, which may be of use in places.


As for making another object of the result, simply create an instance of a result class when performing a query and return it. Often, the class' constructor will take the result set identifier given to you by the API of choice.

Posted: Tue Mar 27, 2007 10:24 am
by bokehman
What's the point? All you have done is re-wrapped a load of built in functions.

Posted: Tue Mar 27, 2007 11:15 am
by wildwobby
Im still not exactly sure about the mysql query results into a new object. Can you show me a small example explaining it?

Posted: Tue Mar 27, 2007 5:31 pm
by feyd
bokehman wrote:What's the point? All you have done is re-wrapped a load of built in functions.
Encapsulation.

The current database class is an Adapter/Fascade. This allows changing the underlying API with little or no changes to the calling code. PDO does pretty much the same thing.

Posted: Tue Mar 27, 2007 7:48 pm
by Christopher
I see a few problems:

1. You have a basic connection class, but then you add two view methods overview_table() and overview_table(). They should be in a separate class.

2. You don't validate or filter any request vars. There are many SQL injection vulnerabilities in this code.

3. Usually it is better to pass the database connection information to the connection object from configuration data. Then you can use multiple databases and have live/development databases.

4. It seems like you Disp, Admindisp and Admin could inherit from a base class.

5. You might find the code more maintainable if you separate your template code from your program code.

Posted: Wed Mar 28, 2007 12:59 am
by jmut
arborint wrote:I see a few problems:

1. You have a basic connection class, but then you add two view methods overview_table() and overview_table(). They should be in a separate class.

2. You don't validate or filter any request vars. There are many SQL injection vulnerabilities in this code.

3. Usually it is better to pass the database connection information to the connection object from configuration data. Then you can use multiple databases and have live/development databases.

4. It seems like you Disp, Admindisp and Admin could inherit from a base class.

5. You might find the code more maintainable if you separate your template code from your program code.
....
6. Use more descriptive names
function affecte_db()
function id_db()
I should read the comments to understand what these methods do.
7. You don't have to add '_db' as it is clear methods concern DB class
e.g function close_db() could become just close()
In code it will be clear enough.

Code: Select all

$db = new DB();
$db->close();