我想从另一个控制器中的函数加载控制器,因为我集成到我的项目中的库我不想将它加载到控制器,因为我想保持它的清洁和相关。
我尝试使用模块,但我仍然需要将控制器放在网址中,如
http://example.com/maincontroller/function
http://example.com/othercontroller/function
我有默认控制器,所以我可以加载http://example.com/function所以如何从main函数访问控制器,所以我不必将控制器放在url中。
如果我可以从主控制器功能加载控制器功能,我仍然愿意使用HMVC。
答案 0 :(得分:43)
是的,你可以(对于版本2)
在控制器内加载
$this->load->library('../controllers/whathever');
并调用以下方法:
$this->whathever->functioname();
答案 1 :(得分:22)
您无法从CI中的控制器加载控制器 - 除非您使用HMVC或其他东西。
你应该考虑一下你的架构。如果您需要从另一个控制器调用控制器方法,那么您应该将该代码抽象出一个帮助器或库,并从两个控制器中调用它。
<强>更新强>
再次阅读你的问题之后,我意识到你的最终目标不一定是HMVC,而是URI操纵。如果我错了,请纠正我,但似乎你正在尝试使用第一部分作为方法名称来完成URL并完全忽略控制器名称。
如果是这种情况,您可以通过creative with your routes获得更清晰的解决方案。
对于一个非常基本的例子,假设您有两个控制器,controller1
和controller2
。 Controller1
有一个方法method_1
- controller2
有方法method_2
。
您可以设置如下路线:
$route['method_1'] = "controller1/method_1";
$route['method_2'] = "controller2/method_2";
然后,您可以使用http://site.com/method_1
等网址调用方法1,使用http://site.com/method_2
调用方法2。
虽然这是一个硬编码,非常基本的例子 - 但是如果您需要做的就是从URL中删除控制器,它可以让您到达您需要的位置。
您也可以使用remapping your controllers。
从文档:“如果您的控制器包含一个名为_remap()的函数,无论您的URI包含什么,它都会被调用。”:
public function _remap($method)
{
if ($method == 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}
答案 2 :(得分:16)
你无法直接从另一个控制器调用控制器方法
我的解决方案是使用继承并从库控制器扩展控制器
class Controller1 extends CI_Controller {
public function index() {
// some codes here
}
public function methodA(){
// code here
}
}
在您的控制器中,我们将其称为Mycontoller
,它将扩展Controller1
include_once (dirname(__FILE__) . "/controller1.php");
class Mycontroller extends Controller1 {
public function __construct() {
parent::__construct();
}
public function methodB(){
// codes....
}
}
你可以从mycontroller调用methodA
http://example.com/mycontroller/methodA
http://example.com/mycontroller/methodB
这个解决方案对我有用
答案 3 :(得分:8)
我有类似的问题。我想要两个控制器:
homepage.php - 面向公众的主页
home.php - 用户登录后的主屏幕
我希望他们都能从'mydomain.com'中读取
我能够通过在我的路由配置中将'hompepage'设置为默认控制器并向homepage.php添加重映射功能来实现此目的
function _remap()
{
if(user_is_logged_in())
{
require_once(APPPATH.'controllers/home.php');
$oHome = new Home();
$oHome->index();
}
else
{
$this->index();
}
}
答案 4 :(得分:1)
虽然上述方法可行,但这是一个非常好的方法。
使用MY控制器扩展核心控制器,然后为所有其他控制器扩展此MY控制器。例如,您可以:
class MY_Controller extends CI_Controller {
public function is_logged()
{
//Your code here
}
public function logout()
{
//Your code here
}
}
然后你的其他控制器可以扩展如下:
class Another_Controller extends MY_Controller {
public function show_home()
{
if (!$this->is_logged()) {
return false;
}
}
public function logout()
{
$this->logout();
}
}
答案 5 :(得分:1)
您可以通过多种方法将一个控制器访问另一个控制器。
class Test1 extends CI_controller
{
function testfunction(){
return 1;
}
}
然后创建另一个类,并在其中包含第一个类,并随您的类扩展它。
include 'Test1.php';
class Test extends Test1
{
function myfunction(){
$this->test();
echo 1;
}
}
答案 6 :(得分:0)
我来到这里因为我需要在Twig中创建一个{{ render() }}
函数来模拟Symfony2的行为。从视图中渲染控制器非常酷,可以显示独立的小部件或ajax-reloadable东西。
即使您不是Twig用户,您仍然可以使用<?php echo twig_render('welcome/index', $param1, $param2, $_); ?>
使用此帮助程序并在视图中使用它来呈现控制器。这将回应控制器输出的所有内容。
这是:
助手/ twig_helper.php
<?php
if (!function_exists('twig_render'))
{
function twig_render()
{
$args = func_get_args();
$route = array_shift($args);
$controller = APPPATH . 'controllers/' . substr($route, 0, strrpos($route, '/'));
$explode = explode('/', $route);
if (count($explode) < 2)
{
show_error("twig_render: A twig route is made from format: path/to/controller/action.");
}
if (!is_file($controller . '.php'))
{
show_error("twig_render: Controller not found: {$controller}");
}
if (!is_readable($controller . '.php'))
{
show_error("twig_render: Controller not readable: {$controller}");
}
require_once($controller . '.php');
$class = ucfirst(reset(array_slice($explode, count($explode) - 2, 1)));
if (!class_exists($class))
{
show_error("twig_render: Controller file exists, but class not found inside: {$class}");
}
$object = new $class();
if (!($object instanceof CI_Controller))
{
show_error("twig_render: Class {$class} is not an instance of CI_Controller");
}
$method = $explode[count($explode) - 1];
if (!method_exists($object, $method))
{
show_error("twig_render: Controller method not found: {$method}");
}
if (!is_callable(array($object, $method)))
{
show_error("twig_render: Controller method not visible: {$method}");
}
call_user_func_array(array($object, $method), $args);
$ci = &get_instance();
return $ci->output->get_output();
}
}
特定于Twig用户(使此代码适应您的Twig实现):
库/ Twig.php
$this->_twig_env->addFunction('render', new Twig_Function_Function('twig_render'));
用法
{{ render('welcome/index', param1, param2, ...) }}
答案 7 :(得分:0)
使用我在下面创建的代码创建一个帮助器,并将其命名为controller_helper.php。
在autoload.php
下的config
文件中自动加载您的助手。
从方法调用controller('name')
加载控制器。
请注意name
是控制器的文件名。
此方法会将'_controller'
附加到您的控制器'name'
。要在控制器中调用方法,只需在加载控制器后运行$this->name_controller->method();
,如上所述。
<?php
if(!function_exists('controller'))
{
function controller($name)
{
$filename = realpath(__dir__ . '/../controllers/'.$name.'.php');
if(file_exists($filename))
{
require_once $filename;
$class = ucfirst($name);
if(class_exists($class))
{
$ci =& get_instance();
if(!isset($ci->{$name.'_controller'}))
{
$ci->{$name.'_controller'} = new $class();
}
}
}
}
}
?>
答案 8 :(得分:0)
我在尝试各种方式时遇到了会话文件错误,最终实现了这样。使函数成为静态(我想在另一个控制器中调用),并调用
require_once('Welcome.php');
Welcome::hello();