Page 1 of 3

First Class problems

Posted: Thu Apr 03, 2008 9:06 pm
by psurrena
Below is my first class. It creates rows of thumbnails and starts a new row at a defined number. Everything works fine except when I'm trying to use list() to pull my info from the database.

The user specifies the fields to pull from the database, they are listed in the query with commas. Then I turn them into an array and remove the commas and in a foreach loop put a $ in front of them. All that works.

The problem is, the next step is to put a value to the variable using list(). I would love to implode the array there [list(implode(',',$array))=mysql_fetch_array...] but that doesn't work.

Can anyone help me get the variables in list(), in the below case the solution is: list($id,$image,$title)

Thank you in advance!

Code: Select all

 
class Pgrid{
    var $grid_fields;
    var $grid_table;
    var $grid_order;
    var $grid_thumb_url;
    var $grid_row="5";
    
    function pgrid_grid(){
        $query="SELECT $this->grid_fields FROM $this->grid_table ORDER BY $this->grid_order ASC";
        $result=mysql_query($query) or die (mysql_error());
        
        //Take out comma
        $grid_field_array=explode(',',$this->grid_fields);
        
        //Add $ infront of field names
        foreach($grid_field_array as &$grid_field_value){
            $grid_field_value="$".$grid_field_value;
        }
 
        //Test, returns $id, $image, $title  <-Perfect
    /*  foreach($grid_field_array as $value){
            echo $value;
        }
    */  
 
               //Problem area
        while(list($this->newvars)=mysql_fetch_array($result)){
            echo $this->grid_thumb_url;
    
            //Create rows
            ++$i;
            if($i >= $this->grid_row){
                echo "<br />";
            
                // Reset counter 
                $i=0;
            }
        }
    }
}
 
And here it is called on a page

Code: Select all

 
$grid=& new Pgrid();
$grid->grid_fields="id,title,image";
$grid->grid_table="work";
$grid->grid_order="id";
$grid->grid_url='<a href="work-$id.html"><img src="images/portfolio/$image_t.jpg" alt="$title" width="80" height="80" /></a>';
echo $grid->pgrid_grid();
 

Re: First Class problems

Posted: Fri Apr 04, 2008 12:56 am
by Christopher
I think you should probably just use mysql_fetch_assoc() and access the array elements. It would certainly simplify things. But that is the least of the problems with this code.

Re: First Class problems

Posted: Fri Apr 04, 2008 1:34 am
by Rovas
You should use the mysqli extension or the PDO so you can implement their functions in to your class (all examples posted on the Internet are done this way). You need to do something like this

Code: Select all

 
// we need the mysqli functions so i am getting them by making this class a derivate of it
class Database extends mysqli{
  // the object constructor directly makes a connection to the server using the given arguments
  function __construct($userName, $password, $database){
    mysqli->connect("localhost", $userName, $password, $database); 
  }
 //this function makes the desired query
  function queryDb($q){
     //is needed the query function from mysqli so I call it this way 
     $result=parent::query($q);
     $array=array();
     $array=$result->fetch_array();
     return $array
  } 
 

This snippet isn' t a working one you have to continue it.

Re: First Class problems

Posted: Fri Apr 04, 2008 8:18 am
by psurrena
Time for a book ;)

What's are some of the better books that really explain oop? I like the PeachPit (Larry Ullman) but they barely go into oop.

Anyone thoughts on Object-Oriented PHP: Concepts, Techniques, and Code: http://www.amazon.com/gp/product/159327 ... JYG9VSQ8D?

Re: First Class problems

Posted: Fri Apr 04, 2008 2:31 pm
by Christopher
Recommending books is difficult because different people have different learning styles.

The basic of OOP is really not that difficult to get. Your first attempt, pretty typically, used the class construct as a namespace and you continued to program procedurally. That is actually the first step. We could walk through creating classes to solve your grid problem here if you like.

Re: First Class problems

Posted: Fri Apr 04, 2008 3:18 pm
by psurrena
That would be great, I just don't want to use up everyone's time.

Re: First Class problems

Posted: Fri Apr 04, 2008 4:17 pm
by Christopher
There is always a little time. Hopefully you will do most of the work and thinking! ;)

When I look at the problem you present, I see three things:

1. specify the fields
2. pull from the database
3. create rows of thumbnails with a defined number of thumbnails per row.

You can do it all in one, but it is best to break everything in to pieces.

Re: First Class problems

Posted: Fri Apr 04, 2008 4:27 pm
by psurrena
Exactly. The database part really confuses me but seems like it would be the most useful. Is it better to specify the fields or specify the query? All in on meaning class or function?

