Переменная дает мне неопределенный индекс отключен 0 - PullRequest
1 голос
/ 20 июня 2020

Сейчас я создаю социальную сеть. Я дошел до точки, когда мне нужны файлы cookie и токены (в базе данных), чтобы люди выходили из системы и входили в систему.

Проблема в том, что по какой-то причине одна из моих переменных не получает никаких данных из запроса, который я написал ...

Вот код страницы:

Cookie_login. php

<?php declare(strict_types=1);

class Login
{
    public static function isloggedIn(): ?int
    {
        if (isset($_COOKIE['SNID'])) {
            $user = DB::query(
                'SELECT  user_id FROM tokens WHERE token=:token',
                [':token' => sha1($_COOKIE['SNID'])]
            );

            if (empty($user) && isset($user[0]['user_id'])) {
                $userid = $user[0]['user_id'];
            }
            if (isset($_COOKIE['SNID_'])) {
                return $userid;
            }
            $cstrong = true;
            $token = bin2hex(openssl_random_pseudo_bytes(64, $cstrong));
            DB_update::query_update(
                'INSERT INTO tokens VALUES (\'\',:token,:user_id)',
                [':token' => sha1($token), ':user_id' => $userid]
            );
            DB_update::query_update('DELETE FROM tokens WHERE token=:token', [':token' => sha1($_COOKIE['SNID'])]);

            setcookie('SNID', $token, time() + 60 * 60 * 24 * 7, '/', null, true, true);

            return $userid;
        }

        return null;
    }
}

и БД. php


<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

class DB
{
    private static function connect(): PDO
    {
        $pdo = new PDO('mysql:host=127.0.0.1;dbname=pap;charset=utf8', 'root', '');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $pdo;
    }

    public static function query($query, $params = [])
    {
        $statement = self::connect()->prepare($query);
        $statement->execute($params);
        return $statement->fetchALL();
    }
}

class DB_update
{
    private static function connect(): PDO
    {
        $pdo = new PDO('mysql:host=127.0.0.1;dbname=pap;charset=utf8', 'root', '');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $pdo;
    }

    public static function query_update($query_update, $paramss = [])
    {
        $statement = self::connect()->prepare($query_update);
        $statement->execute($paramss);
        return $statement->RowCount();
    }
}

Я использовал fopen() и fwrite(), чтобы увидеть, что возвращается $userid, и он возвращал 1 ... Уже проверяйте запросы в SQL, и они работают нормально ... Так что я не знать, почему переменная $userid не сохраняет user_id из таблицы. Надеюсь, вы, ребята, можете мне помочь ... PS: DB_update - это просто имя, которое отличается от DB_query

Ответы [ 3 ]

1 голос
/ 20 июня 2020

Прежде всего:

fwrite($fp, print_r($userid));

Функция print_r имеет второй параметр, по умолчанию установлено false, но в вашем случае вы должны установить true:

fwrite($fp, print_r($userid, true));

В противном случае вы всегда будете писать в файл 1 значение.

И второе. Рекомендуется использовать функцию fclose, чтобы закрыть указатель на открытый файл, если он больше не требуется.

0 голосов
/ 20 июня 2020

Эта строка генерирует вашу ошибку «undefined index off 0»:

$userid = DB::query('SELECT  user_id FROM tokens WHERE token=:token', 
        array(':token' =>sha1($_COOKIE['SNID'])))[0]['user_id'];

В частности, бит [0]['user_id'], который вы пропатчили до конца запроса. Вам следует делать это только в том случае, если вы уверены, что вызываемая функция всегда будет возвращать массив с необходимыми полями (не в случае запросов к БД!). Если совпадений нет, ваш метод DB::query, вероятно, вернет NULL или false (и у вас не может быть NULL[0] et c. Тем более NULL[0]['user_id'], следовательно, ошибка).

Вы захотите отложить присвоение смещения и, прежде всего, иметь logi c для ситуаций, когда совпадения не происходит. Сначала поместите результат запроса БД в переменную, которую вы можете оценить как ожидаемый тип ресурса или нет, - только затем назначьте смещения массива.

$user = DB::query('SELECT  user_id FROM tokens WHERE token=:token', 
        array(':token' =>sha1($_COOKIE['SNID'])));

