Как загрузить контроллер с другого контроллера в codeigniter?
Я хочу загрузить контроллер из функции в другой контроллер, потому что библиотека, которую я интегрировал в свой проект, я не хочу загружать ее в контроллер, потому что я хочу сохранить ее чистой и связанной.
Я пробовал использовать модули, но мне все равно пришлось поставить контроллер в URL-адрес, например
http://example.com/maincontroller/function
http://example.com/othercontroller/function
У меня есть контроллер по умолчанию, поэтому я могу загрузить http://example.com/function, чтобы как я мог получить доступ к контроллеру из функции из main, поэтому я не должны поставить контроллер в URL.
Я все еще готов использовать HMVC, если я могу загрузить функцию контроллера из функции главного контроллера.
Ответы
Ответ 1
Вы не можете загрузить контроллер с контроллера в CI - если вы не используете HMVC или что-то еще.
Вы должны немного подумать о своей архитектуре. Если вам нужно вызвать метод контроллера с другого контроллера, вы должны, вероятно, отвлечь этот код от помощника или библиотеки и вызвать его с обоих контроллеров.
UPDATE
После прочтения вашего вопроса снова я понимаю, что ваша конечная цель - не обязательно HMVC, а URI-манипуляция. Исправьте меня, если я ошибаюсь, но похоже, что вы пытаетесь выполнить URL-адреса, причем первый раздел является именем метода и вообще не содержит имя контроллера.
Если это так, вы получите более чистое решение, получив объявление с вашими маршрутами.
Для действительно базового примера, скажем, у вас есть два контроллера, controller1
и controller2
. controller1
имеет метод method_1
- и controller2
имеет метод method_2
.
Вы можете настроить маршруты следующим образом:
$route['method_1'] = "controller1/method_1";
$route['method_2'] = "controller2/method_2";
Затем вы можете вызвать метод 1 с URL-адресом типа http://site.com/method_1
и методом 2 с помощью http://site.com/method_2
.
Хотя, это жестко закодированный, очень простой пример, но он может привести вас туда, где вам нужно, если все, что вам нужно сделать, это удалить контроллер из URL.
Вы также можете перейти с переназначением своих контроллеров.
Из документов: "Если ваш контроллер содержит функцию с именем _remap(), он всегда будет вызываться независимо от того, что содержит ваш URI.":
public function _remap($method)
{
if ($method == 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}
Ответ 2
да, вы можете (для версии 2)
загрузите это внутри вашего контроллера
$this->load->library('../controllers/whathever');
и вызовите следующий метод:
$this->whathever->functioname();
Ответ 3
вы не можете вызвать метод контроллера с другого контроллера напрямую
Мое решение заключается в использовании наследований и расширении вашего контроллера из библиотечного контроллера.
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....
}
}
и вы можете вызвать методA из mycontroller
http://example.com/mycontroller/methodA
http://example.com/mycontroller/methodB
это решение работало для меня
Ответ 4
У меня была аналогичная проблема. Я хотел иметь два контроллера:
homepage.php - общедоступная домашняя страница
home.php - домашний экран после входа пользователя в систему
и я хотел, чтобы они оба читали "mydomain.com"
Я смог выполнить это, установив "hompepage" в качестве контроллера по умолчанию в настройках маршрутов и добавив функцию переназначения на домашнюю страницу .php
function _remap()
{
if(user_is_logged_in())
{
require_once(APPPATH.'controllers/home.php');
$oHome = new Home();
$oHome->index();
}
else
{
$this->index();
}
}
Ответ 5
В то время как вышеприведенные методы могут работать, вот очень хороший метод.
Расширьте контроллер ядра с помощью 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();
}
}
Ответ 6
Я пришел сюда, потому что мне нужно было создать функцию {{ render() }}
в Twig, чтобы имитировать поведение Symfony2. Рендеринг контроллеров из представления действительно крут, чтобы отображать независимые виджеты или перезаряжаемые материалы.
Даже если вы не пользователь Twig, вы все равно можете воспользоваться этим помощником и использовать его, как хотите, в своих представлениях для рендеринга контроллера, используя <?php echo twig_render('welcome/index', $param1, $param2, $_); ?>
. Это будет отражать все, что выводил ваш контроллер.
Вот он:
helpers/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):
libraries/Twig.php
$this->_twig_env->addFunction('render', new Twig_Function_Function('twig_render'));
Usage
{{ render('welcome/index', param1, param2, ...) }}
Ответ 7
Создайте помощника, используя код, который я создал, и назовите его 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
У меня был файл сеанса, который не был найден, и попытался по-разному, наконец, достиг такого. Сделал функцию статичной (которую я хочу вызвать в другом контроллере) и назвал ее
require_once('Welcome.php');
Welcome::hello();