Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I started reading some tutorials about OOP, because I want to learn the basics.

I have a question about it. I understand how you can have a object "Car" and give it a color like this $oCar->setColor("white");

But there are some things unclear to me. Let's say I have a database with all kinds of cars. What is the best way to create the object "car"? A SQL-query instead the class?

And the other question is: how can I output a list of all cars? Do I need to create a object called "Garage" with has only one method within that selects all the cars from the database? Or does this kind of method belong in the "Car" object?

share|improve this question

migrated from stackoverflow.com May 7 '13 at 6:48

This question came from our site for professional and enthusiast programmers.

    
Thanks, I will read it. –  user2353495 May 7 '13 at 6:39
5  
OOP has nothing to do with relational database systems. The structure of a relational database is fundamentally different than the structure of objects. This is evident through object-relational impedance mismatch. –  Gordon May 7 '13 at 6:44
add comment

7 Answers

Let's say I have a database with all kinds of cars.

Yes, let's say you have that database in the memory of your computer (in-memory-database) and let's say that the interface to it are variables in PHP.

What is the best way to create the object "car"? A SQL-query instead the class?

Obviously an SQL query makes no sense here. First of all in PHP there is only one (and a half) way to create the object car and I'm sure you know that already:

new car;

Second SQL does not understand PHP directly. So using an SQL query would not make any sense.

Object orientation requires you to separate things. For example the object itself should not care about how (and when) it is stored into the memory, on disk, into an SQL database or printed out on paper to be typed in later again. If the car object would need to take care about all this, it would less be a car object but more the super-store-exchange-object called "car".

So just take care that one class is responsible for what it is good with:

And create new objects with new. You can find many hints how to make your code more simple and still improving it when writing OOP code in the post Don't be STUPID: GRASP SOLID! (Dec 2011; by NikiC).

share|improve this answer
    
Which one? ;) - And you're welcome! –  hakre May 7 '13 at 19:13
    
Don't be STUPID :). By coincidence, I had read a different article about GRASP about an hour before (and I had never heard of it or the STUPID concept, though I constantly try to talk people away from doing STUPID stuff). –  Amy Blankenship May 7 '13 at 20:56
add comment

when you iterate your sql records in loop you can create objects then and put it for example to array

$array = array();
$sql = 'select yourFunction(params...)';
$db = new PDO('pgsql:dbname=yourDBname');

$cmd = $db->prepare($sql);
while ($row = $cmd->fetch(PDO::FETCH_ASSOC))
{
   $car = new Car();
   $car->setColor($row['color']);
   array_push($array, $car);
}

