使用 CodeIgniter 加载视图文件夹外的视图
Posted
技术标签:
【中文标题】使用 CodeIgniter 加载视图文件夹外的视图【英文标题】:Loading view outside view folder with CodeIgniter 【发布时间】:2021-04-05 21:27:58 【问题描述】:我需要从以下范围之外加载视图:
$this->load->view();
这似乎适用于base/application/views
目录。如何从/application/
目录外部访问视图?
我想我将不得不扩展CI_Loader class
这是最好的前进方式吗?
我还找到了包含 view_paths 的数组:
// base/system/core/Loader.php
// CI_Loader
/**
* List of paths to load views from
*
* @var array
* @access protected
*/
protected $_ci_view_paths = array();
但是所有声明变量上方的注释让我卡住了
// All these are set automatically. Don't mess with them.
任何关于从这里去哪里的想法将不胜感激:-)
【问题讨论】:
application
文件夹是为您的application
准备的,您为什么要使用 CodeIgniter 应用程序文件夹之外的文件?
这是一个很好的观点,它是位于 application
文件夹之外的第三方资产,我正在尝试整合它的一部分。
那你为什么不整合它呢?它有什么问题?
你可以使用debug_backtrace()
查看,执行了什么。你可以添加它here 看看,在view()
方法之前调用了什么。
@tereško 很棒的回溯,+helpfull 标志
【参考方案1】:
不知道是不是正确的方法,但它有效:)
在您的 application/core
文件夹中放置此加载程序扩展
<?php
class MY_Loader extends CI_Loader
function ext_view($folder, $view, $vars = array(), $return = FALSE)
$this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH . $folder . '/' => TRUE));
return $this->_ci_load(array(
'_ci_view' => $view,
'_ci_vars' => $this->_ci_object_to_array($vars),
'_ci_return' => $return
));
?>
然后你想要一个外部视图文件,假设它在 third_party 文件夹中
application/third_party/my_new_view.php
Hello : <?php echo $my_name; ?>
然后在控制器中调用你的新视图
ext_view 是您的新视图加载器方法,
第一个参数:应用程序内的文件夹 第二个参数:视图名称 第三个参数:变量数据等等...test_controller.php
$view_data = array('my_name' => 'dino');
$this->load->ext_view('third_party', 'my_new_view', $view_data);
如果一切正常。它会输出
你好:恐龙
【讨论】:
请注意,APPPATH 默认为“应用程序”文件夹 如果您希望制作一个看起来比 APPPATH 高一级的产品,我假设您可以添加 doAPPPATH . '../' . $folder . '/'
。
我已经测试过了,事实上你可以做到以上。
@Dino。感谢您提供如此出色的解决方案。无论如何我们可以加载这样的模型(即在“应用程序/模型”文件夹之外)?如果是这样,我们需要做什么?我不确定加载后如何调用模型函数? 【参考方案2】:
Dino's
solution 似乎非常合理,并且确实适用于application
中的文件,但是,我需要更深入的解决方案。我们的 CI 嵌入到主目录的子目录中,例如 ip.ip.ip.ip/dir/sub/application/..
。也许我做错了什么,但我无法让他的解决方案完全符合我的需求,即使在尝试应用类似../../
的东西之后,这仍然不可行;如果我需要更深入地了解未知的后备目录计数怎么办?
因此,我最终编写了自己的解决方案,到目前为止,它似乎工作得很好,尽管它使用了原生 PHP。通过这种方式,它试图抓取您的文件所在的基本目录并加载它们,这与 CI 的加载功能的工作方式几乎相同。
与他的解决方案相同,在 application/core
中创建一个名为 MY_Loader.php
的文件。然后简单地写下(或者如果你想保留他的解决方案,也可以添加方法):
<?php
class MY_Loader extends CI_Loader
public function base_view($view, $vars = array(), $get = FALSE)
// ensures leading /
if ($view[0] != '/') $view = '/' . $view;
// ensures extension
$view .= ((strpos($view, ".", strlen($view)-5) === FALSE) ? '.php' : '');
// replaces \'s with /'s
$view = str_replace('\\', '/', $view);
if (!is_file($view)) if (is_file($_SERVER['DOCUMENT_ROOT'].$view)) $view = ($_SERVER['DOCUMENT_ROOT'].$view);
if (is_file($view))
if (!empty($vars)) extract($vars);
ob_start();
include($view);
$return = ob_get_clean();
if (!$get) echo($return);
return $return;
return show_404($view);
然后,如果您在最里面的根目录中有一个名为“bob.php”的文件,只需调用:
$this->load->base_view('bob');
// OR
$this->load->base_view('bob.php');
// OR if it's extension is .html
$this->load->base_view('bob.html');
如果它位于根目录的另一个目录中:
$this->load->base_view('directory/bob');
// OR
$this->load->base_view('directory\bob.htm');
或者随便你,只要你调用真实目录中的真实文件!
希望这个替代解决方案可以帮助遇到类似危险的人。
【讨论】:
这是一个很好的解决方案,但是你不能在那个部分传递 var 表单控制器??【参考方案3】:要自定义 'application'
文件夹之外的模型和视图,请按照以下简单步骤操作,
在'application/core'
目录下创建My_Loader.php
文件
将代码复制到自定义的My_Loader.php
class MY_Loader extends CI_Loader
function mymodel($model, $folder = '',$vars = array(), $return = FALSE)
array_push($this->_ci_model_paths, ""); //replace "" with any other directory
parent::model($model);
function myview($folder, $view, $vars = array(), $return = FALSE)
$this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH . '../' . $folder . '/' => TRUE));
return $this->_ci_load(array(
'_ci_view' => $view,
'_ci_vars' => $this->_ci_object_to_array($vars),
'_ci_return' => $return
));
保存文件并在控制器中,调用并加载模型(位于应用程序文件夹之外),
$this->load->mymodel('folder/model');
对于视图,
$this->load->myview('views','view_dir/view-php-file', $data);
【讨论】:
您的回答 - 关于“视图” - 在应用程序文件夹之外不起作用!它是已接受答案的副本。【参考方案4】:在 application/core/ 中创建一个文件 MY_Loader.php
<?php
class MY_Loader extends CI_Loader
function __construct()
parent::__construct();
$CI =& get_instance();
$CI->load = $this;
public function ext_view($view, $vars = array(), $return = FALSE)
$_ci_ext = pathinfo($view, PATHINFO_EXTENSION);
$view = ($_ci_ext == '') ? $view.'.php' : $view;
return $this->_ci_load(array(
'_ci_vars' => $this->_ci_object_to_array($vars),
'_ci_path' => $view, '_ci_return' => $return));
在 application/core/ 中创建一个文件 MY_Controller.php
<?php
class MY_Controller extends CI_Controller
public function __construct()
parent::__construct();
$this->load =& load_class('Loader', 'core', 'MY_');
$this->load->initialize();
log_message('debug', "Controller Class Initialized");
使用MY_Controller
而不是CI_Controller
,您可以使用 ext_view 方法访问
$this->load->ext_view(path/to/the/view/file,@param2,@param3);
例如:
class Welcome extends MY_Controller
public function __construct()
parent::__construct();
public function index()
$this->load->ext_view('/path/to/view');
【讨论】:
【参考方案5】:按照 Dino 的回答并更正 ci_vars,作为查看 Codeigniter 的功能:
Codeigniter 视图函数
public function view($view, $vars = array(), $return = FALSE)
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return));
Dino 的视图功能现在是:
function ext_view($folder, $view, $vars = array(), $return = FALSE)
$this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH . $folder . '/' => TRUE));
return $this->_ci_load(array(
'_ci_view' => $view,
'_ci_vars' => $this->_ci_prepare_view_vars($vars),
'_ci_return' => $return
));
【讨论】:
【参考方案6】:这是我在 CodeIgniter 论坛 https://forum.codeigniter.com/thread-58412.html 上找到的更直接的答案
这是我与docmattman提出的解决方案的微小偏差:
class MY_Loader extends CI_Loader
public function __construct()
parent::__construct();
public function load_ext_view($view, $vars = array(), $return = FALSE)
$view_file = '/full/path/to/'.$view.'.php';
if(file_exists($view_file))
$view_to_load = array('_ci_path' => $view_file,
'_ci_view' => $view,
'_ci_vars' => $this->_ci_object_to_array($vars),
'_ci_return' => $return
);
return $this->_ci_load($view_to_load);
return $this->view($view, $vars, $return);
【讨论】:
以上是关于使用 CodeIgniter 加载视图文件夹外的视图的主要内容,如果未能解决你的问题,请参考以下文章
如何将codeigniter视图文件gmap存储到redis以使视图显示更快?