Проблем със сесия

teroristd

Registered
Ето какъв е проблема. Да кажем потребител отива на някаква страница, която изисква да бъде логнат за да може да извърши някакво действие. На страницата(вю-то) сетвам сесия.

PHP:
session_start();
$_SESSION['userCurrentUrl'] = $this->_currentUrl;

Потребителят отива да се логва и аз проверявам дали е сетната сесия с url-a и ако не е го пращам на началната страница иначе го връщам на страницата от която идва.

PHP:
if (!isset($_SESSION['userCurrentUrl']))
{
header("Location:" . $this->_link);
}
else
{
header("Location:" . $this->_link . '/' . $_SESSION['userCurrentUrl']);
}

На страницата в която сетвам имам сесията, но в логина сесията е null. Някакви идеи какво да правя?
 
По default нямам в логин контролера. Така работеше на локалхоста, но пробвах да слагам в конструктора на логин контролера също и във вю-то на
логин и няма резултат.
 
Нещо липсва информация. Сигурен ли си, че реално сетваш сесията? Малко повече код няма да навреди да се погледне. Също ... дебъг.
 
Ето какво е положението.
Слагам session_start(); и var_dump($_SESSION['userCurrentUrl']); в конструктора на логин контролер-а и имам сесия преди да субмитна. След това вече сесията става null и проверката не минава. Пускам контролера и модела за повече информация.

Login controller


PHP:
<?php

namespace controllers;

use application\Normalize;
use application\routers\DefaultRouter;
use application\View;
use models\IsLoggedModel;
use models\LoginModel;

class Login
{
    private $_view;
    private $_loginModel;
    private $_defaultRouter;
    private $_normalize;
    private $_data;
    private $_link;
    private $_isLoggedModel;

    public function __construct(View $view, LoginModel $loginModel, DefaultRouter $defaultRouter, Normalize $normalize, IsLoggedModel $isLoggedModel)
    {
        $this->_view = $view;

        $this->_loginModel = $loginModel;

        $this->_defaultRouter = $defaultRouter;

        $this->_normalize = $normalize;

        $this->_data = $this->_loginModel->html();

        $this->_link = $this->_defaultRouter->link();

        $this->_isLoggedModel = $isLoggedModel;
        
        session_start();
        var_dump($_SESSION['userCurrentUrl']);
    }

    public function run()
    {
        try
        {
            $this->_isLoggedModel->isLogged();
        }
        catch (\Throwable $exc)
        {
            if ($exc->getMessage() == 'logged')
            {
                header("Location:" . $this->_link);
            }
        }

        $submit = $this->_normalize->post('submit', 'trim');

        $email = $this->_normalize->post('email', 'trim');

        $pass = $this->_normalize->post('pass', 'trim');

        try
        {
            $this->_loginModel->run($email, $pass);
        }
        catch (\Throwable $exc)
        {
            $this->_view->_emailValue = $email;

            if (isset($submit))
            {
                if ($exc->getMessage() == 'ok')
                {
                    if (!isset($_SESSION['userCurrentUrl']))
                    {
                        header("Location:" . $this->_link);
                    }
                    else
                    {
                        header("Location:" . $this->_link . '/' . $_SESSION['userCurrentUrl']);
                    }
                }
                elseif ($exc->getMessage() == 'token')
                {
                    $this->_view->_message = $this->_data['message_13'];

                    $this->layout();
                }
                elseif ($exc->getMessage() == 'empty')
                {
                    $this->_view->_message = $this->_data['message_2'];

                    $this->layout();
                }
                elseif ($exc->getMessage() == 'email')
                {
                    $this->_view->_emailValue = null;

                    $this->_view->_message = $this->_data['message_15'];

                    $this->layout();
                }
                elseif ($exc->getMessage() == 'pass')
                {
                    $this->_view->_message = $this->_data['message_15'];

                    $this->layout();
                }
                elseif ($exc->getMessage() == 'active')
                {
                    $this->_view->_message = $this->_data['message_16'];

                    $this->layout();
                }
            }
            else
            {
                $this->_view->_emailValue = null;

                $this->_view->_message = $this->_data['message_0'];

                $this->layout();
            }
        }
    }

    public function layout()
    {
        // Display
        $this->_view->display('header');
        $this->_view->display('Login');
        $this->_view->display('footer');
    }
}

Login model

PHP:
<?php

namespace models;

use application\App;
use application\Config;
use application\Database;
use application\Normalize;

class LoginModel
{
    private $_config;
    private $_database;
    private $_app;
    private $_normalize;

    public function __construct(Config $config, Database $database, App $app, Normalize $normalize)
    {
        $this->_config = $config;

        $this->_database = $database;

        $this->_app = $app;

        $this->_normalize = $normalize;
    }

    public static function generate()
    {
        return $_SESSION['tokenLogin'] = bin2hex(openssl_random_pseudo_bytes(16));
    }

