CodeIgniter 3中实现URL显示新闻ID与标题并验证标题一致性的问题求助
Got it! Let's fix this issue. The core problem here is that your current code only validates the news ID, not the title part in the URL. We need to add a check to make sure the URL's title matches the actual news title (converted to a URL-friendly "slug" format). Here's how to do it step by step:
1. Fix the News Controller Logic
First, let's clean up your controller code and add the slug validation. I'll adjust variable names for readability and add the key check:
defined('BASEPATH') OR exit('No direct script access allowed!'); class News extends CI_Controller { public function __construct() { parent::__construct(); } // Helper method to generate URL-friendly slugs from titles private function generate_slug($title) { // Convert to lowercase $slug = strtolower($title); // Replace spaces with hyphens $slug = str_replace(' ', '-', $slug); // Remove any non-alphanumeric/non-hyphen characters $slug = preg_replace('/[^a-z0-9-]/', '', $slug); // Replace multiple hyphens with a single one $slug = preg_replace('/-+/', '-', $slug); // Trim hyphens from start/end return trim($slug, '-'); } public function index($newsId = null, $newsTitle = null) { // Return 404 if either ID or title is missing if ($newsId == null || $newsTitle == null) { $this->load->view('errors/html/error_404.php'); return; } $this->load->model('NewsM'); // Fetch the news item by ID $news = $this->NewsM->getBy('id', $newsId); // Return 404 if no news found with this ID if (!$news) { $this->load->view('errors/html/error_404.php'); return; } // Return 404 if the news is inactive if ($news['newsActive'] == 0) { $this->load->view('errors/html/error_404.php'); return; } // Generate the correct slug from the actual news title $correct_slug = $this->generate_slug($news['title']); // Compare URL slug with correct slug; return 404 if mismatch if ($correct_slug !== $newsTitle) { $this->load->view('errors/html/error_404.php'); return; } /** Header Section */ $headerD['settings'] = $this->SettingsM->getSettings(); $headerD['pageTitle'] = $headerD['settings']['pageTitle'] . " | News | " . $news['title']; $this->load->view('components/Header', $headerD); /** Main Content Section */ // Pass the single news item to the view (not all news!) $bodyD['news'] = $news; $this->load->view('News', $bodyD); } }
Key Changes Explained:
- Parameter Check: Changed
&&to||in the initial check — if either ID or title is missing, we return 404 immediately. - Slug Generation: Added a private
generate_slugmethod to convert the actual news title into the same URL-friendly format used in your URLs (lowercase, hyphens instead of spaces, no special characters). - Slug Validation: After fetching the news item, we generate the correct slug and compare it to the
$newsTitlefrom the URL. If they don't match, return 404. - View Data Fix: Updated the main content section to pass only the current news item to the view (your original code was using
getAll()which returns all news, which is probably not intended).
2. Verify Your Route Configuration
Your existing route is already correct, so no changes needed here:
$route['news/(:num)-(:any)'] = 'news/index/$1/$2';
This correctly captures the numeric ID and the title slug from the URL and passes them to your controller's index method.
3. Testing the Fix
- If your news title is "Lorem Ipsum", the generated slug will be
lorem-ipsum. Only URLs likehttps://example.com/news/1-lorem-ipsumwill load the news. - Any URL with the correct ID but wrong title (e.g.,
https://example.com/news/1-wrong-title) will now return a 404 error, which is exactly what you want.
Optional: Move Slug Generation to a Helper
For reusability across your application, you can move the generate_slug method to a custom helper:
- Create
application/helpers/slug_helper.php - Add the function (remove the
privatekeyword):function generate_slug($title) { // Same slug logic as above } - Load the helper in your controller's constructor:
public function __construct() { parent::__construct(); $this->load->helper('slug'); } - Then use it in your controller like:
$correct_slug = generate_slug($news['title']);
内容的提问来源于stack exchange,提问作者ravenekse

