[英]How to make a button execute a php script?
如何使 html 按钮执行 php 脚本?
我正在开发一个只有一个用户可以登录的登录系统,每当其他用户尝试登录时,它应该给他们一个警告弹出消息,说another user is already logged in - Do you want to take over from them?
userA
已经登录并且userB
尝试登录,那么它应该显示在弹出窗口中,因为userA is already logged in, do you want to take over?
.userA
,我们将取消写入权限并向他们显示另一个弹出消息,表明您的写入权限已被撤销。 第二点我可以稍后处理,但现在我专注于做第一点。 以下是我试图在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";
}
}
我想完成以下任务,但我对如何实现感到困惑-
LINE A
,我想显示一个弹出消息,说"Previous user is logged in. Do you want to take over?"
与确定和取消按钮。Ok
按钮,然后我想在 php 中执行某些代码,假设现在打印hello world
,如果我点击弹出消息上的cancel
按钮,那么我不想做任何事情。简而言之,我想实现两件事:
1.在 A 行创建一个带有 Ok 和 Cancel 按钮的弹出消息。
2.单击“确定”按钮,我想执行 php 脚本,单击“取消”按钮,我不想发生任何事情。
.txt
文件中:json_encode(['user_id' => 1, 'created_at' => (new DateTime('now'))->format('Y-m-d H:i:s')]);
user_id
和created_at
字段。user_id
字段与尝试登录的用户的id
相同并且created_at
字段不早于 12 小时前(或您的自定义逻辑),则只需更新文件中的created_at
字段并登录用户在。user_id
字段与尝试登录但已超过 12 小时(或您的自定义逻辑)的用户的id
相同,则询问用户他/她是否想接管另一个用户。user_id
场不一样的id
谁登录尝试询问用户是否他/她想要接管其他用户的用户。.txt
文件。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();
}
}
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>
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>
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,
]);
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.',
]);
经测试,工作正常。 但是你应该根据你的需要定制它。
这里是基本概念。
active_user_id
和last_updated
(数据库/文件/内存缓存/redis 任何你想要的)流动
$_SESSION['user_id'] = user_id
$_SESSION['user_id']
!== active_user_id
(中央存储 - 见上文)和last_updated
< 10s
active_user_id
更新为$_SESSION['user_id']
; 将last_updated
更新为现在; 重定向到主页check-active.php
check-active.php
(伪代码):
$_SESSION['user_id']
=== active_user_id
来自storage
$_SESSION['user_id']
storage
last_updated
; 返回“确定”;session_destroy();
返回“失败”; frontend
伪代码(已登录):
check-active.php
为什么要检查
last_updated
> 10s?
因为有人登录可以关闭浏览器,所以我们不知道会话是否仍然处于活动状态。 所以我们检查last_updated
(只要浏览器仍然打开,它就会每 5 秒更新一次)。 如果last_updated
大于 10 秒,我们会将其视为“当前没有人处于活动状态”,因此我们不必要求接管。
打开这个- 点击“运行”(如果没有运行)。
然后打开此两次。 一个在隐身标签中,以获得第二个会话来踢自己。
免责声明:这绝对是实验性的。
这种排序答案是Possible
。
您可以使用JavaScript
和jQuery
。
使用setInterval
userA和userB普通用户登录检查php
setInterval(function() {
// codes here
},5000); // for 5 seconds
然后在点击功能时得到用户的确认
$('#submit').on('click', function()
带有confirm
调用$.ajax
函数
if(confirm("Are you sure ?")) {
// $.ajax codes here
}return false;
userB尝试登录setInterval
发送 20 秒等待响应。
20 秒后, userA ip 设置为注销。
setInterval
userA收到“注销”然后调用注销 php。
它是基本的ip ,用户和登录信息在检查 php 与数据库。
我刚刚放置了用于此的哪个函数? 不是完整的代码。
注意:下面的代码未经测试,但应该可以让您对要走的路有一个基本的了解。
首先,您应该只撤销当前具有写访问权限的人的写访问权限,因此您的第一个 sql 应该是:
$sql = "SELECT * FROM trace_users where open='true' && write_access = '1'";
其次,由于您已经只选择了具有'open' == "true"
,然后再次检查if($row['open'] == "true") {
是多余的。
第三,您应该将用户名放入会话中,以便以后操作和检索登录的用户数据。
第四,您在下面的代码中连续两次执行相同的查询,而不是:
if($result1 = mysqli_query($connect, $sql))
只是放:
if($result1)
现在来解决您的问题:
为了避免在确认后第二次登录尝试来回传递名称和密码,我们可以使用令牌。 另外,那时我想保存用户名,因为我将要使用它,所以在 A 行输入:
$_SESSION['login_token'] = sha1(time());
$_SESSION['user_name'] = $username;
并且我们必须有一种方法将该令牌返回给客户端,然后返回到服务器,以便在脚本中的某处您可以拥有:
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
}
我们还希望上面的 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();
}
最后,我们需要一个检查权限更改的前端脚本:我将为此使用轮询 + jQuery:
<script>
setInterval(function() {
$.get('check_permissions.php', function(data) {
if (data == '-1') {
alert('your write access is revoked');
}
});
}, 5000);
</script>
和 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.