Я хочу загрузить контроллер из функции в другой контроллер, потому что библиотека, которую я интегрировал в свой проект, я не хочу загружать ее в контроллер, потому что я хочу сохранить ее чистой и связанной.
Я пробовал использовать модули, но мне все еще приходилось вводить контроллер в URL-адрес
http://example.com/maincontroller/function
http://example.com/othercontroller/function
У меня есть контроллер по умолчанию, поэтому я могу загрузить http://example.com/function, чтобы как я мог получить доступ к контроллеру из функции из main, поэтому мне не нужно вводить контроллер в URL-адрес.
Я все еще готов использовать HMVC, если я могу загрузить функцию контроллера из функции главного контроллера.
Вы не можете загрузить контроллер с контроллера в CI – если вы не используете HMVC или что-то еще.
Вы должны немного подумать о своей архитектуре. Если вам нужно вызвать метод контроллера с другого контроллера, то вам, вероятно, следует отвлечь этот код от помощника или библиотеки и вызвать его с обоих контроллеров.
ОБНОВИТЬ
После того, как вы снова прочитали свой вопрос, я понимаю, что ваша конечная цель – не обязательно 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)
загрузите это внутри вашего контроллера
$this->load->library('../controllers/whathever');
и вызовите следующий метод:
$this->whathever->functioname();
вы не можете вызвать метод контроллера с другого контроллера напрямую
мое решение заключается в использовании наследований и расширении вашего контроллера от библиотечного контроллера
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 из моего контроллера
http://example.com/mycontroller/methodA
http://example.com/mycontroller/methodB
это решение работало для меня
У меня была аналогичная проблема. Я хотел иметь два контроллера:
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(); } }
Я пришел сюда, потому что мне нужно было создать функцию {{ render() }}
в Twig, чтобы имитировать поведение Symfony2. Рендеринг контроллеров из представления действительно классный, чтобы отображать независимые виджеты или ajax-reloadable stuffs.
Даже если вы не пользователь Twig, вы все равно можете воспользоваться этим помощником и использовать его, как хотите, в своих представлениях для визуализации контроллера, используя <?php echo twig_render('welcome/index', $param1, $param2, $_); ?>
<?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, ...) }}
Создайте помощника, используя код, который я создал, и назовите его controller_helper.php.
Загрузите свой помощник в файл autoload.php
в config
.
С вашего controller('name')
вызова метода 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(); } } } } } ?>
У меня был файл сеанса, который не был найден, и попытался по-разному, наконец, достиг такого. Сделал функцию статической (которую я хочу вызвать в другом контроллере), и вызвал
require_once('Welcome.php'); Welcome::hello();
Хотя вышеприведенные методы могут работать, вот очень хороший метод.
Расширьте основной контроллер с помощью 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(); } }
изclass Another_Controller extends MY_Controller { public function show_home() { if (!$this->is_logged()) { return false; } } public function logout() { $this->logout(); } }