从Twig调用Symfony控制器方法时遇到问题
Hey there! Let's dig into your Symfony CSV generation issue—your code has a few syntax gaps and best practice tweaks that are likely causing the trouble. Let's fix this step by step.
First, let's list the key issues in your original code:
- Missing semicolons on database connection and query lines (PHP will throw a parse error here)
- A syntax mistake in the
setCallbackclosure (extra closing parenthesis) - No loop to write your database results into the CSV file (so your output would be empty)
- Hardcoded file path that's not aligned with Symfony's directory conventions
- No proper response headers to trigger a download in the browser
Here's the corrected and improved version of your controller action:
<?php namespace CampaignBundle\Controller; // For Symfony 3.x, use Controller; for Symfony 4+, use AbstractController instead use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\StreamedResponse; class CsvController extends AbstractController { public function generateCsvAction() { // Fix missing semicolons and get database connection $conn = $this->get('database_connection'); $results = $conn->query("SELECT * FROM external_attribute;"); $response = new StreamedResponse(); $response->setCallback(function() use($results) { // Use Symfony's kernel to get project root (avoids hardcoded paths) $projectRoot = $this->getParameter('kernel.project_dir'); // Store generated CSV in var/ directory (Symfony-standard writable location) $filePath = $projectRoot . '/var/external_attributes.csv'; // Open file handle with error checking $handle = fopen($filePath, "w+"); if (!$handle) { throw new \RuntimeException('Failed to open CSV file for writing'); } // Write CSV header row (match your actual database column names here) $csvHeaders = ['ID', 'Attribute Name', 'Attribute Value']; fputcsv($handle, $csvHeaders); // Loop through database results and write each row to CSV while ($row = $results->fetch(\PDO::FETCH_ASSOC)) { fputcsv($handle, [ $row['id'], $row['name'], // Replace with your actual column names $row['value'] ]); } // Clean up: close the file handle fclose($handle); }); // Set headers to tell browser this is a downloadable CSV $response->headers->set('Content-Type', 'text/csv'); $response->headers->set( 'Content-Disposition', 'attachment; filename="external_attributes.csv"' ); return $response; } }
Key Fixes & Notes:
- Syntax Corrections: Added missing semicolons and fixed the closure's parenthesis mistake—these were immediate showstoppers for your code running.
- Path Best Practice: Used
kernel.project_dirto get your project's root instead of hardcoding a local path. This works across environments (local, staging, production) and uses Symfony's standard writablevar/directory. - Result Loop: Added a
whileloop to iterate over your database results and write each row to the CSV—without this, your file would only have (if any) the header row. - Response Headers: Set proper
Content-TypeandContent-Dispositionheaders so the browser recognizes the response as a downloadable CSV file, instead of trying to display it as text. - Symfony 4+ Compatibility: Switched to
AbstractController(the recommended base controller for newer Symfony versions)—if you're on Symfony 3.x, just swap it back toController.
One extra tip: If you're using Doctrine ORM (instead of raw DBAL queries), you could clean this up further by using a repository to fetch your entities, then map them to CSV rows—this is more aligned with Symfony's object-oriented approach.
内容的提问来源于stack exchange,提问作者Basile Mauvieux
相关产品推荐
相关产品推荐

