russthebarber Posted December 9, 2011 Share Posted December 9, 2011 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? Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/ Share on other sites More sharing options...
scootstah Posted December 9, 2011 Share Posted December 9, 2011 protected $db_fields = array(); public function __construct($fields) { $this->db_fields = $fields; } Then when you instantiate the class just pass the tables to it. $class = new class(array('id', 'name', 'address')); Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296232 Share on other sites More sharing options...
ManiacDan Posted December 9, 2011 Share Posted December 9, 2011 You can also have it accept a database tablename and parse its own fields from the db, but that will require a query which may be unnecessary if these tables rarely change. Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296244 Share on other sites More sharing options...
russthebarber Posted December 9, 2011 Author Share Posted December 9, 2011 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; Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296379 Share on other sites More sharing options...
requinix Posted December 9, 2011 Share Posted December 9, 2011 get_class_vars Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296381 Share on other sites More sharing options...
russthebarber Posted December 9, 2011 Author Share Posted December 9, 2011 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. Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296385 Share on other sites More sharing options...
ManiacDan Posted December 9, 2011 Share Posted December 9, 2011 Write a "class maker." Give it a database table. The script issues a SHOW CREATE TABLE for that table, and parses the output. Print out properly-formatted PHP code to the screen, then copy and paste into your favorite editor. Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296386 Share on other sites More sharing options...
mikesta707 Posted December 9, 2011 Share Posted December 9, 2011 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. Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296392 Share on other sites More sharing options...
ManiacDan Posted December 9, 2011 Share Posted December 9, 2011 If each class has its own functionality, you have to keep them as separate classes. You could do the array thing, but that would require an extra database query on every page load, which might be costly if you have large traffic stats. Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296396 Share on other sites More sharing options...
Andy-H Posted December 9, 2011 Share Posted December 9, 2011 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); } } Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296399 Share on other sites More sharing options...
xyph Posted December 9, 2011 Share Posted December 9, 2011 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 ) Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296403 Share on other sites More sharing options...
mikesta707 Posted December 9, 2011 Share Posted December 9, 2011 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. Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296405 Share on other sites More sharing options...
russthebarber Posted December 10, 2011 Author Share Posted December 10, 2011 Lots of good tips and advice. Thanks very much. I need to have a good think about which way to go. Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296459 Share on other sites More sharing options...
kicken Posted December 10, 2011 Share Posted December 10, 2011 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'); } Quote Link to comment https://forums.phpfreaks.com/topic/252832-loop-declaring-class-variables/#findComment-1296465 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.