Jump to content

dynamic variables?


dstokkel

Recommended Posts

Hi,

 

I have a Class in which I declare the database field, that I am going to use, manually.

Is it possible to do the declaration dynamically?

In this way I have one class to manage multiple database tables.

<?php
require_once("initialize.php");
require_once(LIB_PATH.DS."database.php");

class Genre {
   
  protected static $table_name="genre";  
  protected static  $db_fields = array('id', 'name');
  public            $id;  
  public            $name;


public static function get_name($id) {
   return self::find_by_id($id)->name;
} 

// Common Database Methods
protected function attributes() {
    // Return an array of attribute keys 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 submmitting
    // Note: does noet 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;
    $attributes = $this->sanitized_attributes();
  $sql = "INSERT INTO ".self::$table_name." (";
	$sql .= join(", ", array_keys($attributes));
  $sql .= ") VALUES ('";
	$sql .= join("', '", array_values($attributes));
	$sql .= "')";    
    if($database->query($sql)) {
      $this->id = $database->insert_id();
      return true;
    } else {
      return false;
    }
  }
     
  public function update() {
    global $database;
    $attributes      = $this->sanitized_attributes();    
    $attribute_pairs = array();
    foreach($attributes as $key => $value) {
      $attribute_pairs[] = "{$key} = '{$value}'";
    } 
    $sql = "UPDATE ". self::$table_name . " SET " . join(", ", $attribute_pairs) . " WHERE id = "  . $database->escape_value($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 = "  . $database->escape_value($this->id) . " LIMIT 1";
    $database->query($sql);
    return ($database->affected_rows() == 1) ? true : false;
  }  
    
  private static function instantiate($record) {
    $object = new self;
    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());
}  

  public static function find_all() {
    global $database;
    return self::find_by_sql("SELECT * FROM ".self::$table_name);
  }
  
  public static function find_by_id($id=0) {
    global $database;
    $result_array = self::find_by_sql("SELECT * FROM ".self::$table_name ." WHERE id = ". $database->escape_value($id) . " LIMIT 1");
    return !empty($result_array) ? array_shift($result_array) : false;
  }
  
  public static function find_id_by_name($name) {
    global $database;
    $result_array = self::find_by_sql("SELECT * FROM ".self::$table_name ." WHERE name = '". $database->escape_value($name) . "' LIMIT 1");
    if (!empty($result_array) ) {
      return array_shift($result_array)->id;
    } else { return false;}
     
  } 
  
  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[] = self::instantiate($row);
    }
    
    return $object_array;
  }

  public static function count_all() {
    global $database;
    $result_set = $database->query("SELECT COUNT(*) FROM ".self::$table_name);
    return array_shift($database->fetch_array($result_set));
  }  
}


?>

Link to comment
Share on other sites

Using globals in a class kind of defeats the purpose of OOP IMO.

 

You probably want something like this.

<?php 

$db1 = new database( 'localhost', 'user', 'pass', 'db1' );

$classA = new classThatNeedsDB( $db1 );

$db2 = new database( 'localhost', 'user', 'pass', 'db2' );

$classB = new classThatNeedsDB( $db2 );

$classC = new classThatNeedsDB( $db2 );

class database {

private $link, $error = FALSE, $errors = array();

public function __construct( $host, $user, $pass, $db ) {
	$this->link = new MySQLi( $host,$user,$pass,$db );
	if( mysqli_connect_error() ) {
		$error = TRUE;
		$errors[] = 'Could not connect to database - '.mysqli_connect_error();
	}
}

public function select( $table, $fields, $where = FALSE ) {
	// etc		
}

}

class classThatNeedsDB {

private $link;

public function __construct( database $link ) {
	$this->link = $link;
}

public function doSomething( $id ) {
	$this->link->select( 'users', array('auth,name,email'), 'id='.$id );
	//etc
}

}

?>

Link to comment
Share on other sites

@thorpe : thanks, and sorry did't know, will do next time

@xyph    : thanks, I am using your construct to get the database object into my Genre class.

 

But what I want, is to generate the properties of the Genre class based on the the table structure.

Now, as you can see, I have coded these properties.

  protected static $table_name="genre";  
  protected static  $db_fields = array('id', 'name');
  public            $id;  
  public            $name;

 

I am a newby in the area of OOP and I am looking for the perfect way to implement OOP into my code.

 

