【问题标题】:Direct link to a subfolder view returns 404直接链接到子文件夹视图返回 404
【发布时间】:2026-01-24 19:55:02
【问题描述】:

我无法通过直接链接直接加载 CodeIgniter views 文件夹的子文件夹中的视图。

这是文件夹结构:

my_project/
    application/
        views/
            pages/
                about.php
                about/
                    organization.php
                    history.php

我需要通过以下链接访问organization.phphistory.php

<div id="container">
    <ul>
        <li>
            <a href='<?php echo base_url('about'); ?>'>About</a>
        </li>
        <li>
            <a href='<?php echo base_url('about/organization'); ?>'>About/Organization</a>
        </li>
        <li>
            <a href='<?php echo base_url('about/history'); ?>'>About/History</a>
        </li>
    </ul>
</div>

但是我得到了 404。

我的htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /my_project/

# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /my_project/$1$2 [R=301,NE,L]

# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /my_project/index.php/$1 [L]
</IfModule>

这是我的routes.php,它指向我的默认视图控制器Pages::view(path/to/file)

$route['default_controller'] = 'welcome';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;

$route['pages/(:any)/(:any)'] = 'pages/view/$1/$2';
$route['(:any)'] = 'pages/view/$1';

这是我的控制器:

<?php
class Pages extends CI_Controller
{
    function __construct()
    {
        parent::__construct();
    }

    public function view($page = 'home')
    {
        if(!file_exists(APPPATH.'views/pages/'.$page.'.php'))
        {
            show_404();
        }

        $data['title'] = strtoupper(str_replace(["-", "–"], ' ', $page));
        $this->load->view('templates/header', $data);
        $this->load->view('pages/'.$page, $data);
        $this->load->view('templates/footer', $data);
    }
}

注意每当我直接使用时

$this->load->view('pages/views/about/organization');

没关系。与打印相同:

file_exists(APPPATH.'views/pages/about/organization.php');

我不知道是什么搞砸了。

我必须为这些子文件夹制作自定义控制器吗?这是我目前能想到的唯一解决方案。


注意我还将这个子文件夹(实际上是整个项目的)权限设置为777,但直接链接仍然不起作用。


注意我现在唯一的解决方案是为每个子文件夹制作单独的控制器,以便查看它们!这真的不可能只用一个控制器吗?

就像 url 模式 my_app/controller/method 是严格的,my_app/folder/view 是不允许的,除非 folderview 分别对应于 controllermethod


解决方案

Zeeshandidthat!

珊蒂,你留下来! Thank you

你是对的,我想要一个通用方法来捕获我所有的静态页面查看请求。我们现在可以关闭这个问题(我将在 20 小时内奖励赏金)。

You were the only one who understood the assignment.

【问题讨论】:

  • 伙计们,我不想为这些子文件夹中的每一个创建多个控制器,请帮助我在心里知道,这可以通过这个控制器实现,也许是我的htaccess???
  • 你的 routes.php 文件写得不好。再次阅读this保留的路由必须位于任何通配符或正则表达式路由之前。 而且路由将按照它们定义的顺序运行。较高的路线总是优先于较低的路线。 这意味着如果您有$route['(:any)'] = 'something/here',它必须位于文件的最后一行。
  • @Tpojka:我听从了你的建议,仍然没有改变。 I get a 404 for the subfolder view

标签: php .htaccess codeigniter view subdirectory


【解决方案1】:

在完成您的问题后,我发现您正在尝试编写一些通用函数来负责加载您的视图。请参考以下内容,因为您可以处理 codeigniter 中的任何结构。

控制器功能会这样

public function view($folder='',$page = 'home')
{       
    $path = $folder!=""?$folder.'/':'';
    $path = $page!=""?$path.$page:$page;

    $this->load->view('templates/header', $data);
    **$this->load->view($path, $data);**
    $this->load->view('templates/footer', $data);
}

现在,在您看来,链接将如下所示:

