xionhack Posted April 8, 2010 Share Posted April 8, 2010 Hello. I have a problem, when I instantiate an object from inside the class and then pass it to any page, then it appears as an array, and for me to echo it i have to do something like $array[0][name]->whatever, and Its really annoying. Im very new at object oriented programming and I think there is something Im missing, any help? Thanks! Quote Link to comment Share on other sites More sharing options...
leehanken Posted April 8, 2010 Share Posted April 8, 2010 I am not sure what you mean about an object turning into an array. Have you tried using print_r, for example: <?php class x { public $p; public $q; function __construct() { $this->p=10; $this->q=20; } }; $a = new x(); print_r($a); ?> produces x Object ( [p] => 10 [q] => 20 ) Quote Link to comment Share on other sites More sharing options...
xionhack Posted April 8, 2010 Author Share Posted April 8, 2010 [syntax=php] class DatabaseObject { public static function find_by_sql($sql="") { global $database; $result_set = $database->query($sql); $object_array = array(); while ($row = $database->fetch_array($result_set)) { $object_array[] = static::instantiate($row); } return $object_array; } protected static function instantiate($record) { // Could check that $record exists and is an array $object = new static; // Simple, long-form approach: // $object->id = $record['id']; // $object->username = $record['username']; // $object->password = $record['password']; // $object->first_name = $record['first_name']; // $object->last_name = $record['last_name']; // More dynamic, short-form approach: foreach($record as $attribute=>$value){ if($object->has_attribute($attribute)) { $object->$attribute = $value; } } return $object; } private function has_attribute($attribute) { // We don't care about the value, we just want to know if the key exists // Will return true or false return array_key_exists($attribute, $this->attributes()); } protected function attributes() { // return an array of attribute names and their values $attributes = array(); foreach(static::$db_fields as $field) { if(property_exists($this, $field)) { $attributes[$field] = $this->$field; } } return $attributes; } [/syntax] [syntax=php] class Schedule extends DatabaseObject { protected static $id_name = "schedule_id"; protected static $table_name="scheduled_studies"; protected static $db_fields = array('schedule_id', 'student_id', 'teacher_id', 'lesson', 'date' , 'time'); public $schedule_id; public $student_id; public $teacher_id; public $date; public $time; public $lesson; public static function find_last_study($student_id) { $sql = "SELECT * FROM " . self::$table_name . " WHERE stuent_id= {$stuent_id} ORDER BY date, time DESC"; $last_study = parent::find_by_sql($sql); return $last_study; } [/syntax] Then If I do this [syntax=php] <?php echo $last_study = Schedule::find_last_study(1); ?> [/syntax] It will return an array with the object in it, not just the object. Let me know if it makes sense. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted April 8, 2010 Share Posted April 8, 2010 It returns an array because find_by_sql returns an array. As an aside, are you sure that you're getting objects back from your instantiate method? 'Static' is a PHP keyword. I doubt it can be used as the name of a class (i.e., '$object = new static;'). Quote Link to comment Share on other sites More sharing options...
xionhack Posted April 8, 2010 Author Share Posted April 8, 2010 its because im using late static binding. Quote Link to comment Share on other sites More sharing options...
leehanken Posted April 8, 2010 Share Posted April 8, 2010 Nightslyr is right that the function returns an array. I think the following will give what you want, limiting the query to 1 record, and returning just the first (and only) element in the array - your object. class Schedule extends DatabaseObject { protected static $id_name = "schedule_id"; protected static $table_name="scheduled_studies"; protected static $db_fields = array('schedule_id', 'student_id', 'teacher_id', 'lesson', 'date' , 'time'); public $schedule_id; public $student_id; public $teacher_id; public $date; public $time; public $lesson; public static function find_last_study($student_id) { $sql = "SELECT * FROM " . self::$table_name . " WHERE stuent_id= {$stuent_id} ORDER BY date, time DESC LIMIT 1"; $last_study = parent::find_by_sql($sql); return $last_study[0]; } ... Also you will need to declare __toString in the Schedule class definition so you can print the object with echo. public function __toString() { return $this->schedule_id . " " . $this->student_id . " " . $this->teacher_id . " " . $this->date . " " . $this->time . " " . $this->lesson; } Quote Link to comment Share on other sites More sharing options...
xionhack Posted April 9, 2010 Author Share Posted April 9, 2010 Thats what I was doing, but because im new at this i diddnt know if thats the best way to do it. Anybody has a better way? Thanks! Quote Link to comment Share on other sites More sharing options...
leehanken Posted April 9, 2010 Share Posted April 9, 2010 One way of doing things, would be to get find_by_sql() to return an array if there are multiple rows, but return an object if there is just one row. public static function find_by_sql($sql="") { global $database; $result_set = $database->query($sql); $object_array = array(); while ($row = $database->fetch_array($result_set)) { $object_array[] = static::instantiate($row); } if (count($object_array)==1) return $object_array[0]; else return $object_array; } I don't know if this solution is aesthetically perfect, but I have seen it done in other people's code and it is the best I can think of. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.