如何在PHP/Laravel中避免函数被重复点击/刷点击?
Hey there! I’ve run into similar problems with clickable action links before—users double-clicking or spamming buttons can definitely cause unexpected bugs. Let’s go through a few practical solutions to stop this from happening, combining both frontend and backend safeguards since relying on just one isn’t enough.
Frontend: Prevent Immediate Re-Clicks
First, let’s add some JavaScript to give users instant feedback and block repeated clicks right when they interact with the link. This improves the user experience too, since they’ll see that their action is being processed.
Add a class to your links (like item-action) so we can target them easily:
if($idd->is_active == 0){ echo "<a href='/item/activate/" . $s . "' class='item-action'>Aktifleştir</a>"; } elseif($idd->is_active == 1){ echo '<a href="/item/de-activate/' . $s . '" class="item-action">Pasifleştir</a>'; }
Then add this JavaScript to your page:
document.querySelectorAll('.item-action').forEach(link => { link.addEventListener('click', function() { // Disable the link so it can't be clicked again this.style.pointerEvents = 'none'; // Change the text to show the action is in progress this.textContent = 'İşlem Yapılıyor...'; // Optional: Add a loading spinner if you have one this.innerHTML = '<span class="spinner"></span> İşlem Yapılıyor...'; }); });
This way, once the user clicks the link, it becomes unclickable and shows a loading state—no more accidental repeats.
Backend: Add Idempotency Checks (Critical!)
Frontend safeguards can be bypassed (e.g., if someone uses browser dev tools), so we need to add validation on the backend to ensure the action only runs when it makes sense.
For your activation endpoint (/item/activate/$s):
// Fetch the current item from the database first $item = // Your code to get the item by ID $s; // Only run the activation if the item is currently inactive if($item->is_active == 0) { // Perform your activation logic here (update database, etc.) $item->is_active = 1; $item->save(); // Or your DB update query } else { // The item is already active—do nothing and redirect back header("Location: /path/to/item/page"); exit; }
Do the same for the deactivation endpoint (/item/de-activate/$s):
$item = // Fetch the item by ID $s; if($item->is_active == 1) { $item->is_active = 0; $item->save(); } else { header("Location: /path/to/item/page"); exit; }
This ensures even if a user somehow sends multiple requests, the backend will ignore any that don’t match the item’s current state.
Bonus: One-Time Request Tokens
For an extra layer of security, you can use one-time tokens to prevent duplicate requests entirely. Here’s how:
- Generate a unique token when rendering the page and store it in the session:
$token = uniqid('', true); // Generate a unique token $_SESSION["item_token_$s"] = $token; // Store it linked to the item ID if($idd->is_active == 0){ echo "<a href='/item/activate/" . $s . "?token=" . $token . "' class='item-action'>Aktifleştir</a>"; } elseif($idd->is_active == 1){ echo '<a href="/item/de-activate/' . $s . '?token=' . $token . '" class="item-action">Pasifleştir</a>'; }
- Validate the token in your backend endpoint before processing the action:
$s = $_GET['s']; $token = $_GET['token'] ?? ''; // Check if the token exists in the session and matches if(isset($_SESSION["item_token_$s"]) && $_SESSION["item_token_$s"] === $token) { // Token is valid—remove it so it can't be reused unset($_SESSION["item_token_$s"]); // Now run your activation/deactivation logic (with the idempotency check above!) } else { // Invalid or reused token—redirect back header("Location: /path/to/item/page"); exit; }
This makes sure each action link can only be used once, even if someone tries to copy and re-send the URL.
I’d recommend combining the frontend feedback with the backend idempotency check as your base solution—this covers most cases. The one-time token is great if you want to add extra protection against intentional duplicate requests.
内容的提问来源于stack exchange,提问作者Berke

