views:

69

answers:

6

I have very basic class:

class Customer {

  protected $id;
  protected $customer;

  public function __construct($customer_id) {
    $this->id = $customer_id;
    return $this->set_customer();
  }

  protected function set_customer() {
    $query = mysql_query("SELECT * FROM customer WHERE id = '$this->id'");
    $this->customer = mysql_fetch_row($query);
    return $this->customer;
  }
}

$customer = new Customer($order->customer->id);
print_r($customer);

This is not doing what I want it to but I understand why... $customer returns a reference to the Customer Object...

What I want is the MySQL row array from the mysql_fetch_row() - How do I return the array?

What am I missing?

+3  A: 

Of course. If you construct a new object, you'll get back a reference to the new object. How else would you hold the reference to it?

$customer = new Customer();
// if $customer was a data array, where did the object reference go?

The new operator will always return a reference to the newly created object. You can not return anything else from a constructor.

deceze
Bingo, there we go.
Ólafur Waage
Guys... I know and understand this!!! That is why i wrote:"what I want is the MySQL row array from the mysql_fetch_row()"I'll update the post to put a question mark at the end of this sentence... maybe then I'll get the feedback I'm seeking.
php-b-grader
@php-b-grader You'll have to call the `set_customer()` method in a second step manually, there's no other way. Or you save the result in an instance variable and read it after you have constructed the object. Either way, you'll need to restructure your constructor.
deceze
@php-b-grader If you understand this, it appears you need to decide first and foremost how your class should work and what you want it to do. Maybe read another OOP tutorial or look at more existing classes of other projects to get some inspiration...?
deceze
A: 

Put the result in a public variable within the class and then do a print_r on $customer and don't return in the constructor.

Currently it's a protected variable, so you wont see it with print_r

Does something like this work?

class Customer {

  protected $id;
  public $customer;

  public function __construct($customer_id) {
    $this->id = $customer_id;
    $this->set_customer();
  }

  protected function set_customer() {
    $query = mysql_query("SELECT * FROM customer WHERE id = '$this->id'");
    $this->customer = mysql_fetch_row($query);
  }
}

$customer = new Customer($order->customer->id);
print_r($customer);
Ólafur Waage
I am having an issue with the way I am referencing it... print_r($customer) prints the Customer Object, not the $customer array...I can reference $customer->customer...But If I refence $customer->customer->name or $customer->customer['name'] It prints: Array->name or Array['name']
php-b-grader
That is not a very good OOP way of doing things.
Ólafur Waage
+1  A: 

You could leverage ArrayObject (provided you're using PHP 5.3) to get what you want:

class Customer extends ArrayObject {

    protected $id;
    protected $customer;

    public function __construct($customer_id) {
        $this->id = $customer_id;
        $this->set_customer();
        parent::__construct($this->customer);
    }

    protected function set_customer() {
       $query = mysql_query("SELECT * FROM customer WHERE id = '$this->id'");
       $this->customer = mysql_fetch_row($query);
    }
}

Then you can use $customer as an array:

$customer = new Customer($customer_id);
echo $customer['name'];
rojoca
the code above makes print_r($customer) print nothing and echo $customer->name also prints nothing
php-b-grader
My mistake, I thought set_customer was returning the row but it wasn't. I have fixed the example.
rojoca
+2  A: 

Sounds like you want a static method instead (judging by the comments) - see the example at the end.

I think you're missing the 'mindset' of the object, however.

class Customer should be an Object - an actual customer. You're halfway there, but you're taking an array and slamming it into a blank object.

Use that set_customer to populate your object - like this (this was typed in-browser btw, just getting the idea across):

class Customer {

  public $id;
  public $name;
  public $address;

  public function __construct($customer_id) {
    $this->customer = $this->set_customer($id);
  }

  private function set_customer($id ) {
    $query = mysql_query("SELECT * FROM customer WHERE id = '$id'");
    $customer = mysql_fetch_assoc($query);
    foreach($customer as $field => $value) {
       $this->$field = $value;
    }
  }
}

$customer = new Customer();
print_r($customer); // now has $customer->id, $customer->name, $customer->address

to fit your code and comments:

class Customer {

  protected $id;
  public $customer;

  public function __construct($customer_id) {
    $this->id = $customer_id;
    $this->customer = self::get_customer($id);
  }

  public static function get_customer($id ) {
    $query = mysql_query("SELECT * FROM customer WHERE id = '$id'");
    return mysql_fetch_row($query);
  }
}

$customer = Customer::get_customer($id);
Dan Heberden
I think I'm getting there mentally...I am not missing the 'mindset' of an object - I'm missing the 'mindset' of the transformation of the object into actual customer information.You don't call the constructor in the method above though??? Does that matter?Also, I originally wanted to set each field but there is 20-30 fields and thought it would become unmanagable... That's why I started looking at just the single array object for one single reference...
php-b-grader
The static method option, no constructor but it's basically just a home for the function - that's not a good option at all for leveraging OOP in this case.. that's more for utility functions. For site-wide classes, like a db or template class, I would utilize singletons. You're right about setting fields - that's where iterating through them automatically is a blessing.
Dan Heberden
+1  A: 

How about this:

class Customer {

  protected $id;

  public function __construct($customer_id) {
    $this->id = $customer_id;
  }

  public function getAsArray() {
    $query = mysql_query("SELECT * FROM customer WHERE id = '$this->id'");
    return mysql_fetch_assoc($query);
  }
}

$customer = new Customer( $id );
$customer_array = $customer->getAsArray();
print_r( $customer_array );

That said, a few things to mention:

  • The class is missing alot (error/exception handling for one).
  • You may want to look into one of the many ORM's for php.
  • You may want replace the mysql_* use with PDO and use parameterized queries.
Rob Apodaca
I +1ed you, becuase of the `fetch_assoc`, but damn couldn't you have done this OOP shit different. `$customer->getCustomer();` What the hell is that ;)
Gutzofter
@Gutzofter I agree that $customer->getCustomer() does not make much sense. I was shooting for the most direct answer to the original question without assuming what he should be doing instead.
Rob Apodaca
+1  A: 

Here is what I think is a more Object Oriented Style:

class CustomerFind {

    public static function byIdNumber($customer_id) {
      $query = mysql_query("SELECT * FROM customer WHERE id = '$customer_id'");
      return mysql_fetch_assoc($query);
    }

}

$customer = CustomerFind::byIdNumber( 1 );
print_r( $customer );
Gutzofter
Better class name for its behavior
Rob Apodaca