    public function run($email, $pass)
    {
        session_start();

        $token = $this->_normalize->post('token', 'trim');

        if ($token != isset($_SESSION['tokenLogin']))
        {
            throw new \Exception('token', 405);
        }

        $this->_database->prepare('USE market')->execute();

        if (empty($email) || empty($pass))
        {
            throw new \Exception('empty', 405);
        }

        $sql = $this->_database->prepare('SELECT email FROM users WHERE email=?', array($email))->execute()->fetchAllAssoc();

        if ($sql == null)
        {
            throw new \Exception('email', 405);
        }

        $sqlPass = $this->_database->prepare('SELECT pass FROM users WHERE email=?', array($email))->execute()->fetchAllAssoc();

        foreach ($sqlPass as $value)
        {
            foreach ($value as $hash)
            {
                $verify = password_verify($pass, $hash);

                if ($verify == true)
                {
                    $sqlActive = $this->_database->prepare('SELECT active FROM users WHERE email=?', array($email))->execute()->fetchAllAssoc();

                    foreach ($sqlActive as $val)
                    {
                        foreach ($val as $active)
                        {
                            if ($active == 'no')
                            {
                                throw new \Exception('active', 405);
                            }
                        }
                    }

                    $this->_database->prepare('USE session')->execute();

                    $id = $this->_app->getSession()->getSessionId();

                    $this->_database->prepare('UPDATE sess SET email = ? WHERE sess_id = ?', array($email, $id))->execute();

                    $this->_app->getSession()->setSessionData('logged');

                    $this->_app->getSession()->saveSessionData();

                    throw new \Exception('ok', 200);
                }
                else
                {
                    throw new \Exception('pass', 405);
                }
            }
        }
    }

    public function html()
    {
        $arr = $this->_config->getConfigFile('htmlArr');

        return $arr;
    }
}
[/php]
 
Как load-ваш класовете (инклудваш файловете)?

Може би е вече късно, защото искаш да ползваш системката, която си си написал, но този начин на хвърляне на ексепшъни дори и за неща, които не са грешка е много грешен. Ползвай булеви изрази за връщане и разбий дългите (големи методи) на по-малки, които да вършат само един task с return type bool.
 
С dependency injection container.

Благодаря за съвета, за напред ще го имам на предвид, но за този сайт вече няма за кога да го пренаписвам.
 
Значи тази сесия която идва от модела $_SESSION['tokenLogin'] си съществува. Дали е възможно да презаписва другата защото тя изчезва след като извикам модела?
 
teroristd каза:
Значи тази сесия която идва от модела $_SESSION['tokenLogin'] си съществува. Дали е възможно да презаписва другата защото тя изчезва след като извикам модела?

session_start трябва да го викаш смао веднъж при изпълнение на скрипт.

намери някъде другаде къде да го сложиш
 
Всеки път като извикаш контролера си изтриваш сесията.

1. Викаш за първи път - регистрираш сесията
2. Препращаш
3. Викаш контролера - сесията ти се изтрива

Поне така си го обяснявам аз.

Също, в контролера дъмпни session_status() след като извикаш модела. Трябва да ти изпише 2.



П.П. Цялата ти логика е много объркана.
Във втория try-catch блок на run() в Login контролера викаш отново session_start() през run() на модела.
Цялото използване на try-catch блоковете е напълно излишно. Само си си усложнил живота с тях.

За замазване на положението опитай да дебъгнеш session_status() преди

PHP:
if (!isset($_SESSION['userCurrentUrl']))

и ако не е активна, я активирай там. Ако не, ще трябва да се проследява по-обстойно как и какво извикваш, каква поредност и т.н.
 
Между другото, ако тестваш и оправяш на хостинга, ти препоръчвам, докато го правиш да си вклчиш display_errors докато си оправиш проблемите. Защото по принцип са спрени.
Трябва да имаш PHP Manager някъде в cpanel-а от където да ги включиш.
 
@Revelation в интерес на истината. С php:

PHP 7.0.27 (cli) (built: Jan 5 2018 12:26:39) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Xdebug v2.5.0, Copyright (c) 2002-2016, by Derick Rethans

и следния тест:

1.php:
Код:
<?php
error_reporting(E_ALL ^ E_NOTICE);
session_start();


$_SESSION['myKey'] = 'myValue';
echo 'PREDI INCLUDE'.PHP_EOL;
var_dump($_SESSION['myKey']);

include('./2.php');
echo 'SLED INCUDE'.PHP_EOL;
var_dump($_SESSION['myKey']);

2.php:
Код:
<?php
session_start();
?>

Output-a ми е:

$ php 1.php
PREDI INCLUDE
/Users/fakeheal/Desktop/Test/1.php:8:
string(7) "myValue"
SLED INCUDE
/Users/fakeheal/Desktop/Test/1.php:12:
string(7) "myValue"

Има и notice, ама явно не чисти сесията. Нз дали е от версията, де, notice-a e: "ignoring session_start()" :D
 
Прави сте session_status(); ми връща 2. Не се получава да я активирам преди if (!isset($_SESSION['userCurrentUrl'])). Не знам какво да правя освен да пренапиша логина.
 
Fakeheal каза:

Аз нямам предвид, че session_start wipe-ва сесията, а че когато извика още веднъж контролера, след като извика конструктора стойността на $this->_currentUrl; не е същата и най-вероятно е NULL.
 
Revelation каза:
Fakeheal каза:

Аз нямам предвид, че session_start wipe-ва сесията, а че когато извика още веднъж контролера, след като извика конструктора стойността на $this->_currentUrl; не е същата и най-вероятно е NULL.

Да
 
teroristd каза:
Revelation каза:
Fakeheal каза:

Аз нямам предвид, че session_start wipe-ва сесията, а че когато извика още веднъж контролера, след като извика конструктора стойността на $this->_currentUrl; не е същата и най-вероятно е NULL.

Да

Ами, тогава направи проверка дали е сетната сесията, и ако е не и присвоявай наново стойността на currentUrl.
 

Горе