I'm having some trouble updating a MySQL database via a PHP class (this is my first real foray into PHP classes, so I might be missing some very basic elements). I've included the code that is relevant to the problems I am having (that is, not properly updating the MySQL table).
To quickly explain my code, I pull a user's information from the database when an object is constructed. Then, I call the function modify_column()
to increase or decrease a numeric value from the data I've pulled. Finally, I run save()
to update the MySQL table.
I am having two problems: (1) $this->info
is not being updated properly by the modify function (for example, if I modify_column('age', '1')
, a var_dump shows age int(3)
rather than age string(2) = 10
(assuming the original age was 9). And (2), the update query is not working. I'm assuming it's because I have an improperly-sized variable stemming from the first issue.
A snippet of the code (my database functions are based on a PDO wrapper and they have always worked just fine):
class user {
public $id;
public function __construct($id) {
global $db;
/* pull the user's information from the database */
$bind = array(':id' => $id);
$result = $db->select('user', 'id = :id', $bind, '*', SQL_SINGLE_ROW);
$this->id = $result['id'];
$this->info = $result;
}
/*
* Update the user's MySQL table, thereby saving the data.
*/
public function save() {
global $db;
$bind = array($this->id);
$db->update('users', $this->info, 'id = ?', $bind);
}
public function modify_column($column, $amount) {
$this->info[$column] += $amount;
}
}
Also, please let me know if there is a neater way to do what I am trying to accomplish (that is, quickly modify numeric values in a table using class functions.
Thanks!
You seem to not have any provision for typing of your variables. When you add your data to $this->info
all the value are going to be set as strings. You don't want to do incremental math (i.e. +=
, -=
etc.) on strings. You need to cast to these values as integer. What I suggest would be to add a class property having an array of your class properties and their types. You will then be able to cast all you values according to their types when setting the $info
array.
So something like this
protected $fields = array(
'age' => 'integer',
'name' => 'string',
// etc.
}
Then you can add a function like this
protected function type_cast(&$value, $key) {
// field type to use
$type = $this->fields[$key];
if ($type === 'integer') {
$value = (integer)$value;
} else if ($type === 'string') {
$value = (string)$value;
} // etc.
}
And in your constructor, just walk $result
through the type_cast
function:
array_walk(&$result, array($this, 'type_cast'));
$this->info = $result;
You probably also need to make sure your id value cast as an integer if you are using an integer in the DB.
I am not sure how you DB abstraction works, so hard to tell what is happening. I would suggest echoing out the query itself and trying it against the database, or taking a look at the MySQL errors that are being returned to get a feel fro what is going wrong there.