简体   繁体   English

如何让按钮执行php脚本?

[英]How to make a button execute a php script?

How to make a html button execute a php script ?如何使 html 按钮执行 php 脚本?

I am working on a login system where only one user can login and whenever other users try to login, it should give them the warning pop up message saying another user is already logged in - Do you want to take over from them?我正在开发一个只有一个用户可以登录的登录系统,每当其他用户尝试登录时,它应该给他们一个警告弹出消息,说another user is already logged in - Do you want to take over from them?

  • If userA is already logged in and userB tries to login then it should show on the popup as userA is already logged in, do you want to take over?如果userA已经登录并且userB尝试登录,那么它应该显示在弹出窗口中,因为userA is already logged in, do you want to take over? . .
  • Now for userA behind the scene, we will take away write access and show them another popup message that your write access is revoked.现在对于幕后的userA ,我们将取消写入权限并向他们显示另一个弹出消息,表明您的写入权限已被撤销。

Second point I can handle it later on but as of now I am focus on doing the point one.第二点我可以稍后处理,但现在我专注于做第一点。 Below is my code in which I am trying to achieve the first point at LINE A -以下是我试图在LINE A实现第一点的代码 -

if (isset($_POST['user_name'], $_POST['user_pass']) && $_POST['user_login'] == 1) {
    //Assigning posted values to variables.
    $username = $_POST['user_name'];
    $password = $_POST['user_pass'];

    //Checking the values are existing in the database or not
    $stmt = $connect->prepare("SELECT user_pass FROM userspanel WHERE user_name=?");
    $stmt->bind_param('s', $username);
    $stmt->execute();
    $result = $stmt->get_result();
    $user_from_db = $result->fetch_object();

    if ($user_from_db && password_verify($password, $user_from_db->user_pass)) {

        $_SESSION['user_name'] = $username;

        $sql = "SELECT * FROM trace_users where open='true'";
        $result1 = mysqli_query($connect, $sql);
        if($result1 = mysqli_query($connect, $sql)){
            if(mysqli_num_rows($result1) > 0){
                while($row = mysqli_fetch_array($result1)){
                    if($row['open'] == "true") {
                        if(!isset($_SESSION['pageadmin'])) {
                            $message = "user " . $row['user_name'] . " is logged in. Do you want to take over ?";
                            // LINE A
                            // how to show pop up button which shows $message on it
                            // and add action on ok and cancel button here?
                        }
                        break;
                    }
                }
            } else{
                $_SESSION['pageadmin'] = true;
                $open = "true";
                $read_access = "1";
                $write_access = "1";
                $stmt = $connect->prepare("UPDATE trace_users SET open=?, read_access=?, write_access=? WHERE user_name=?");
                $stmt->bind_param('ssss', $open, $read_access, $write_access, $username);
                $stmt->execute();
            }
        }

    } else {
        echo "Invalid username and password";
    }
}

I want to achieve the following tasks but I am confused on how to achieve it -我想完成以下任务,但我对如何实现感到困惑-

  • At LINE A , I want to show a pop up message saying "Previous user is logged in. Do you want to take over?"LINE A ,我想显示一个弹出消息,说"Previous user is logged in. Do you want to take over?" with Ok and Cancel buttons.与确定和取消按钮。
  • Once I click on Ok button on that pop up message then I want to execute certain code in php let's say print hello world for now and if I click the cancel button on that pop then I don't want to do anything.一旦我点击弹出消息上的Ok按钮,然后我想在 php 中执行某些代码,假设现在打印hello world ,如果我点击弹出消息上的cancel按钮,那么我不想做任何事情。

In short, I want to achieve two things:简而言之,我想实现两件事:

1. Create a popup message with Ok and Cancel buttons at Line A. 1.在 A 行创建一个带有 Ok 和 Cancel 按钮的弹出消息。
2. On clicking Ok button, I want to execute php script and on clicking Cancel button I don't want anything to happen. 2.单击“确定”按钮,我想执行 php 脚本,单击“取消”按钮,我不想发生任何事情。

