нет, вы не правильно поняли MVC.
Попробуйте подойти к проблеме чуть с другой стороны. Реализуйте ваше приложение так, что бы оно ничегошеньки не знало о HTTP, внутри него небыло ни единого echo, оно ничего не знало о сессиях и вообще ничего не знал о таких вещах. Проще всего этого добиться - ваше приложение можно запускать через CLI. Грубо говоря как-то так:
<?php
// run.php - просто скрипт для разового теста
require __DIR__ . '/vendor/autoload.php'; // вы же уже используете composer?
$app = new App();
$app->getService('login_handler')->login('user@example.com', 'password');
Что-то типа такого. То есть на каждый "юз кейс", то есть то что приложение должно делать, у вас должен быть метод. Типа "сделай то-то" и "сделай еще что-то".
Вот это - наше приложение, наша "модель". Не один какой-то класс... это все приложение. MVC же ставит перед собой задачу снижения связанности между UI и приложением. Цель при этом приследуется простая - UI обычно меняется намного чаще чем логика приложения, а стало быть лучше их друг от дружки отделить целиком и полностью.
Делается это за счет того что между UI и приложением вводят дополнительный промежуточный слой адаптеров - контроллеры (это опять же не обязательно один объект, это может быть целая цепочка адаптеров, каждый из которых делает что-то конкретное, в плодь до последнего адаптера который уже конвертирует http запрос в нужный вызов нужного метода).
То есть что бы сказать "я сделал MVC" у вас приложение не должно зависить от UI. Если вы хоть где-то в приложении используете суперглобальные массивы, и т.д. вы проиграли. Ну либо просто не называйте это MVC, скажите что вы просто шаблоны отдельно ложите ну и роутер еще есть. Но это не MVC, это smartui, то есть наше приложение вкурсе что у него есть UI и они сильно связаны.
MVC нужно далеко не всем, и smartui сойдет для простых проектов. Но вы должны понимать разницу, и знать когда стоит загоняться а когда можно логику в контроллеры выносить.
Надо ли было создавать глобальные переменные в модели
Это вы еще не уяснили значит что такое ООП, почему глобальное состояние плохо и что такое побочные эффекты (погуглите в контексте состояния).
делать сеттеры и геттеры?
А этим мы нарушаем инкапсуляцию. Внешний мир должен знать только что можно делать с моделью, но никак не ее структуру. То есть вместо setSomething у вас должно быть осмысленное название, типа updateSomething, changeSomething и т.д. Типа "user should be able to change password" и у вас появляется метод "changePassword". Или "User should be able to update profile details" и у вас появляется один единственный метод "updateProfileDetails()". А что оно как состояние меняет - это консерн исключительно объекта. Ему рашеть менять чего или нет. Мы таким образом изолируем побочные эффекты и уменьшаем вероятность багов. Ну и нам не нужно валидировать при таком раскладе ничего так как нет промежуточного невалидного состояния.