eldan88 Posted April 12, 2013 Share Posted April 12, 2013 Hey, I am new to PHP and I'm trying to understand this tutorial that instanicates a row, and assigns it to a $object[] array through a method called find_by_sql. There is another method that is called find_by_id that uses the find_by_sql method, the difference is it just finds the array through an ID. My question is why does the find_by_id method returns the result set using an array_shift? Below is the code. Any help will be highly appreciated! :happy-04: The Class starts with the user attributes.. they get assigned by the instantiate method below. class User { //Object attributes are below public $id; public $username; public $password; public $first_name; public $last_name; Below is the find_by_sql and find_by_id method. /* 1) The following method below does the SQL finding based on an arguement that i passed in 2) It then preforms a fetch array on the result set and instantiates it with the instantiate method below and assigns it to the $object_array */ 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 instanciated row and assignes it to $object_array } return $object_array; } public static function find_by_id($id=0) { // Takes an ID as an argument $result_array = self::find_by_sql("SELECT * FROM users WHERE id={$id} LIMIT 1"); return !empty($result_array) ? array_shift($result_array) : false; // Why does it take the first element out of the array ??? } Below is the instantiate method that instantiates a row and assigns it to the attriubutes above private static function instantiate($record) { // Could check that $record exists and is an array $object = new self; // Instanciates the user calss to $object // 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)) { // the has_attribute is a function I had to write below the checks if the attributes are in the object first. $object->$attribute = $value; } } return $object; } private function has_attribute($attribute) { // get_object_vars returns an associative array with all attributes // (incl. private ones!) as the keys and their current values as the value $object_vars = get_object_vars($this); // 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, $object_vars); } }// end of user class Quote Link to comment Share on other sites More sharing options...
TOA Posted April 12, 2013 Share Posted April 12, 2013 From the manual: array_shift() shifts the first value of the array off and returns it *emphasis added You only need the first result so it just grabs the first one and returns it to the function called. But since it LIMITS to 1, it seems kinda pointless to me, but I just glanced at the code so there might be something I'm missing. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted April 12, 2013 Share Posted April 12, 2013 it's probably for consistency purposes. you can use the same line of code to fetch the next element from the array no matter how rows are in the array being operated on. Quote Link to comment Share on other sites More sharing options...
akphidelt2007 Posted April 12, 2013 Share Posted April 12, 2013 You have this question... Why does it take the first element out of the array ?? That is what array_shift does. It takes the first element out of the array. $array = Array(1,2,3,4); $firstEl = array_shift($array); print_r($array); //equals Array(2,3,4) //And $firstEl = 1; For what you are doing you can use isset instead of array_shift... return isset($result_array[0]) ? $result_array[0] : false; This way you retain the $result_array. Quote Link to comment Share on other sites More sharing options...
trq Posted April 12, 2013 Share Posted April 12, 2013 A little off topic, but if you are using this code to learn OOP, don't. All those code will teach you is bad coding practices. Even at a glance there is some glaringly obvious poor design / coding decisions being made. Public properties, global variables and static methods everywhere. Forget you ever found this code. Quote Link to comment Share on other sites More sharing options...
eldan88 Posted April 18, 2013 Author Share Posted April 18, 2013 A little off topic, but if you are using this code to learn OOP, don't. All those code will teach you is bad coding practices. Even at a glance there is some glaringly obvious poor design / coding decisions being made. Public properties, global variables and static methods everywhere. Forget you ever found this code. Whats wrong with having global, static, and private properties in on class? Quote Link to comment Share on other sites More sharing options...
Hall of Famer Posted April 18, 2013 Share Posted April 18, 2013 (edited) Whats wrong with having global, static, and private properties in on class? Globals are bad not just in OOP, they are considered evil everywhere. You can easily overwrite a global variable, and break the rest of your code that depends upon it. You should only use them when you absolutely have to, most likely with metadata. If you can use dependency injection, do it, its way better than using globals. Otherwise, at least get around with a Registry object. Statics are not OOP at all, they can be called and accessed without using objects and object relations. Inheritance and Polymorphism are important for OOP, which are nonexistent in static context. Also you can bring back the horror of global state with statics, especially for public static properties/methods. Theres nothing wrong with private properties though, and in fact properties should be private or protected while public properties are poor OOP practice. Edited April 18, 2013 by Hall of Famer Quote Link to comment Share on other sites More sharing options...
eldan88 Posted April 18, 2013 Author Share Posted April 18, 2013 Globals are bad not just in OOP, they are considered evil everywhere. You can easily overwrite a global variable, and break the rest of your code that depends upon it. You should only use them when you absolutely have to, most likely with metadata. If you can use dependency injection, do it, its way better than using globals. Otherwise, at least get around with a Registry object. Statics are not OOP at all, they can be called and accessed without using objects and object relations. Inheritance and Polymorphism are important for OOP, which are nonexistent in static context. Also you can bring back the horror of global state with statics, especially for public static properties/methods. Theres nothing wrong with private properties though, and in fact properties should be private or protected while public properties are poor OOP practice. Wow never knew about that? So what would be a better way to call the $database class after instantiating it in the user class? Quote Link to comment Share on other sites More sharing options...
Hall of Famer Posted April 22, 2013 Share Posted April 22, 2013 (edited) Well you can use dependency injection. The best way to instantiate a user class is to design a domain model and a data mapper. The beauty of this is, well, its truly object oriented. Heres an example from Anthony Ferrara: $mapper = new PersonDataMapper(new MySQLi(...)); $people = $mapper->getAll(); As you see, the database extension used here is MySQLi(quite similar to PDO though), and Anthony uses dependency injection to pass this database object into the Mapper object. The mapper then encapsulates all the processes of data retrieval, and mapping of data into person model or people collection. Note the above example fetches all users in the database, which is why you see the method getAll(). If you know the user id, simply use $user = $mapper->findByID($id) and the mapper returns a domain model object nicely. The implementation of Mapper classes can be a bit complex for beginners and intermediate skilled programmers though, its a step for intermediate skilled programmers to improve into advanced programmers. Edited April 22, 2013 by Hall of Famer Quote Link to comment Share on other sites More sharing options...
Strider64 Posted April 22, 2013 Share Posted April 22, 2013 (edited) I don't want to hijack this thread, so I'll keep my question simple. Isn't Mapper Classes a PEAR package? Edited April 22, 2013 by Strider64 Quote Link to comment Share on other sites More sharing options...
Hall of Famer Posted April 22, 2013 Share Posted April 22, 2013 I am not quite familiar with Pear, but yeah I do remember they have a base mapper class. In most cases though, you will need to design individual data mappers for each different domain object, unless you have a really simple structure and that every database table shares exactly the same behavior. 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.