Basic scenario:基本场景:

  • Store currently authenticated user's unique id and time in a .txt file in the following format (as JSON):将当前已验证用户的唯一ID时间以以下格式(作为 JSON)存储在.txt文件中:
json_encode(['user_id' => 1, 'created_at' => (new DateTime('now'))->format('Y-m-d H:i:s')]);
  • Check the stored user_id and created_at fields in the file when a user attempts to sign in.当用户尝试登录时,检查文件中存储的user_idcreated_at字段。
  • If the file is empty, log the user in and write user's unique id and time to the file.如果文件为空,则用户登录并将用户的唯一ID和时间写入文件。
  • If the file is not empty and user_id field is same as the id of the user who attempts to log in and created_at field is not older than 12 hours ago (or your custom logic), just update created_at field in the file and log the user in.如果文件不为空并且user_id字段与尝试登​​录的用户的id相同并且created_at字段不早于 12 小时前(或您的自定义逻辑),则只需更新文件中的created_at字段并登录用户在。
  • If the file is not empty and user_id field is same as the id of the user who attempts to log in, but passed more than 12 hours (or your custom logic), ask the user if he/she want to take over another user.如果文件不为空并且user_id字段与尝试登​​录但已超过 12 小时(或您的自定义逻辑)的用户的id相同,则询问用户他/她是否想接管另一个用户。
  • If the file is not empty and user_id field is not same as the id of the user who attempts to log in ask the user if he/she want to take over another user.如果文件不是空的, user_id一样的id谁登录尝试询问用户是否他/她想要接管其他用户的用户。

Basic implementation:基本实现:

  1. Create a .txt file in your project directory.在您的项目目录中创建一个.txt文件。
  2. Add these helper functions to your project ( helpers.php in my case):将这些辅助函数添加到您的项目中(在我的例子中是helpers.php ):
if (! function_exists('check_auth')) {
    function check_auth(): bool
    {
        if (! isset($_SESSION['user_id'])) {
            return false;
        }

        if (! file_exists('current_user.txt') || filesize('current_user.txt') === 0) {
            return true;
        }

        $trace = json_decode(file_get_contents('current_user.txt'));

        // You can write your own logic here.
        return (int) $trace->user_id === $_SESSION['user_id'] && (new DateTime($trace->created_at))->modify('+12 hours') > new Datetime('now');
    }
}

if (! function_exists('logout'))
{
    function logout()
    {
        if (isset($_SESSION['user_id'])) {
            $trace = json_decode(file_get_contents('current_user.txt'));

            if ((int) $trace->user_id === $_SESSION['user_id']) {
                file_put_contents('current_user.txt', '');
            }

            unset($_SESSION['user_id']);
        }
    }
}

if (! function_exists('redirect')) {
    function redirect(string $url, int $status_code = 303): void
    {
        header('Location: ' . $url, true, $status_code);
        die();
    }
}
  1. Create a login page ( login.php in my case):创建一个登录页面(在我的例子中是login.php ):
<?php

declare(strict_types=1);

// Start session.
session_start();

// Include helper functions.
require_once 'helpers.php';

// Redirect user to homepage/dashboard if authenticated.
if (check_auth()) {
    redirect('index.php');
    return;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $pdo = new PDO('mysql:host=[DB_HOST];dbname=[DB_NAME];charset=utf8mb4', '[DB_USERNAME]', '[DB_PASSWORD]', [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ]);
    $stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
    $stmt->execute([$_POST['email']]);
    $user = $stmt->fetch();

    if (! ($user && password_verify($_POST['password'], $user->password))) {
        echo json_encode([
            'success' => false,
            'message' => 'These credentials don\'t match our records.',
        ]);
        return;
    }

    // Log user in if another is not authenticated.
    if (filesize('current_user.txt') === 0) {
        file_put_contents('current_user.txt', json_encode([
            'user_id'    => $user->id,
            'created_at' => (new DateTime('now'))->format('Y-m-d H:i:s'),
        ]));

        $_SESSION['user_id'] = $user->id;

        echo json_encode([
            'success' => true,
        ]);

        return;
    }

    $trace = json_decode(file_get_contents('current_user.txt'));

    // Log user in if the last authenticated user is himself/herself.
    if ((int) $trace->user_id === $user->id) {
        $trace->created_at = (new DateTime('now'))->format('Y-m-d H:i:s');

        file_put_contents('current_user.txt', json_encode($trace));

        $_SESSION['user_id'] = $user->id;

        echo json_encode([
            'success' => true,
        ]);

        return;
    }

    // Ask user if he/she wants to take over.
    echo json_encode([
        'success'  => false,
        'takeover' => true,
        'message'  => 'Another user is logged in. Do you want to take over?',
    ]);

    return;
}

