Codeigniterでは、get_instance()
はグローバルに使用可能な関数で、現在ロードされているすべてのクラスを含むControllerスーパーオブジェクトを返します(Controllerクラスインスタンスを返します)。現在のソースコードを含めます。
get_instance()
は_Codeigniter.php
_で定義されています
_// Load the base controller class
require BASEPATH.'core/Controller.php';
function &get_instance()
{
return CI_Controller::get_instance();
}
_
そして_CI_Controller
_は_Controller.php
_で定義されています
_class CI_Controller {
private static $instance;
/**
* Constructor
*/
public function __construct()
{
self::$instance =& $this;
// Assign all the class objects that were instantiated by the
// bootstrap file (CodeIgniter.php) to local class variables
// so that CI can run as one big super object.
foreach (is_loaded() as $var => $class)
{
$this->$var =& load_class($class);
}
$this->load =& load_class('Loader', 'core');
$this->load->set_base_classes()->ci_autoloader();
log_message('debug', "Controller Class Initialized");
}
public static function &get_instance()
{
return self::$instance;
}
}
_
ライブラリを作成するためのユーザーガイド での使用が推奨される方法は次のとおりです。
ライブラリ内でCodeIgniterリソースを活用する
ライブラリ内のCodeIgniterのネイティブリソースにアクセスするには、
get_instance()
関数を使用します。この関数は、CodeIgniterスーパーオブジェクトを返します。通常、コントローラー関数内から、_
$this
_コンストラクトを使用して、利用可能なCodeIgniter関数のいずれかを呼び出します:$this->load->helper('url'); $this->load->library('session'); $this->config->item('base_url');
など。_
$this
_ただし、コントローラー、モデル、またはビュー内でのみ直接機能します。独自のカスタムクラス内からCodeIgniterのクラスを使用する場合は、次のようにします。最初に、CodeIgniterオブジェクトを変数に割り当てます。
$ CI =&get_instance();
オブジェクトを変数に割り当てたら、_
$this
_の代わりにその変数を使用します。$ CI =&get_instance(); $ CI-> load-> helper( 'url'); $ CI-> load-> library( 'session'); $ CI-> config-> item( 'base_url');等.注:上記の
get_instance()
関数が参照渡しされていることに気付くでしょう:$ CI =&get_instance();
これは非常に重要です。参照による割り当てでは、コピーを作成するのではなく、元のCodeIgniterオブジェクトを使用できます。
関連記事: explain $ CI =&get_instance(); / Codeigniter:Get Instance
だから、ここに私の実際の質問があります:
ユーザーガイドがget_instance()
を変数に割り当てることを推奨するのはなぜですか?参照による割り当てを行わないことの意味を理解していると確信していますが、get_instance()->load->model()
が正常に機能するときに変数に割り当てることが推奨されるのはなぜですか?
オブジェクトのプロパティに割り当てるCIのユーザー定義またはサードパーティのクラスがたくさんあります。
_class MY_Class {
private $CI;
function __construct()
{
$this->CI =& get_instance();
}
function my_func()
{
$this->CI->load->view('some_view');
}
function my_other_func()
{
$this->CI->load->model('some_model');
}
}
_
悪い例ですが、私はこれを頻繁に見ます。なぜget_instance()
を直接呼び出すのではなく、このメソッドに煩わされるのですか? Controllerオブジェクト全体をクラス変数に割り当てるようなseemsは、たとえそれが参照であっても素晴らしいアイデアではありません。多分それは問題ではありません。
入力しやすいようにget_instance()
のラッパー関数を作成したいので、常に変数に割り当てる必要はありません。
_function CI()
{
return get_instance();
}
_
または:
_function CI()
{
$CI =& get_instance();
return $CI;
}
_
そうすれば、変数に代入する手間をかけずにどこからでもCI()->class->method()
を使用でき、変数の内容を非常に簡単に記述して理解でき、より短く、よりエレガントなコードを作成できます。
CI()
関数に違いはありますか?get_instance()
を直接呼び出すのではなく、変数に割り当てることが推奨されるのはなぜですか?function &get_instance(){}
の_&
_は、それがどこで定義されているのですか? references の目的について少し知っているので、必要に応じて使用しますが、この方法で定義された関数を見たことはありません。ラッパー関数を作成する場合、これも使用する必要がありますか?これはstyleの質問ではなく、技術的な質問であることに注意してください。私が提案している方法を使用して、問題、パフォーマンスまたはその他があるかどうかを知りたいです。
[〜#〜] edit [〜#〜]:これまでのところ:
他に何か、またはこれらが唯一の潜在的な問題ですか?
私の知る限り、それは何よりも利便性の問題です。ライブラリでCIスーパーオブジェクトを頻繁に使用する可能性があるので、それを変数に割り当てて、作業を少し簡単にするのはなぜですか?
他にも考慮すべきことがいくつかあります...
get_instance()
を呼び出すため、パフォーマンスにわずかな影響があります。_CI_Controller::$instance
_の値は、クラスの別のインスタンスが作成されると変更される可能性があるため、参照によって割り当てる必要があります。コンストラクターは、実行するたびに_self::$instance
_を再割り当てします。
一般的に、これは悪いデザインパターンのように感じられ、クラスを1つのインスタンスのみに制限するシングルトンのプロパティ http://en.wikipedia.org/wiki/Singleton_pattern が欠落しています。
CI_Controller::get_instance()->$className->$method();
と入力できるようです。これは、要求されたCI()->$className->$method
よりも入力が多いようです。
最終的に、_$instance
_のインスタンスを1つだけ作成し、参照による割り当ての必要性を排除することを要求することは理にかなっています。
直接呼び出すのではなく、変数にget_instance()を割り当てることが推奨されるのはなぜですか?
最も可能性が高いのは、php4との後方互換性を維持することをお勧めします。php4では、デフォルトではオブジェクトは参照渡しではなく、複製されています。
このアプローチを取らない理由はありますか?
古いPHPインストールでアプリケーションを実行する場合のみ
メソッドチェーンは_PHP4
_ではサポートされておらず、CI
は最近(バージョン_PHP4
_から)_2.0.0
_のサポートを終了しました。また、毎回get_instance()
と書くよりも_$CI
_と書くのは簡単です。
私はこの方法を使うことを好みます、それは簡単です
class Test
{
//magic method __get, whit this can use $this->load
//instead create a variable ci, then do $this->ci->load, cool :)
public function __get($var)
{
return get_instance()->$var;
}
public function showUrl()
{
$this->load->helper("url");
echo base_url();
}
}
既に述べたものを含む、いくつかのことの組み合わせである可能性があります。
できれば、この「推奨」がスタイルガイドの一部であるという考えが好きです。 CIの公式スタイルガイドではないかもしれませんが、まだです。
CIのすべてのサードパーティスクリプトがこの推奨事項を実装していることを想像してください。開発者は、これらのスクリプトがどのように設計されているかをすぐに判断できます。
IMOが重要なもう1つのことは、メソッドチェーンの仕組みです。そして、CI()->class->method()
を行うことは、CIの残りの部分がどのように機能するかを知っているため、直感的ではありません。
参照によってget_instance()
の結果を取得することは、PHP5以降では意味がありません。悲しいことに、この悪い習慣は根が深いようですので、対処しましょう。
興味のある方のために、ここに超高速のインスタンスゲッターがあります。
_function CI()
{
static $CI;
isset($CI) || $CI = CI_Controller::get_instance();
return $CI;
}
_
参照によって割り当てられた場合、静的変数は機能しないことに注意してください。
また、このCI()
の結果を参照によって取得しないように強制されます。余分な砂糖:-)
ああ、明らかにあなたはまだ関数呼び出しの(わずかな)コストを持っています。関数を何十回も呼び出す代わりに、変数を使用したい場合があります。