<div id="container">
<ul>
    <li>
        <a href='<?php echo base_url."about/"; ?>'>About</a>
    </li>
    <li>
        <a href='<?php echo base_url."about/organization" ?>'>About/Organization</a>
    </li>
    <li>
        <a href='<?php echo base_url."about/history" ?>'>About/History</a>
    </li>
</ul>

另外请注意在 Codeigniter 中您不需要手动处理 404。只需添加以下内容即可显示您的自定义

$route['404_override'] = 'mycustom404';//mycustom404 is controller for 404

如果您有任何疑问或疑问,请告诉我。

问候, 泽山。

【讨论】:

  • 谢谢谢谢谢谢谢谢谢谢谢谢这正是我想要的,但无法用语言表达谢谢!!!
  • 欢迎好友...很荣幸分享您的知识。随时提出您的疑问或疑问。
【解决方案2】:

我认为 CodeIgniter 的 URI 模式严格来说是 controller/method,而不喜欢 subfolder/view_file

我刚刚使用organizationhistory 方法为About 制作了一个控制器,它们将显示页面。

<?php
class About extends CI_Controller
{
    function __construct()
    {
        parent::__construct();
        $this->load->helper('url');
    }

    function organization($page = 'organization')
    {
        if(!file_exists(APPPATH.'views/pages/about/'.$page.'.php'))
        {
            show_404();
        }

        $data['title'] = strtoupper(str_replace(["-", "–"], ' ', $page));
        $this->load->view('templates/header', $data);
        $this->load->view('pages/about/'.$page, $data);
        $this->load->view('templates/footer', $data);
    }

    function history($page = 'history')
    {
        if(!file_exists(APPPATH.'views/pages/about/'.$page.'.php'))
        {
            show_404();
        }

        $data['title'] = strtoupper(str_replace(["-", "–"], ' ', $page));
        $this->load->view('templates/header', $data);
        $this->load->view('pages/about/'.$page, $data);
        $this->load->view('templates/footer', $data);
    }
}

I will probably do this for Contact Us, FAQs...

Apparently this is the correct answer。使用控制器和方法以subfolder/view 的形式显示页面。假发。

【讨论】:

    【解决方案3】:

    我将Pages::view() 修改为没有默认参数:

    <?php
    class Pages extends CI_Controller
    {
        function __construct()
        {
            parent::__construct();
        }
    
        public function view()
        {
            $page = $this->uri->segment(1);
            if(!empty($this->uri->segment(2))) {
                $page .= '/'.$this->uri->segment(2);
            }
    
            if(!file_exists(APPPATH.'views/pages/'.$page.'.php'))
            {
                show_404();
            }
    
            $data = "";
            $this->load->view('templates/header', $data);
            $this->load->view('pages/'.$page, $data);
            $this->load->view('templates/footer', $data);
        }
    }
    

    到目前为止,我网站中的页面只有一级子文件夹,因此我对以下内容进行了硬编码:

    $page = $this->uri->segment(1);
    if(!empty($this->uri->segment(2))) {
        $page .= '/'.$this->uri->segment(2);
    }
    

    给定我的链接http://localhost:8080/practice/item-2/subitem-2,URI 段的值如下:

    $this->uri->segment(1) == 'item-2'
    $this->uri->segment(2) == 'subitem-1'
    

    我也用硬编码的捕手更新了routes.php

    $route['default_controller'] = 'welcome';
    $route['404_override'] = '';
    $route['translate_uri_dashes'] = FALSE;
    
    $route['pages/(:any)'] = 'pages/view/$1';
    $route['pages/(:any)/(:any)'] = 'pages/view/$1/$2';
    $route['pages/view/(:any)'] = 'pages/view/$1';
    $route['pages/view/(:any)/(:any)'] = 'pages/view/$1/$2';
    $route['(:any)'] = 'pages/view/$1';
    $route['(:any)/(:any)'] = 'pages/view/$1/$2';
    

    【讨论】: