プロジェクトに統合したライブラリは、クリーンで関連性を保ちたいので、コントローラーにロードしたくないので、別のコントローラーの関数からコントローラーをロードしたいです。
私はモジュールを使用しようとしましたが、私はまだコントローラをURLに入れなければなりませんでした
http://example.com/maincontroller/function
http://example.com/othercontroller/function
ロードできるようにデフォルトのコントローラーがあります http://example.com/function mainから関数からコントローラーにアクセスするにはどうすればコントローラーをURLに入れる必要はありません。
メインコントローラー機能からコントローラー機能を読み込むことができれば、HMVCを引き続き使用できます。
HMVCなどを使用しない限り、CIのコントローラーからコントローラーをロードすることはできません。
アーキテクチャについて少し考える必要があります。別のコントローラーからコントローラーメソッドを呼び出す必要がある場合は、おそらくそのコードをヘルパーまたはライブラリに抽象化し、両方のコントローラーから呼び出す必要があります。
[〜#〜] update [〜#〜]
もう一度質問を読んだ後、私はあなたの最終目標は必ずしもHMVCではなく、URIの操作であることを理解しています。私が間違っている場合は修正してください。しかし、最初のセクションをメソッド名としてURLを達成しようとしているようで、コントローラー名を完全に省いています。
この場合、 ルートのクリエイティブ を取得することにより、よりクリーンなソリューションが得られます。
本当に基本的な例として、controller1
とcontroller2
の2つのコントローラーがあるとします。 Controller1
にはメソッドmethod_1
があり、controller2
にはメソッドmethod_2
があります。
次のようなルートを設定できます。
$route['method_1'] = "controller1/method_1";
$route['method_2'] = "controller2/method_2";
次に、http://site.com/method_1
などのURLでメソッド1を呼び出し、http://site.com/method_2
でメソッド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....
}
}
そして、mycontrollerからmethodAを呼び出すことができます
http://example.com/mycontroller/methodA
http://example.com/mycontroller/methodB
このソリューションは私のために働いた
同様の問題がありました。 2つのコントローラーが必要でした。
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();
}
}
上記の方法は機能する可能性がありますが、ここに非常に良い方法があります。
コアコントローラーを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();
}
}
さまざまな方法を試しているうちに、セッションファイルが見つからないというエラーが発生し、最終的にはこのようになりました。関数を静的(別のコントローラーで呼び出したい)として作成し、次のように呼び出しました
require_once('Welcome.php');
Welcome::hello();
Belowsで作成したコードを使用してヘルパーを作成し、controller_helper.phpという名前を付けます。
config
の下の_autoload.php
_ファイルにヘルパーを自動ロードします。
メソッドから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();
}
}
}
}
}
?>
_
Symfony2の動作をシミュレートするために、Twigで{{ render() }}
関数を作成する必要があるため、ここに来ました。ビューからコントローラーをレンダリングすることは、独立したウィジェットやajaxでリロード可能なものを表示するのに非常に便利です。
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, ...) }}