Symfony PHP:如何为Twig模板中的按钮创建处理控制器?
Alright, let's walk through how to handle that Add button interaction in Symfony. Since you’re using a plain <input type="button"> (not a submit button), we’ll need a bit of frontend JavaScript to trigger a request to your backend, plus a Symfony controller to process that request and send a response.
First, we need to listen for the button's click event and send an HTTP request to your Symfony app. You can add this directly in your Twig template (or a dedicated JS file for better organization):
{# Your existing Twig template #} <input type="button" id="addLink" value="Add"> <script> document.getElementById('addLink').addEventListener('click', async function() { try { // Send a POST request to our controller route const response = await fetch('{{ path('add_link') }}', { method: 'POST', headers: { 'Content-Type': 'application/json', // Include CSRF token for security (Symfony requires this for POST requests) 'X-CSRF-Token': '{{ csrf_token("add_link_action") }}' }, // Optional: Send data to the controller (e.g., form inputs) // body: JSON.stringify({ url: document.getElementById('linkUrl').value }) }); if (!response.ok) { throw new Error('Request failed'); } // Parse the JSON response from the controller const result = await response.json(); // Update the UI to show success (e.g., add a new row, show a message) console.log('Action successful:', result); alert('Link added successfully!'); } catch (error) { console.error('Error:', error); alert('Oops, something went wrong.'); } }); </script>
Next, let's build the controller that will handle the request. You can generate a controller quickly with Symfony's console command:
php bin/console make:controller AddLinkController
Then replace the generated code with something like this:
// src/Controller/AddLinkController.php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; class AddLinkController extends AbstractController { /** * @Route("/add-link", name="add_link", methods={"POST"}) */ public function handleAddAction(Request $request): JsonResponse { // Validate the CSRF token first (critical for security!) $this->isCsrfTokenValid('add_link_action', $request->headers->get('X-CSRF-Token')); // If you sent JSON data from the frontend, parse it here // $requestData = json_decode($request->getContent(), true); // Perform your business logic here: // - Save a new link to the database // - Validate input data // - Trigger any necessary services // Example database operation (uncomment if needed): // $entityManager = $this->getDoctrine()->getManager(); // $link = new \App\Entity\Link(); // $link->setUrl($requestData['url']); // $entityManager->persist($link); // $entityManager->flush(); // Return a JSON response back to the frontend return $this->json([ 'success' => true, 'message' => 'Link added successfully', // Optional: Send data back to the frontend (e.g., the new link ID) // 'linkId' => $link->getId() ]); } }
- CSRF Protection: Never skip the CSRF token check! Symfony requires this for POST requests to prevent cross-site request forgery attacks. We included the token in the request headers in our JS code.
- Request Methods: The route is restricted to
POSTmethods, which is the right choice for an action that modifies data (like adding a link). - Response Type: We’re using
JsonResponsebecause we’re communicating via AJAX, but if you wanted to redirect the user instead (less common for this type of button), you could use$this->redirectToRoute('route_name'). - Alternative: Using Symfony Forms
If you’re working with form fields alongside the button, using Symfony’s form system is a great option (it handles CSRF automatically). You’d wrap the button in a form and handle submission in the controller like this:
Then your controller would process the form submission normally.{{ form_start(addLinkForm) }} {# Add form fields here #} {{ form_widget(addLinkForm.submit, {'label': 'Add'}) }} {{ form_end(addLinkForm) }}
内容的提问来源于stack exchange,提问作者SDmitrij