you can also fetch object as STD object( stdClass is php's generic empty clas). In PDO you can fetch object also to class using

 $stmt->setFetchMode(PDO::FETCH_CLASS, 'MyRow');

PDO::FETCH_CLASS: returns a new instance of the requested class, mapping the columns of the result set to named properties in the class. If fetch_style includes > PDO::FETCH_CLASSTYPE (e.g. PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE) then the name of the class is determined from a value of the first column.

http://php.net/manual/en/pdostatement.fetch.php

There is also one technology called ORM for mapping sql.

Good PHP ORM Library?

share|improve this answer
    
It's very basic example the other part of answer contains PDO, I do know manual. –  Robert Podwika May 7 '13 at 6:38
    
ok, thanks. But that $array part of the code, where do I put that? In another class or inside the Car-class in a method called "getAllCars"? –  user2353495 May 7 '13 at 6:38
    
before the loop, it's the variable to hold list of cars. –  Robert Podwika May 7 '13 at 6:44
    
Yes better go to the manual because PDO allows fetching into classes directly, either via PDOStatement::fetchObject or by using the PDO::FETCH_CLASS or PDO::FETCH_OBJ constants. Mind the difference between Class and Object here. –  hakre May 7 '13 at 7:01
add comment

But there are some things unclear to me. Let's say I have a database with all kinds of cars. What is the best way to create the object "car"? A SQL-query instead the class?

SQL queries and classes are two completely independent concepts and they are not interchangeable. You can't create objects out of SQL queries, but you can use an SQL query to retrieve the values for the properties of an object. There are two ways to go about this:

  1. The class knows about the database and retrieves the values itself when you create a new object.
  2. The class does not know about the database and relies on external code to provide the relevant values. These can come from a database or from elsewhere.

If you code it all yourself, the second way is easier, because you can split it up in more functions, which makes it easier to understand what each function does. There are also lots of frameworks available that provide an ORM (Object Relational Model) component which does most of the hard work for you. There it depends on the framework architecture if the ORM component is based on the first or the second way.

And the other question is: how can I output a list of all cars? Do I need to create a object called "Garage" with has only one method within that selects all the cars from the database? Or does this kind of method belong in the "Car" object?

Although some ORM implementations do provide such methods as part of the "Car" class, they do not really belong there. On the other hand, creating a "Garage" class just to provide a list of cars would also be overkill.

The pragmatic way is to have a method in the class that handles the database interaction for "Car" to retrieve a list of cars and if that happens to be "Car" itself, the so be it. IMO, it is more important to have all the code that deals with retrieving cars from the database close together than the purity of the solution. This method returns the cars as a list, array, hash or whatever collection type your language provides you.

share|improve this answer
add comment

the practical part of object oriented comes not so much from "Getting" things (like from a database). its when you are Changing things in a sequence over time. so for example - lets say you have an app where someone can call up a model of car - and then they can change the color, view, change the color again, view.

  • they request a car model, you get it from database as an object $carModel with a default color.
  • they request to see the color Red - you take that "instance" of $carModel, and run it through the changeBodyColor() method to change it to Red, then you pass the updated $carModel to your view and display it.

so obviously this could be a lot more complicated - different doors, tires, interior etc. but its all happening to the same object. AND that object is unique to the requester! here is where it gets amazing -- with the same class code -- you can have many simultaneous users -- each one will have a $carModel object -- AND that object is unique to them!!

thats why sometimes you will hear classes referred to as 'blueprints'. with one set of blueprints you can make 50 houses. but even though they came from the exact same 'blueprint' (class), each house (object) is unique.

share|improve this answer
add comment

You still need to understand what the Object is and what does it represent.

What is the best way to create the object "car"? A SQL-query instead the class?

  • Firstly, an SQL query doesn't help you to create objects, you can use its output to create objects.
  • OBJECTS RESIDE IN MEMORY. You must be aware that what represent the Objects are their STATES. Now what are the states ? It's nothing but the values that object is having.

Say for example

Car Object --> name='bmw', color='black' // values of the both the variable is state of car object.

I think you are clear enough about the objects now.

So think of your problem again.

You need to access list of cars. But the data that represents the cars is in the database.

ONE DB ROW = CAN CREATE ONE CAR OBJECT.

  • How we will create objects from the database output ? Simple. Fire query against the database, get the output and CONSTRUCT OBJECTS from that data.

Now about LIST of the CARS. As you are having all your objects in the memory you can create list which will include all the objects in it. Again this list is also an object and its state is its values.

Hope this clears your understanding of Objects.

share|improve this answer
add comment

there are many ways to do this, one i did was:

  1. create a table
  2. create a class with the same name
  3. create in both the same attributes/column names
  4. create a mapper or a parent class for your car class and create functions to load in all objects. (with static class)
  5. create a standard getters and setters or use magic __call method

so you can do Car::Find() for example, to return al cars.

my code:

//Code for parent class:
abstract class databaseObject {
public static function getClassName(){
    return get_called_class();
}

public static function find(){
    mysql_query("SELECT * FROM ".static::getClassName().";");
    $cars = array();
    while($row = mysql_fetch_assoc())
    {
        $car = new Car();
        $car->setAttributes($row);
        $cars[] = $car;
    }
    return $cars;

}

public function setAttributes(array $values) {
    foreach ($values as $attribute => $value) {
        if ($this->{$attribute . 'Exists'}()) {
            $this->{'set' . ucfirst($attribute)}($value);
        }
    }
    return $this;
}

    //this function gets called when a function of an object gets called which does not exist
    public function __call($name, array $args) {
    // get attribute
    if (0 === strpos($name, 'get')) {
        $property = lcfirst(substr($name, 3));
        if (property_exists($this, $property)) {
            return $this->$property;
        } else {
            return new Exception("Attribuate $property does not exist");
        }
    } elseif (0 === strpos($name, 'set')) {
        $property = lcfirst(substr($name, 3));
        if (property_exists($this, $property)) {
            $this->$property = $args[0];
            return $this;
        } else {
            throw new Exception("Cannot set attribute '{$property}', it does not exist");
        }
    }
    return new Exception("Method $name does not exist");
}
 }


class Car extends databaseObject {
    protected $color;
}

offcourse you will probably want an already created database abstraction layer something like ORM/Doctrine

share|improve this answer
2  
Please, don't use mysql_* functions in new code. They are no longer maintained and are officially deprecated. See the red box? Learn about prepared statements instead, and use PDO or MySQLi - this article will help you decide which. If you choose PDO, here is a good tutorial. –  teresko May 7 '13 at 7:42
    
Also, static methods are no part of OOP paradigm –  teresko May 7 '13 at 7:44
add comment

I would include methods in the class to retrieve and write the information to and from the database.

Class Car {
   public $color;
   public $id;

   public function load(&$db, $car_id) {
      //get info from database
      $result = $db->query("SELECT color FROM car_table WHERE car_id=".$id);
      $row = $result->fetch_row();

      $this->id = $car_id;
      $this->color = $row['color'];
   }

   public function save(&$db, $car_id) {
      $db->query("INSERT INTO car_table (color) VALUES (".$this->color.") WHERE car_id=".$this->id);
   }
}

//create db connection
$mydb = new mysqli("server","user","pass","db");

//car id to search for
$car_id= 1234;

//create new Car object with car id
$the_car = new car();
$the_car->load($mydb, $car_id);

//save a new car
$other_car = new car();
$other_car->color="Green";
$other_car->save($mydb);

You'll have to excuse any mistakes (especially in the mysql bits). My php is pretty rusty these days... Also, I'm sure my code isn't completely best practice. My main point is that you can create a method inside of a class to load some information from a datasource.

share|improve this answer
    
static methods are not OOP. And, stop concatenating SQL queries. –  teresko May 7 '13 at 6:51
    
You could do the same thing without the static method. Just instantiate the object and call the load function which will then modify itself ($this). Good to know static methods aren't OOP. –  RealityGone May 7 '13 at 6:54
    
.. also, since PHP 5.0 was release, passing object by reference is unnecessary and even highly harmful. –  teresko May 7 '13 at 7:05
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.