You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter 3中实现URL显示新闻ID与标题并验证标题一致性的问题求助

Solution for Matching News Title in URL

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_slug method 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 $newsTitle from 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 like https://example.com/news/1-lorem-ipsum will 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:

  1. Create application/helpers/slug_helper.php
  2. Add the function (remove the private keyword):
    function generate_slug($title) {
        // Same slug logic as above
    }
    
  3. Load the helper in your controller's constructor:
    public function __construct() {
        parent::__construct();
        $this->load->helper('slug');
    }
    
  4. Then use it in your controller like: $correct_slug = generate_slug($news['title']);

内容的提问来源于stack exchange,提问作者ravenekse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 03:32:27