Link to comment
Share on other sites

As you can see, the Class Genre has two properties "Id" and "Name" and I have hardcoded them in the class.

I am using more tables and corresponding classes, like "Books" and "Authors".

These classes also have properties, for instance "Books" has "Author", "Date Plublished" and so on.

In each class I have to code the corresponding properties.

Is there a way to dynamicly genreate these properties based on the database table structure?

Link to comment
Share on other sites

All you want to do is specify which table is used for your calls to your methods? Do you want the table to be constant for a single instance of the object? Or did you want to define the table at each method call?

Link to comment
Share on other sites

Well, you have to watch out as you have static properties, and you're mixing them in with non-static methods. This is how static properties work in PHP

 

<?php

class demo {

private static $var = 'foo';

public function setVar( $val ) {
	self::$var = $val;
}

public function getVar() {
	return self::$var;
}

}

$a = new demo;
$b = new demo;

echo $a->getVar(); // Echos 'foo'

$b->setVar( 'bar' );

echo $a->getVar(); // Echos 'bar'

?>

 

So the first thing you want to do is make $table_name non-static, and change self::$table_name to $this->table_name

 

You could even make $table_name public, and just use

 

$obj = new Genre;

$obj->table_name = 'Books';

 

Or you could include it in the constructor and use

 

$obj = new Genre( 'Books' );

Link to comment
Share on other sites

Hi xyph,

 

Thanks a lot.

I really appreciate your effords in helping me.

Apparantly I am not capable to tell you what I need, this has to do with my lack

in experience in OOP.

Can you supply my with your code of a sytem that you build?

A only need to see how you setup a system in OO style.

Say for instance that you build a CMS, can you supply me with a couple of the files

in which you make the classes that helps you maintain the tables in your database?

 

 

Link to comment
Share on other sites

Hi xyph,

 

Thanks a lot.

I really appreciate your effords in helping me.

Apparantly I am not capable to tell you what I need, this has to do with my lack

in experience in OOP.

Can you supply my with your code of a sytem that you build?

I only need to see how you setup a system in OO style.

Say for instance that you build a CMS, can you supply me with a couple of the files

in which you make the classes that helps you maintain the tables in your database?

Link to comment
Share on other sites

If you aren't understanding the examples above, my code will just confuse the hell out of you. I make use of abstract classes, interfaces, etc.

 

I'm not even sure if you understand exactly what your own class is doing.

Link to comment
Share on other sites

I am understanding the examples that you are giving but it's not what I am searching for.

And I am not able to make clear what I am searching for.

I am attracted by the use of static methods and properties but I don't fully understand them.

That is why I am asking for a real world example.

On the Internet they are always giving abstract examples of cars and fruit and so on.

But when I can take a look at an example of a working system, perhaps I then understand.

If you don't think that is wise, perhaps you can direct my to a source where I can find seach

a working system.

 

thx in advance.

 

Link to comment
Share on other sites

If you don't understand them, don't use them. There are very specific instances where static methods and properties are really helpful. When you run into those, you'll begin to understand why they exist. Until then, write your code as if they don't exist. You don't need or want their functionality at this point.

 

A static property will remain the same through multiple instances of any given object. You only want to use the static keyword when you want to change the behavior over every instance of that specific object. For example

 

class ball {

private $bounce_factor;
private static $surface_factor = '1';

public function __construct( $bounce ) {
	$this->bounce_factor = (int) $bounce;
}

public function drop() {
	return $this->bounce_factor * self::$surface_factor * ( mt_rand(90,110)/100 );
}

static public function changeSurface( $surface ) {
	self::$surface_factor = $surface;
}
}

$ball_hard = new ball( 3 );
$ball_boucy = new ball( 10 );

echo '<h3>Default surface:</h3>';
echo 'Hard ball bounces ' . $ball_hard->drop() . '<br>';
echo 'Bouncy ball bounces ' . $ball_boucy->drop() . '<br>';

ball::changeSurface( 4 );

echo '<h3>Harder surface</h3>';
echo 'Hard ball bounces ' . $ball_hard->drop() . '<br>';
echo 'Bouncy ball bounces ' . $ball_boucy->drop() . '<br>';

 

Another use of static properties is when dealing with Singleton Registries - this is a design pattern, and you can read more about those here

http://www.phpfreaks.com/tutorial/design-patterns---introduction

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.