?>

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Login</title>
</head>
<body>
    <form method="post" id="form">
        <div>
            <label for="email">Email:</label>
            <input type="email" id="email" name="email" placeholder="Email" required>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" placeholder="Password">
        </div>
        <div>
            <span id="message" style="color: red;"></span>
        </div>
        <button>Log in</button>
    </form>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>
        $(function () {
            $('#form').submit(function (e) {
                e.preventDefault();
                $('#message').text('');

                $.post('login.php', $(this).serialize(), function (response) {
                    const res = JSON.parse(response);

                    if (res.takeover) {
                        // Ask user if he/she wants to take over. If user confirms, run `confirmed()` function.
                        confirm(res.message) && confirmed();
                        return;
                    }

                    if (res.success) {
                        // Login is successful. Reload or redirect user to another page.
                        location.reload();
                    } else {
                        // Login failed. Incorrect email or password entered.
                        $('#message').text(res.message || '');
                    }
                });
            });

            function confirmed() {
                $.post('confirmed.php', function (response) {
                    const res = JSON.parse(response);
                    console.log(res.data);
                });
            }
        });
    </script>
</body>
</html>
  1. Check if another user took over currently authenticated user in your pages ( index.php in my case):检查另一个用户是否接管了您页面中当前经过身份验证的用户(在我的情况下为index.php ):
<?php

declare(strict_types=1);

// Start session.
session_start();

// Include helper functions.
require_once 'helpers.php';

?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Home</title>
</head>
<body>
<?php if (check_auth()): ?>
    Welcome friend.
<?php else: ?>
    <a href="/login.php">Log in</a>
<?php endif; ?>

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
    $(function () {
        // Check if another user took over currently authenticated user in every 3 seconds.
        setInterval(function () {
            $.post('check.php', function (response) {
                let res = JSON.parse(response);
                if (! res.auth && res.redirect) {
                    location.replace(res.redirect);
                }
            });
        }, 3000);
    });
</script>
</body>
</html>
  1. Implement your check logic ( check.php in my case):实现你的检查逻辑(在我的例子中是check.php ):
<?php

declare(strict_types=1);

// Start session.
session_start();

// Include helper functions.
require_once 'helpers.php';

if (! check_auth()) {
    logout();

    echo json_encode([
        'auth'     => false,
        'redirect' => 'login.php',
    ]);

    return;
}

echo json_encode([
    'auth' => true,
]);

  1. Finally, create your action/function for the case when user confirms to take over ( confirmed.php in my case):最后,创建了情况下,你的动作/功能,当用户确认接管( confirmed.php在我的情况):
<?php

declare(strict_types=1);

// Start session.
session_start();

// Include helper functions.
require_once 'helpers.php';

/**
 * Run your action here if user confirms to take over another user.
 */
echo json_encode([
    'data' => 'User confirmed to take over another user.',
]);

Tested and works fine.经测试,工作正常。 But you should customize it for your needs.但是你应该根据你的需要定制它。

Here the basic concept.这里是基本概念。

  • You need a central storage where the current active user active_user_id and last_updated is stored (database/file/memcache/redis whatever you want)您需要一个中央存储,其中存储当前活动用户active_user_idlast_updated (数据库/文件/内存缓存/redis 任何你想要的)
  • You need to poll the current active user for each session - if the current user is not the active user he will logged out and notified, so he knows someone else took over.您需要为每个会话轮询当前活动用户 - 如果当前用户不是活动用户,他将注销并通知,因此他知道其他人接管了。