Re: First Class problems

Posted: Fri Apr 04, 2008 5:08 pm
by Christopher
When I am confused (which is often ;)), I try to find a part of the problem that I actually am not confused about. My guess is that for you that is probably my #3, which is displaying the thumbnails.

Re: First Class problems

Posted: Fri Apr 04, 2008 5:46 pm
by psurrena
#3, yes. Procedurally it works, which is great, it means I know what I want to do and I know in one form it works. Then I decided that since it worked and incorporated a few good elements, it would be a good candidate for learning oop.

Code: Select all

 
$query="SELECT id, title, image FROM work ORDER BY RAND()";
$result=mysql_query($query) or die (mysql_error());
 
if(mysql_num_rows($result) < 1){
    error("content");
}else{
    while(list($id,$title,$image)=mysql_fetch_array($result)){
        echo "<a href=\"work.php?id={$id}\">";
        echo "<img src=\"images/{$image}_t.jpg\" width=\"80\" height=\"80\" alt=\"{$title}\"/></a>\n";
    
        //Create rows of 5
        ++$i;
        if($i >= 5){
            echo "<br />";
            
            // Reset counter 
            $i=0;
        }
    }
}   
 

Re: First Class problems

Posted: Fri Apr 04, 2008 7:13 pm
by Christopher
The thing about OO is that it helps clean up code, but a lot of that clean up should happen in any code. Take your code above. You are combining the Datasource code with the Display code. Separating those is considered a fundamental practice, mainly because you really can't know if you have code reuse until you do that. So:

Code: Select all

// find all matching rows
$query="SELECT id, title, image FROM work ORDER BY RAND()";
$result=mysql_query($query) or die (mysql_error());
 
$thumbnails = array();
if(mysql_num_rows($result) < 1){
    error("content");
}else{
    while($row=mysql_fetch_array($result)){
        $thumbnails[] = $row;
    }
}   
 
// display data in N column layout
if ($thumbnails) {
    foreach (thumbnails as $data){
        list($id,$title,$image) = $data;
        echo "<a href=\"work.php?id={$id}\">";
        echo "<img src=\"images/{$image}_t.jpg\" width=\"80\" height=\"80\" alt=\"{$title}\"/></a>\n";
    
        //Create rows of 5
        ++$i;
        if($i >= 5){
            echo "<br />";
            
            // Reset counter 
            $i=0;
        }
    }
}
That might not look much different (and some would complain that it is slower because I am copying the data to an array), but we now have two pretty generic pieces of code. If you squint you will see that the SQL is the about the only thing that makes the query code unique. Likewise the HTML and number of columns are the only things that make the display code unique. They are "find all matching rows" and a "display data in N column layout". Those are pretty common things that web application needs.

Re: First Class problems

Posted: Fri Apr 04, 2008 11:37 pm
by psurrena
Makes perfect sense, so we are setting up two functions for the class?

Re: First Class problems

Posted: Sat Apr 05, 2008 2:18 am
by Christopher
We certainly could, but the question is -- do "find all matching rows" and "display data in N column layout" belong together? If they are together then this code will always read records from mysql and show thumbnails in columns. If they are separate then the "thumbnail displayer" could get its data from a XML, SQLite, etc. because any of them can provide an array. Likewise the "record finder" could be used to provide data for a text list, a scrolling list, etc. So that's one thing to think about.

Another is that objects should be pretty much initialized when they are created. Maybe you need to be able to turn a few knobs on them later, but they should be generally useful after they are created. So what do the two "functions" above need as far as initialization?

Re: First Class problems

Posted: Sat Apr 05, 2008 6:54 am
by psurrena
For finding the rows, we would need the information to choose a db and login. In the end product, the query would be needed. In the thumbnail viewer, it would be the URL/Image.

Re: First Class problems

Posted: Sat Apr 05, 2008 11:34 am
by Christopher
So if you made a class out of just your database code it might look like this:

Code: Select all

class Work {
 
    function findAll() {
        $query="SELECT id, title, image FROM work ORDER BY RAND()";
        $result=mysql_query($query) or die (mysql_error());
 
        $thumbnails = array();
        if(mysql_num_rows($result) < 1){
            error("content");
        }else{
            while($row=mysql_fetch_array($result)){
                $thumbnails[] = $row;
        }
        return $thumbnails;
    }
}
That does what you want to do, but there are some questions. What is the function error() ? We have a dependency on it, but it is outside this class and not in the standard PHP library. And is this the only way you will ever fetch rows? Can the column names or sort order change? If the table name can change then we probably shouldn't call if "Work". So there are some choices for you to make.