Limit users in a PHP application

3

Hello,

Developed a system in php controlled by Sessions ..

I checked that you can limit the maximum number of online users on the system via apache (httpd.conf).

Is there any function (ajax, javascript, php) that I can limit to 05 concurrent users logged into the system?

    
asked by anonymous 09.12.2017 / 13:49

2 answers

1
  

Question: I noticed that you can limit the maximum number of online users on the system via apache (httpd.conf)

No, this limiting session in apache is not done for users, the limits on apache would probably be to control connections, which does not guarantee you limit the maximum access of users to a site or page, nor can determine the As a result of this, since it is possible to maintain a session and there are various types of use for a connection, such as SSE or use the HTTP 100 Continue response, or else the same user can open more than one connection (for each tab or window you open).

But none of these is the main issue, if you want to limit the number of users, first you need to teach your system what a user is , the user could be checked by IP maybe, I think it is not a good idea, since the same IP on a network connected to the same ISP can be used by multiple computers, so what you can do is use the same sessions , however there is a large PLEASE, it is not possible to detect when a user (which you taught to your system "what is / is when") went out / disconnected.

The only way to detect if the user left is a idle time counter, ie if a user is 5 minutes idle you can "kill" his session and determine for other users that session for others is invalid, both factors as much as "kill" and when disregard for others will depend solely on the time check, ie you will not destroy / kill that user's session, it's just a matter of logic. >

  

Maybe someone will tell you what beforeunload could help, but it's up to you, beforeunload does not will work to detect when the user is leaving, more details about it in

     

Even if you can apply all the logic, you still need a database or .txt (which can be much more complicated) to check all users, you do not really need to be authenticated, the table should be something like:

CREATE TABLE usuarios (
    id INT NOT NULL UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    session VARCHAR(80) NOT NULL,
    lastactive TIMESTAMP
)

As users go to the table it would look like this

id | session                    | lastactive
------------------------------------------------------
1  | 22sin5grink0a22l80ej33mcj6 | 2018-06-24 01:00:23
------------------------------------------------------
2  | ul5c6rkacb68suu6rqmd6dubt3 | 2018-06-24 01:00:33
------------------------------------------------------

Each session generated in the table was created at the time the session was entered, ie the first time the user logged in, the script would look something like:

<?php

session_start();
require 'conexao.php';

define('MAX_USERS', 10); //Limite de 10 usuários
define('TIME_ONLINE', time() - 120);//120 = 2 minutos

$jaEstaOnline = false;

//Verifica se você já esta na "sessão" e dentro do limite de 2 minutos para considerar se estava ocioso ou não
$queryLogado = 'SELECT id TOTAL FROM usuarios WHERE
                session = ' . session_id() . ' AND
                lastactive > FROM_UNIXTIME(' . TIME_ONLINE . ')';


//Verifica só considera as linhas (usuários) no banco dentro dos minutos
$queryConta = 'SELECT count(*) as TOTAL FROM usuarios
               WHERE lastactive > FROM_UNIXTIME(' . TIME_ONLINE . ')';

if ($result = $mysqli->query($queryLogado)) {

    $row = $result->fetch_assoc();

    $jaEstaOnline = isset($row['id']); //Verifica se existe

    $result->free();
}

//Só executa a contagem se você estiver ocioso ou se for o seu primeiro acesso
if (!$jaEstaOnline && ($result = $mysqli->query($queryConta))) {

    $row = $result->fetch_assoc();

    if (!$row) {
        die('Erro na query');
    } else if ($row['TOTAL'] > MAX_USERS) {
        die('Já tem ' . MAX_USERS . ' usuários acessando');
    }

    $result->free();
}

//Verifica só considera as linhas (usuários) no banco dentro dos minutos
$query = 'SELECT count(*) as TOTAL FROM usuarios WHERE lastactive < FROM_UNIXTIME(' . TIME_ONLINE . ')';

if ($result = $mysqli->query($query)) {

    $row = $result->fetch_assoc();

    if (!$row) {
        die('Erro na query');
    } else if ($row['TOTAL'] > MAX_USERS) {
        die('Já tem ' . MAX_USERS . ' usuários acessando');
    }

    $result->free();
}

//Acaso chegar até aqui então irá atualizar o seu tempo no banco e irá determinar que você não esta ocioso, ou acaso seja o seu primeiro acesso irá te "registrar"
$query = 'REPLACE INTO my_table (session, lastactive) VALUES (session_id(), CURRENT_TIMESTAMP);';

if ($result = $mysqli->query($query)) {
   echo 'Você esta conectado';
} else {
   die('Você não esta conectado');
}
  

It would also be interesting to add something to delete all rows with more than a week for example, so it would decrease the unnecessary data in the bank

How to check users online without a bank

Yes it is possible to do with .txt for example, but it is much more complicated, because you will have to write a logic on it, but something like this would be the next thing you could do:

<?php

session_start();

$arquivoDeUsuarios = 'caminho/para/arquivo/usuarios.txt';

define('MAX_USERS', 10); //Limite de 10 usuários
define('TIME_ONLINE', time() - 120);//120 = 2 minutos

$users = array();

if (is_file($arquivoDeUsuarios)) {
     $unserialized = unserialize(file_get_contents($arquivoDeUsuarios));

     if ($unserialized) {
         $users = $unserialized;
     }
}

$id = session_id();

//Filtra e só considera os usuários não ociosos
$users = array_filter($users, function ($tempo) {
    return $tempo >= TIME_ONLINE;
});

//Verifica se é a seu primeiro acesso, se for vazio é porque é o primeiro ou vocÊ estava ocioso
if (empty($users[$id]) && count($users) > MAX_USERS) {

     //Se o count passar do MAX_USERS é por que tem mais de 10 usuários (ou o limite que você definiu)
     die('Já tem ' . MAX_USERS . ' usuários acessando');
}

//Atualiza o tempo ou adiciona você acaso for o primeiro acesso
$online[$id] = time();

//Salva os dados
file_put_contents($arquivoDeUsuarios, serialize($users));

But it's important to note that using .txt can be very inefficient, someone can get over the information of the other before the expected moment, in this case working with LOCK php flock ) next to a recursive check would help avoid problems such as loss of recordings, or record something over, however this would make everything very slow for users.

    
09.12.2017 / 18:48
-1

First, create a table with the following columns:

|-----------------------------------|
| IP varchar(15) | Views tinyint(1) |
|-----------------------------------|

Then, for each view, enter the IP (if it is not in the database) or increase the views by 1. If views = 5, kill the page and do not allow the user to visit.

You can then run a cron every night at 00:00 which excludes all data in the table (study: truncate).

    
09.12.2017 / 16:59