Flow流动

  • User loggs in用户登录
    • $_SESSION['user_id'] = user_id
    • IF: $_SESSION['user_id'] !== active_user_id (central storage - see above) AND last_updated < 10s如果: $_SESSION['user_id'] !== active_user_id (中央存储 - 见上文)和last_updated < 10s
      • TRUE: log in, update active_user_id to $_SESSION['user_id'] ; TRUE:登录,将active_user_id更新为$_SESSION['user_id'] update last_updated to now;last_updated更新为现在; redirect to main-page重定向到主页
      • FALSE: show popup "Take over?"错误:显示弹出窗口“接管?” -> ok: same as TRUE from above, abort: close popup -> ok:与上面的 TRUE 相同,中止:关闭弹出窗口
  • While logged-in call check-active.php every 5 seconds登录时每 5 秒调用一次check-active.php

check-active.php (pseudocode): check-active.php (伪代码):

  • IF: user_id from $_SESSION['user_id'] === active_user_id from storage如果:来自$_SESSION['user_id'] === active_user_id来自storage $_SESSION['user_id']
    • TRUE: update last_updated in storage ; TRUE:更新storage last_updated return 'ok';返回“确定”;
    • FALSE: call session_destroy();错误:调用session_destroy(); return 'failed';返回“失败”;

frontend pseudocode (logged in): frontend伪代码(已登录):

  • call check-active.php every 5 seconds每 5 秒调用一次check-active.php
  • handle result处理结果
  • IF: result === 'ok'如果:结果 === 'ok'
    • TRUE: do nothing真:什么都不做
    • FALSE: redirect to main page like 'main.php?message=' .错误:重定向到主页,如 'main.php?message=' 。 urlencode('You got replaced') urlencode('你被替换了')

Why check for last_updated > 10s?为什么要检查last_updated > 10s?

Because someone logged in could just close the browser, so we dont know if the session is still active or not.因为有人登录可以关闭浏览器,所以我们不知道会话是否仍然处于活动状态。 So we check last_updated (which will be updated every 5 seconds as long as the browser is still open).所以我们检查last_updated (只要浏览器仍然打开,它就会每 5 秒更新一次)。 If last_updated is > 10s we consider it as "noone is currently active" so we dont have to ask to take over.如果last_updated大于 10 秒,我们会将其视为“当前没有人处于活动状态”,因此我们不必要求接管。


Working example工作示例

Open this - hit "run" (if not running).打开这个- 点击“运行”(如果没有运行)。

Then open this twice.然后打开两次。 One in a incognito tab, to get a secondary session to kick yourself out.一个在隐身标签中,以获得第二个会话来踢自己。

Disclaimer: This is absolutely experimental.免责声明:这绝对是实验性的。

This Sort Answer is Possible .这种排序答案是Possible

You can do with JavaScript and jQuery .您可以使用JavaScriptjQuery

use setInterval userA and userB common users login check php使用setInterval userAuserB普通用户登录检查php

setInterval(function() {
    // codes here
},5000); // for 5 seconds

then confirmation from user when click function然后在点击功能时得到用户的确认

