Jump to content

Question about using array_shift with OOP


eldan88

Recommended Posts

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: :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 
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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 by Hall of Famer
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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 by Hall of Famer
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.