Нужно ли передавать POST, GET, SESSION в класс?
Что бы писать качественные оо-приложения, для начала избавься от знания того, что есть все эти суперглобалы. Они, конечно, используются, но их надо "оборачивать" их классами-сервисами.  Это нетривиальная работа - сделать сервис Session, в котором инкапсулировать всю логику по работе с сесиями, избавившись от нативных функций в коде. Суперглобалы GPR тоже обернуть, навесить на них некоторую логику. В целом тебе правильно сказали - любые значения надо "перебрасывать" в объекты. Напрямую их использовать не нужно. Твои классы должны быть черными ящиками с интерфейсом для входа параметров. А откуда параметры пришли - из GPRC или еще откуда - классы знать не должны.   
 Я не претендую на истину, но я в своем фреймворке сделал вот такое решение: class Request implements Singleton
{
    private function __construct()
    {
        $this->request_data = new RequestData($_REQUEST);
        $this->post_data = new PostData($_POST);
        $this->get_data = new GetData($_GET);
        $this->cookie_data = new CookieData($_COOKIE);
    }

    // ....
Те при инстанцировании приложения я создаю объекты с копиями данных из запроса. На каждый из массивов свой объект: /**
 * Оболочка над GPCR массивами.
 */
abstract class Data extends CoverArray
{
    /**
     * @param array $data
     */
    public function __construct(array $data = array())
    {
        parent::__construct(self::clearData($data));
    }

    /**
     * Очищает массив от пробелов.
     *
     * @param array $in
     * @return array
     */
    private static function clearData(array &$in): array
    {
        if ($in && is_array($in)) {
            foreach ($in as $key => $value) {
                if (is_array($value)) {
                    self::clearData($in[$key]);
                } else {
                    $in[$key] = trim($value);
                }
            }
        }

        return $in;
    }
}

class Post extends Data
{
    /**
     * @param string $key
     * @param mixed $value
     */
    public function __set(string $key, $value)
    {
        parent::__set($key, $value);

        $_POST = $this->getDataAsArray();
    }

    /**
     * @param string $key
     */
    public function __unset(string $key)
    {
        parent::__unset($key);

        $_POST = $this->getDataAsArray();
    }
}
Класс-singelton Request доступен внутри контроллеров.  Он создается в Application и передаетсяв конкретный контроллер. Соответственно, в контроллере я могу получить, например, POST так: $this->getRequest()->getPost('region')
Тут особого профита как такового нет, но это - ООП-шно. Все классы объектов имеют интерфейсы, ничего из неоткуда не берется, как в случае с суперглобалами. 
А дальше больше - можем наложить логику. Например, санитарную обработку:echo $this->getRequest()->getPost('id', 'int'); // приведение к числу
это был пост-запрос? echo (int) Request::isPost();
изменился ли документ?if (!Request::IfModifiedSince($resource->getModificationTime())) {
    return $this->getResponse()->setHttpStatusCode(304);
}
т.е. любые обертки над суперглобалами неизбежно приводят к более приятному коду и повышают уровень возможностей.
Нет, не нужно