eldan88 Posted May 1, 2013 Share Posted May 1, 2013 Hey, I was going through a PHP coding tutorial. And in this tutorial it seemed like the $photo variable is an instance variable, but I can't seem to find how it was instantiated?? Can anyone please help me. Below is the code <?php require_once("../../includes/initialize.php"); ?> <?php if (!$session->is_logged_in()) { redirect_to("login.php"); } ?> <?php // Find all the photos $photos = Photograph::find_all(); ?> <?php include_layout_template('admin_header.php'); ?> <h2>Photographs</h2> <table class="bordered"> <tr> <th>Image</th> <th>Filename</th> <th>Caption</th> <th>Size</th> <th>Type</th> </tr> <?php foreach($photos as $photo): ?> <tr> <td><img src="../<?php echo $photo->image_path(); ?>" width="100" /></td> <td><?php echo $photo->filename; ?></td> <td><?php echo $photo->caption; ?></td> <td><?php echo $photo->size_as_text(); ?></td> <td><?php echo $photo->type; ?></td> </tr> <?php endforeach; ?> </table> <br /> <a href="photo_upload.php">Upload a new photograph</a> <?php include_layout_template('admin_footer.php'); ?> Quote Link to comment Share on other sites More sharing options...
trq Posted May 1, 2013 Share Posted May 1, 2013 Looks like Photograph::find_all() returns an array of objects. Quote Link to comment Share on other sites More sharing options...
oaass Posted May 1, 2013 Share Posted May 1, 2013 $photo comes from the foreach loop Quote Link to comment Share on other sites More sharing options...
eldan88 Posted May 1, 2013 Author Share Posted May 1, 2013 Looks like Photograph::find_all() returns an array of objects. I see that now. Thanks! Quote Link to comment Share on other sites More sharing options...
eldan88 Posted May 2, 2013 Author Share Posted May 2, 2013 I'm sorry, I am really confused on how this works. In the coding tutorial blow there is a variable that is assigned to a satic call.. $photos = Photograph::find_all() and then it runs a foreach loop on the array that it returns "<?php foreach ($photos as $photo) { ?>" Trq said that "Photograph::find_all() returns an array of object" However there are methods that I called in the object with the $photo-> variable that find_all() didn't return. Like for example I created a test() method and called it with the $photo variable $photo->test() and it still worked? So i am confused of how did that work when that static call Photograph::find_all() didn't call it Below is my photograph class <?php require_once(LIB_PATH.DS.'database.php'); class Photograph { protected static $table_name="photographs"; protected static $db_fields=array('id', 'filename', 'type', 'size', 'caption'); public $id; public $filename; public $type; public $size; public $caption; private $temp_path; protected $upload_dir="images"; public $errors=array(); public $upload_errors = array( UPLOAD_ERR_OK => "No Errors.", UPLOAD_ERR_INI_SIZE => "Large than upload_max_filesize", UPLOAD_ERR_FORM_SIZE => "Larger than from MAX_FILE_SIZE", UPLOAD_ERR_PARTIAL => "Partial Upload", UPLOAD_ERR_NO_FILE => "No File", UPLOAD_ERR_CANT_WRITE => "Can't write to the disk", UPLOAD_ERR_EXTENSION => "File upload stopped by extension"); //Need to enter the error checking. Last thing i did. // Pass in $_FILE(['uploaded_file']) as an argument public function attach_file($file) { //Preform error checking on the form parameters //Set object attributes to the form parameters //Don't worry about saving anything to the database yet if(!$file || empty($file) || !is_array($file)) { $this->errors[] = "There was no file uploaded"; return false; } elseif($file['error'] != 0) { $this->errors[] = $this->upload_errors[$file['error']]; return false; } else { $this->temp_path = $file['tmp_name']; $this->filename = basename($file['name']); $this->type = $file['type']; $this->size = $file_size['size']; return true; } } public function save() { if(isset($this->id)) { // Really just to update the caption $this->update(); } else { // Make sure there are no errors // Can't save if there are pre-existing errors if(!empty($this->errors)) { return false; } // Make sure the caption is not too long for the DB if(strlen($this->caption) > 255) { $this->errors[] = "The caption can only be 255 characters long."; return false; } // Can't save without filename and temp location if(empty($this->filename) || empty($this->temp_path)) { $this->errors[] = "The file location was not available."; return false; } // Determine the target_path $target_path = SITE_ROOT .DS. 'public' .DS. $this->upload_dir .DS. $this->filename; // Make sure a file doesn't already exist in the target location if(file_exists($target_path)) { $this->errors[] = "The file {$this->filename} already exists."; return false; } // Attempt to move the file if(move_uploaded_file($this->temp_path, $target_path)) { // Success // Save a corresponding entry to the database if($this->create()) { // We are done with temp_path, the file isn't there anymore unset($this->temp_path); return true; } } else { $this->errors[] = "The file upload faled, possibly due to incorrect permessions on the upload folder"; } } } public function image_path() { return $this->upload_dir.DS.$this->filename; } public function size_as_text() { if($this->size < 1024) { return "{$this->size} bytes"; } elseif($this->size < 1048576) { $size_kb = round($this->size/1024); return "{size_kb} KB"; } } public function test() { echo "This is a test"; } //Common datavase bethod public static function find_all() { return self::find_by_sql("SELECT * FROM ".self::$table_name); } public function find_by_id($id=0) { // Takes an ID as an argument $result_array = self::find_by_sql("SELECT * FROM ".self::$table_name." WHERE id={$id} LIMIT 1"); return !empty($result_array) ? array_shift($result_array): false; } public static function find_by_sql($sql="") { global $database; // Brings in the $database instanitated object. $result_set = $database->query($sql); // Runs the query on the $sql argument $object_array = array(); // Initilizes an object_array while ($row = $database->fetch_array($result_set)) { $object_array[] = self::instantiate($row); // Take the inisiated row and assignes it to $object_array } return $object_array; } private static function instantiate($record) { // Could check that $record exists and is an array $object = new self; // 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(self::$db_fields as $field) { if(property_exists($this, $field)) { $attributes[$field] = $this->$field; } } return $attributes; } protected function sanitized_attributes() { global $database; $clean_attributes = array(); // sanitize the values before submitting // Note: does not alter the actual value of each attribute foreach($this->attributes() as $key => $value){ $clean_attributes[$key] = $database->escape_value($value); } return $clean_attributes; } public function create() { global $database; $attriubutes = $this->sanitzed_attriubutes(); $sql = "INSERT INTO ".self::table_name." ("; $sql .= join(", ", array_keys($attriubutes)); $sql .= ") VALUES ('"; $sql .= join(", ", array_values($attriubutes)); $sql .= "')"; if($database->query($sql)) { $this->id = $database->insert_id(); return true; } else { return false; } } public function update() { global $database; $attributes = $this->sanitzed_attriubutes(); // First we assign the attributes() functions to the $attriubutes variable. //Then we run a foreach on the attriubutes foreach ($attributes as $key=>$value) { $attribute_pairs[] = "{$key}='{$value}'"; } $sql = "UPDATE ".self::table_name." SET "; $sql .= join(", ", $attribute_pairs); $sql .= " WHERE id=" . $this->id; $database->query($sql); return ($database->affected_rows() == 1) ? true : false; } public function delete() { global $database; $sql = "DELETE FROM ".self::table_name. " WHERE id=". $this->id . " LIMIT 1"; $database->query($sql); return ($database->affected_rows() == 1) ? true : false; } } ?> and below is where I do all my calling <?php require_once("../../includes/initialize.php"); if(!$session->is_logged_in()) { redirect_to("login.php"); } $photos = Photograph::find_all(); include_layout_template('admin_header.php'); ?> <h2> Photographs </h2> <table class="borderd"> <tr> <th>Image </th> <th> Filename </th> <th> Caption </th> <th> Size </th> <th> Type </th> <th> Test </th> </tr> <?php foreach ($photos as $photo) { ?> <td> <img src="../<?php echo $photo->image_path(); ?>" width="100"/> </td> <td> <?php echo $photo->filename; ?> </td> <td> <?php echo $photo->caption; ?> </td> <td> <?php echo $photo->size > 1024 ? round($photo->size / 1024) . "KB" : $photo->size . "Bytes"; ?> </td> <td> <?php echo $photo->type; ?> </td> <td> <?php $photo->test(); // How is test() being called ?> </td> <?php } ?> </table> <?php include_layout_template('admin_footer.php'); ?> Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted May 2, 2013 Share Posted May 2, 2013 (edited) the objects that are in the array are instances of your Photograph class, one for each row that the query matches, with the properties set to whatever data is in the row from the query, and whatever methods your class has. Edited May 2, 2013 by mac_gyver Quote Link to comment Share on other sites More sharing options...
eldan88 Posted May 2, 2013 Author Share Posted May 2, 2013 the objects that are in the array are instances of your Photograph class, one for each row that the query matches, with the properties set to whatever data is in the row from the query, and whatever methods your class has. Hey. I trying to understand but still can't figure it out. What do you mean by "one for each row that the query matches, with the properties set to whatever data is in the row from the query, and whatever methods your class has.? " Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted May 2, 2013 Share Posted May 2, 2013 if you mean, how did i determine what it is doing, i traced through the execution path and read the code - $photos = Photograph::find_all();////////////////////////////////////////////////////////// public static function find_all() { return self::find_by_sql("SELECT * FROM ".self::$table_name); } ///////////////////////////////////////////////////////// public static function find_by_sql($sql="") { global $database; // Brings in the $database instanitated object. $result_set = $database->query($sql); // Runs the query on the $sql argument $object_array = array(); // Initilizes an object_array while ($row = $database->fetch_array($result_set)) { $object_array[] = self::instantiate($row); // Take the inisiated row and assignes it to $object_array } return $object_array; }////////////////////////////////////////////////////////// private static function instantiate($record) { // Could check that $record exists and is an array $object = new self; // 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()); } if you mean, what does that mean, the answer's in your code and would require that you understand what each statement in your code is doing. do you have a specific question about what any of your code is doing? Quote Link to comment Share on other sites More sharing options...
eldan88 Posted May 3, 2013 Author Share Posted May 3, 2013 if you mean, how did i determine what it is doing, i traced through the execution path and read the code - if you mean, what does that mean, the answer's in your code and would require that you understand what each statement in your code is doing. do you have a specific question about what any of your code is doing? I don't understand how does find_all() function call all the methods in the class when its only argument is mysql query. Isn't that supposed to select everything from the table named photograph? Quote Link to comment Share on other sites More sharing options...
Solution kicken Posted May 3, 2013 Solution Share Posted May 3, 2013 (edited) I don't understand how does find_all() function call all the methods in the class when its only argument is mysql query. Isn't that supposed to select everything from the table named photograph? Note: This is a fairly dumbed-down explanation, hopefully for easy understanding The find_all method queries the database and gets back as a result an array of every row that exist in the database. For every row that it gets back from the database, it runs essentially $obj = new Photograph; and then sets all the properties in the Photograph class to the corresponding column from the database row. Each time it makes a new photograph object, it sticks the object into a array which eventually is the return value for find_all. So your code gets back an array of objects, each of those objects is a new separate instance of the Photograph class. Hopefully that helps explain things. If not you might need to try and read more about how classes and objects work in general. Edited May 3, 2013 by kicken Quote Link to comment Share on other sites More sharing options...
eldan88 Posted May 6, 2013 Author Share Posted May 6, 2013 Note: This is a fairly dumbed-down explanation, hopefully for easy understanding The find_all method queries the database and gets back as a result an array of every row that exist in the database. For every row that it gets back from the database, it runs essentially $obj = new Photograph; and then sets all the properties in the Photograph class to the corresponding column from the database row. Each time it makes a new photograph object, it sticks the object into a array which eventually is the return value for find_all. So your code gets back an array of objects, each of those objects is a new separate instance of the Photograph class. Hopefully that helps explain things. If not you might need to try and read more about how classes and objects work in general. Kicken, Thanks for making it more clearer for me. After reading it I know understand what you explained. 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.