if (!empty($user) && isset($user[0]['user_id'])) {
    $userid = $user[0]['user_id'];
}
else {
    // whatever that you need to do here.
}

При проблеме с отладкой; ваш print_r логгер регистрирует только 1, потому что:

 print_r ( mixed $expression [, bool $return = FALSE ] ) : mixed
 
... "When the $return parameter is TRUE, this function will return a string.
Otherwise, the return value is TRUE."

Если вы хотите одновременно печатать и регистрироваться в файле, используйте промежуточную переменную в строках $pr = print_r($foo, true); echo $pr; fwrite($fp, $pr);. Надеюсь, это поможет вам разобраться.

0 голосов
/ 20 июня 2020

Хорошо, вот и весь код с комментариями:

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);

class DB
{
    private static function connect()
    {
        $pdo = new PDO('mysql:host=127.0.0.1;dbname=pap;charset=utf8','root','');
        $pdo -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        return $pdo;
    }

    public static function query($query,$params=array())
    {
        $statement = self::connect() ->prepare($query);
        $statement ->execute($params);
       
        $data = $statement -> fetchALL();
        return $data;


    }
}   

class DB_update
{
    private static function connect()
    {
        $pdo = new PDO('mysql:host=127.0.0.1;dbname=pap;charset=utf8','root','');
        $pdo -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        return $pdo;
    }

    public static function query_update($query_update,$paramss=array())
    {
        $statement = self::connect() ->prepare($query_update);
        $statement ->execute($paramss);
        $datas = $statement -> RowCount();
        return $datas;    
    }
}

/**
 * Table `tokens` schema:
 * CREATE TABLE `tokens` (
 * `token` varchar(255) NOT NULL,
 * `user_id` int(11) NOT NULL,
 * PRIMARY KEY (`token`)
 * ) ENGINE=InnoDB DEFAULT CHARSET=utf8
 */

class Login
{
    public static function isloggedIn()
    {
        if (isset($_COOKIE['SNID'])) {
            $userid = DB::query('SELECT user_id FROM tokens WHERE token=:token',array(':token' =>sha1($_COOKIE['SNID'])))[0]['user_id'];

            $fp = fopen('problem.txt', 'w');
            fwrite($fp, print_r($userid, true));
            fclose($fp);

            // I don't understand, what is this ? There is no place in your code, to set that cookie in that named key
            // It always be false
            if (isset($_COOKIE['SNID_'])) 
            {
                return $userid;   
            }
            else {
                $cstrong = TRUE;
                $token = bin2hex(openssl_random_pseudo_bytes(64, $cstrong));
                DB_update::query_update('INSERT INTO tokens VALUES (:token,:user_id)',array(':token'=>sha1($token),':user_id'=>$userid));
                DB_update::query_update('DELETE FROM tokens WHERE token=:token',array(':token'=>sha1($_COOKIE['SNID'])));

                setcookie("SNID", $token, time() + 60 * 60 * 24 * 7, '/', NULL, TRUE, TRUE);

                // I don't understand what is this below
                setcookie("SNID:", '1', time() + 60 * 60 * 24 * 3, '/', NULL, TRUE, TRUE);

                return $userid;   
            }       
        }
      
        return false;
    }
}

// Uncomment code below to log in
// $userIdToLogIn = 19; // You can change it to any other value
// $cstrong = true;
// $token = bin2hex(openssl_random_pseudo_bytes(64, $cstrong));
// DB_update::query_update('INSERT INTO tokens VALUES (:token, :user_id)', array(':token' => sha1($token), ':user_id' => $userIdToLogIn));
// setcookie("SNID", $token, time() + 60 * 60 * 24 * 7, '/', NULL, TRUE, TRUE);
// ------------------------------

// Uncomment code below to log out
// setcookie("SNID", time() - 3600);
// -------------------------------


// And check
$userId = Login::isloggedIn();
if($userId) {
    printf(
        "User with id: %s is logger in with token: %s",
        $userId,
        DB::query('SELECT token FROM tokens WHERE user_id = :user_id', array(':user_id' => $userId))[0]['token']
    );
} else {
    echo "User is not logger in!";
}

А теперь:

  1. Раскомментируйте строки для комментария: Uncomment code below to log in для первого запроса. Сценарий авторизует вас.
  2. Прокомментируйте его для второго и следующих запросов, чтобы проверить, как он работает.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...