Jump to content

loop declaring class variables


russthebarber

Recommended Posts

I'm looking for a more efficient way of declaring variables within a class. What I normally use is a class which is actually a database object. Every time I make a new table in my database I make a new class and new attributes to match the fields in the db table. Looks something like this:

 

protected static $table_name="myTable";
protected static $db_fields=array('id', 'name', 'address', 'tel_number', 'fax_number');

public $name;
public $address;
public $tel_number;
public $fax_number;

//etc. etc.

 

At the moment I am manually adding the attribute, everytime I add a field to the db table. I'm guessing there should be a way to loop through the $db_fields array and add an attribute in the loop? Can anyone help me with the syntax for this. Is there also a way that I don't have to list the fields everytime in $db_fields....can $db_fields not just look at the relevant db table and pull out the field names in some kind of clever method?

Link to comment
Share on other sites

What ManiacDan has suggested is maybe what I'm looking for.

 

This is an example of the kind of thing I want to do...obviously this code is completely wrong and won't work but will hopefully show which direction I want to go in.

 

protected static $db_fields=array('id', 'field1', 'field2', 'field3', 'field4', 'field5');

function writeAttributes()
{
	for($i = 0; $i < count($db_fields); $i++)
	{
		public $$db_fields[$i];
	}
}

//looking for the function to return the following:
//public $id;
//public $field1;
//public $field2;
//public $field3;
//public $field4;
//public $field5;

Link to comment
Share on other sites

I can only assume my explaination of what I need is extremely bad, so I'll start from scratch.

 

Let's say I have a project with 100 different database tables. Every table has a class with various methods for doing specific tasks in that table. The tables have many fields. At the moment I am having to physically type in the name of the fields at the top of my class...see code above. I am also then physically typing every field name once again when declaring the public variables. This is obviusly time consuming and very bad practice. I am looking for a better way of doing this in a loop, so regardless of which database table I am writing the class for, I just enter the name of the table and my code does the rest. I hope that is clearer.

Link to comment
Share on other sites

Instead of separate variables for each column, why not use an associative array. You could then easily run a query in the constructor to populate the array with the names of the columns. This is a perfect example of why arrays exist in the first place. Plus you don't need to keep track of many classes. Just one.

Link to comment
Share on other sites

Are you doing something like a class where in the __construct it sets all the fields, then they're updated during script execution, then saved back to the database on the __destruct method?

 

 

You could do something like this?

 

 

class db_table
{
   protected
      $_dbo,
      $_table,
      $_fields = array(),
      $_clause
   ;
   public function __construct(Database $dbo, $table, $clause = '')
   {
      $this->_dbo    = $dbo;
      $this->_table  = $table;
      $this->_clause = $clause;
   }
   public function __set($key, $value)
   {
      $this->_fields[$key] = $value;
   }
   public function query()
   {
      $query = "SELECT `" . implode($this->_fields, "`,`") . "` FROM `". $this->_table . "`" . $this->_clause;
      $this->_dbo->query($query);
      $this->_fields = $this->_dbo->fetch('assoc');
   }
   public function __get($key)
   {
      return $this->_fields[$key];
   }
   public function __destruct()
   {
      $func  =  create_function('$k, $v', 'return `$k` = \'$v\';');
      $query = "UPDATE `". $this->_table ."` SET ". implode(',', array_walk($this->_fields, $func) . "`" . $this->_clause;
      $this->_dbo->query($query);
   }
}

Link to comment
Share on other sites

Alternate:

 

func_get_args

 

<?php 

class genericDB {

protected $columns = array(), $table;

public function __construct( $table ) {
	$args = func_get_args();
	array_shift( $args );
	foreach( $args as $arg )
		$this->columns[] = $arg;
}

public function getColumns() {
	return $this->columns;
}

}

$obj = new genericDB( 'tableName', 'col1', 'col2', 'foo', 'bar' );

print_r( $obj->getColumns() );

?>

 

returns

 

Array
(
    [0] => col1
    [1] => col2
    [2] => foo
    [3] => bar
)

Link to comment
Share on other sites

You could also combine me and dans ideas, where you create a script to create the arrays. That way you don't have a bunch of different classes to manage and you don't have to worry about the overhead of an additional query on each page. Then again you could always cache the query.

Link to comment
Share on other sites

unless for some reason you need to have the fields declared as properties, I would just handle it via __get and __set magic methods:

 


abstract class DBTable {
protected static $fields=array();
private $values;

public function __construct(){
	$this->values=array();
	foreach (static::$fields as $f){
		$this->values[$f]=null;
	}
}

public function __get($nm){
	if (!in_array($nm, static::$fields)){
		throw new Exception('Field '.$nm.' does not exist.');
	}

	return $this->values[$nm];
}

public function __set($nm, $v){
	if (!in_array($nm, static::$fields)){
		throw new Exception('Field '.$nm.' does not exist.');
	}

	$this->values[$nm] = $v;
}
}


class Users extends DBTable {
protected static $fields=array('username', 'password', 'email', 'firstname', 'lastname');

//...
}

class Post extends DBTable {
protected static $fields=array('subject', 'content', 'by');
}

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.