this:
$names[] = $row['user_id']. ". ".$row['first_name'].$row['last_name'];
writes the user_id into a string along with the user's name. This will make it difficult to use later on.
Instead, just pass the user_id and name separately:
$names[] = array( $row['user_id'], $row['first_name'].$row['last_name'] );
Then, when you build your select box, use the user_id as the value of the option, leaving the name as the option text
(note I also changed some of your HTML markup that was incorrect):
$select_box = '<select name="user_id">';
foreach ($names as $name) {
// remember, $name is now an array holding the user_id and name
list( $uid,$uname ) = $name;
$select_box .= '<option value="'. $uid .'">'. $uname .'</option>';
}
$select_box .= "</select>";
print $select_box;
when the form is submitted:
if (isset($_POST['user_id']) && ctype_digit( $_POST['user_id'] )) {
// the ctype_digit() check makes sure the user_id is numeric:
// (I'm assuming all your user_ids are integers)
// if other characters are submitted, then something fishy is going on
// This also means that (being only numbers) it's safe for the database query
$user = new User();
$user_id = $_POST['user_id'];
// since we don't use the return value of your getUserById() method,
// there's no reason to assign it to a variable
$user->getUserById($user_id);
// and so forth