如何在新页面展示搜索结果?附邮政编码搜索数据的API代码
Hey there! Let's tackle your two needs: getting those search results to display on a new page, and sprucing up your existing API code. Here's a detailed breakdown:
We’ve got two common approaches depending on whether you want the frontend or backend to handle the heavy lifting:
Approach 1: Frontend-Driven Jump & Render
This works if you want to keep your API focused on data delivery, and let the frontend handle rendering:
- Step 1: Trigger the search from your main page
You can use an HTML form withtarget="_blank"to open results in a new tab automatically:
Or use JavaScript for more control (like validating input before sending):<form action="/search-results" method="GET" target="_blank"> <input type="text" name="pincode" placeholder="Enter PIN Code" required> <button type="submit">Search Vendors</button> </form>document.getElementById('search-btn').addEventListener('click', async () => { const pinCode = document.getElementById('pincode-input').value; // Basic validation if (!pinCode || pinCode.length !== 6) { alert("Please enter a valid 6-digit PIN code!"); return; } // Fetch data from your API const response = await fetch('/api/find-place', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pinCode }) }); const result = await response.json(); // Open new page and pass data const newWindow = window.open('/search-results'); newWindow.onload = () => { newWindow.displayResults(result.data); // Call a render function in the new page }; }); - Step 2: Render results on the new page
Create asearch-results.htmlpage with a container for results, and add a function to display data:function displayResults(vendors) { const container = document.getElementById('results-container'); if (vendors.length === 0) { container.innerHTML = '<p>No vendors found for this PIN code.</p>'; return; } // Generate vendor cards const vendorHTML = vendors.map(vendor => ` <div class="vendor-card"> <img src="${vendor.logo}" alt="${vendor.vendor_name}" class="vendor-logo"> <h3>${vendor.vendor_name}</h3> <p>Phone: ${vendor.phone_no}</p> </div> `).join(''); container.innerHTML = vendorHTML; } // If using the form approach, fetch data from URL params window.onload = async () => { const urlParams = new URLSearchParams(window.location.search); const pinCode = urlParams.get('pincode'); if (pinCode) { const response = await fetch('/api/find-place', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pinCode }) }); const result = await response.json(); displayResults(result.data); } };
Approach 2: Backend-Rendered Results Page
If you’re using a templating engine with Slim (like Twig), you can have the backend fetch data and render the full results page directly:
- Add a new route in your Slim app
$app->get('/search-results', function() use ($app) { $pinCode = $app->request->get('pincode'); // Validate input first if (!$pinCode || !is_numeric($pinCode) || strlen($pinCode) !== 6) { $app->redirect('/search'); // Redirect back to search page if invalid return; } try { $db = getDB(); $sql = "SELECT vendor_name, logo, phone_no FROM vender_list WHERE post_code LIKE :post_code"; $stmt = $db->prepare($sql); // Add wildcards for fuzzy search (adjust if you need exact match) $searchTerm = "%{$pinCode}%"; $stmt->bindParam("post_code", $searchTerm, PDO::PARAM_STR); $stmt->execute(); $vendors = $stmt->fetchAll(PDO::FETCH_ASSOC); // Render Twig template with results echo $app->view->render('search-results.twig', [ 'vendors' => $vendors, 'searchedPin' => $pinCode ]); } catch(PDOException $e) { // Handle database errors gracefully echo $app->view->render('error.twig', ['message' => 'Failed to fetch vendors: ' . $e->getMessage()]); } }); - Create the Twig template (
search-results.twig)
Then just use the same HTML form from Approach 1, and it’ll open the backend-rendered page directly.<!DOCTYPE html> <html> <head> <title>Vendors for {{ searchedPin }}</title> </head> <body> <h1>Vendors Near PIN {{ searchedPin }}</h1> <div id="results-container"> {% if vendors|length == 0 %} <p>No vendors found.</p> {% else %} {% for vendor in vendors %} <div class="vendor-card"> <img src="{{ vendor.logo }}" alt="{{ vendor.vendor_name }}"> <h3>{{ vendor.vendor_name }}</h3> <p>Phone: {{ vendor.phone_no }}</p> </div> {% endfor %} {% endif %} </div> </body> </html>
Looking at your snippet, here are some quick wins to make it more robust:
Fix Fuzzy Search Logic
Your currentLIKE :post_codedoes an exact match. To find vendors with post codes containing the input, add wildcards before binding the parameter:$searchTerm = "%{$pinCode}%"; // Wrap with % for partial matches $stmt->bindParam("post_code", $searchTerm, PDO::PARAM_STR);Never put wildcards directly in the SQL string (like
LIKE '%:post_code%')—that breaks parameter binding and opens you to SQL injection.Add Proper Error Handling
You have atryblock but nocatch. Add error handling to return meaningful JSON responses:try { // ... existing code ... $vendors = $stmt->fetchAll(PDO::FETCH_ASSOC); $app->response->setStatus(200); $app->response->headers->set('Content-Type', 'application/json'); echo json_encode([ 'success' => true, 'data' => $vendors ]); } catch(PDOException $e) { $app->response->setStatus(500); $app->response->headers->set('Content-Type', 'application/json'); echo json_encode([ 'success' => false, 'message' => 'Database error: ' . $e->getMessage() ]); }Validate Input
Make sure the PIN code is valid before hitting the database:$pinCode = json_decode($request->getBody()); // Adjust validation rules based on your country's PIN code format if (!isset($pinCode) || !is_numeric($pinCode) || strlen($pinCode) !== 6) { $app->response->setStatus(400); $app->response->headers->set('Content-Type', 'application/json'); echo json_encode([ 'success' => false, 'message' => 'Invalid PIN code. Please enter a 6-digit number.' ]); return; // Stop execution if input is bad }Clean Up Unused Code
Remove commented-out debug lines likeecho "<pre>"; print_r($stmt); echo"</pre>";die;to avoid clutter in production code.Consistent Naming
Your table is namedvender_list(missing an 'o' in 'vendor')—if that’s a typo, fix the table name. If not, keep variable names consistent (e.g., don’t mixvendorandvender).Use Associative Arrays for JSON
When fetching results, usePDO::FETCH_ASSOCto get key-value pairs (column names as keys) which are cleaner for JSON responses:$vendors = $stmt->fetchAll(PDO::FETCH_ASSOC);
内容的提问来源于stack exchange,提问作者Rudri