$('#submit').on('click', function()

with confirm call $.ajax function带有confirm调用$.ajax函数

if(confirm("Are you sure ?")) {
    // $.ajax codes here
}return false;

userB try login setInterval send 20 seconds wait for response. userB尝试登录setInterval发送 20 秒等待响应。

after 20 seconds that userA ip is set logout. 20 秒后, userA ip 设置为注销。

setInterval userA received "logout" then call logout php. setInterval userA收到“注销”然后调用注销 php。

it is basic ip , user and logged information in check php with database.它是基本的ip用户登录信息在检查 php 与数据库。

i just placed which function used for this?我刚刚放置了用于此的哪个函数? not full code.不是完整的代码。

Note: code below is untested but should give you a basic idea of the way to go.注意:下面的代码未经测试,但应该可以让您对要走的路有一个基本的了解。

First of all, you should only be revoking write access from someone who currently has write access, so your first sql should be:首先,您应该只撤销当前具有写访问权限的人的写访问权限,因此您的第一个 sql 应该是:

$sql = "SELECT * FROM trace_users where open='true' && write_access = '1'";

Secondly, since you already only selecting users who have 'open' == "true" , then checking again if($row['open'] == "true") { is redundant.其次,由于您已经只选择了具有'open' == "true" ,然后再次检查if($row['open'] == "true") {是多余的。

Thirdly, you should put the user name into the session for later manipulation and retrieval of logged-in user data.第三,您应该将用户名放入会话中,以便以后操作和检索登录的用户数据。

Fourthly, you are executing the same query twice consecutively in the code below, so instead of:第四,您在下面的代码中连续两次执行相同的查询,而不是:

if($result1 = mysqli_query($connect, $sql))

just put:只是放:

if($result1)

Now for a solution to your problem:现在来解决您的问题:

To avoid passing the name and password back and forth for a second login attempt after confirmation, we can use a token.为了避免在确认后第二次登录尝试来回传递名称和密码,我们可以使用令牌。 Also, at that point I would like to save the user name as I'm going to be using it so at line A put:另外,那时我想保存用户名,因为我将要使用它,所以在 A 行输入:

$_SESSION['login_token'] = sha1(time());
$_SESSION['user_name'] = $username;

and we have to have a way of returning that token to the client and then back to the server so somewhere in your script you could have:并且我们必须有一种方法将该令牌返回给客户端,然后返回到服务器,以便在脚本中的某处您可以拥有:

if (isset($_SESSION['login_token']) && $_SESSION['login_token']) {
?>
<form id="confirm_form" action="login_script.php" method="POST">
    <input type="hidden" name="login_token" value="<?= $_SESSION['login_token'] ?>">
</form>
<script>
// And the popup:
if (confirm('<?= addcslashes($message, "'/") ?>')) {
    document.getElementById('confirm_form').submit();
}
</script>
<?php
}

We also want the PHP script above to handle the session login which will also disconnect the other user so we will add:我们还希望上面的 PHP 脚本处理会话登录,这也会断开其他用户的连接,因此我们将添加:

if (isset($_POST['login_token'], $_SESSION['login_token']) && $_POST['login_token'] === $_SESSION['login_token']) {
    // block access to any write_access user
    // I am going to make an assumption here - that your write_access column can take the value "-1"
    // I am going to use it as a flag that means that this user needs to be told that his access has been revoked
    mysqli_query($connect, "UPDATE trace_users SET write_access = '-1' where open='true'");

    $_SESSION['pageadmin'] = true;
    $_SESSION['login_token'] = null;
    $open = "true";
    $read_access = "1";
    $write_access = "1";
    $stmt = $connect->prepare("UPDATE trace_users SET open=?, read_access=?, write_access=? WHERE user_name=?");
    $stmt->bind_param('ssss', $open, $read_access, $write_access, $username);
    $stmt->execute();
}

Finally we want a frontend script that checks change in permission: I'm going to use polling + jQuery for this:最后,我们需要一个检查权限更改的前端脚本:我将为此使用轮询 + jQuery:

<script>
setInterval(function() {
    $.get('check_permissions.php', function(data) {
        if (data == '-1') {
            alert('your write access is revoked');
        }
    });
}, 5000);
</script>

and check_permissions.php is:和 check_permissions.php 是:

$stmt = $connect->prepare("SELECT write_access FROM trace_users WHERE user_name = ?");
$stmt->bind_param('s', $_SESSION['user_name']);
$stmt->execute();
$stmt->bind_result($status);
$stmt->fetch();
echo $status;

if ($status == -1) {
    // and update status of this user that he has no write permissions but no longer needs to be warned
    $stmt = $connect->prepare("UPDATE trace_users SET write_access = 0 WHERE user_name = ?");
    $stmt->bind_param('s', $_SESSION['user_name']);
    $stmt->execute();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM