[英]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.