Как сделать конструктор класса правильно?
Обычно это делается в отдельном методе, наподобие Save.
У пользователя, которого нет в базе, $this->id будет нулевым.
И для загрузки данных лучше сделать отдельный метод - Load.public function __construct($id = NULL)
{
  $this->id = $id;
  $this->Load();
}

public function Load()
{
  // идентификатор не указан, загружать данные не нужно
  if (!isset($this->id) || (int)$this->id == 0)
  {
    return false;
  }

  // указан идентификатор, загружаем данные в текущий экземпляр класса
  $mysqli = db_connect();

  $req = 'SELECT u.ID, u.name, u.age, u.city_id, c.city_name FROM users AS u '.
         'INNER JOIN cities AS c ON (c.city_id = u.city_id) '.
         'WHERE u.ID = '.$this->id; // опасно так передавать в запрос данные

  $res = $mysqli->query($req);

  if ($res !== false){
    if ($res->num_rows == 1 )
    {
      // смысла в цикле нет, ожидается ведь одна строка данных
      while ($row = $res->fetch_assoc())
      {
        $this->id = $row['ID'];
        $this->username =  $row['name'];
        $this->city_name = $row['city_name'];
        $this->city_id = $row['city_id'];
        $this->age = $row['age'];
      }
    }
    else
    {
      return false;
    }
  }
  else
  {
    return false;
  }
}

public function Save()
{
  $sql = '';
  $params = [];

  if (!isset($this->id) || (int)$this->id == 0)
  {
    // запрос на добавление данных в базу
    $sql = 'INSERT INTO users (name, city_id, age) VALUES (?, ?, ?)';
    // параметры запроса
    $params = [$this->username, $this->city_id, $this->age];
  }
  else
  {
    // запрос на обновление данных в базе
    $sql = 'UPDATE users SET name = ?, city_id = ?, age = ? WHERE ID = ?';
    // параметры запроса
    $params = [$this->username, $this->city_id, $this->age, $this->id];
  }

  // код выполнения запроса
  // не могу быть уверен в коде, давно не писал и проверять лень
  // должно быть что-то типа такого:

  $mysqli = db_connect(); // лучше сделать отдельный метод для создания и закрытия соединений

  // подготавливаем запрос
  $s = $mysqli->prepare($sql);

  // выполняем запрос с указанными параметрами
  $s->execute($params);

  // тут еще неплохо бы закрыть все соединения :-)
}
Можно пойти дальше и сделать базовый класс, который будет содержать готовые методы Load и Save. 
Либо сделать отдельный класс, который будет получать данные и заполнять экземпляры классов этими данными, сохранять и удалять данные. В таком случае классы таблиц (сущности) будут просто описывать структуру данных в базе и не будут выполнять никаких действий. Этот вариант мне нравится больше, т.к. он чище (проще) и более гибкий. 
Придется придумать, как сопоставлять данные, если имена свойств не соответствую именам полей в базе. Скорее всего интерфейсы нужно будет использовать. Также учесть свойства, которые не определены в базе (которые следует игнорировать).
Для работы со структурой классов потребуется использовать Reflection. 
В общих чертах примерно следующим образом:// создаем экземпляр класса User
$instance = new User();

// получаем информацию об экземпляре класса
$r = new \ReflectionClass($instance);

// получаем список публичных свойств
$propeties = $r->getProperties(\ReflectionProperty::IS_PUBLIC);

// перебираем все свойства
foreach ($propeties as $property)
{
  // получаем имя свойства
  $propertyName = $property->getName();
  // получаем значение свойства
  $propertyValue = $property->getValue();
  // и далее можно использовать полученную информацию
  // для формирования динамических запросов к базе

  // полученные из базы данные можно передать в нужные свойства
  $property->setValue("значение из базы");
}
Готовое решение найти будет проще :-)
}  else return false;
    } else return false;
конструкторы ничего не возвращают.
Просто создавайте пустой инстанс объекта, заполняйте данные, потом сохраняйте его в базу.