Maison >développement back-end >tutoriel php >Explication détaillée de la mise en œuvre de l'instance ThinkPHP5
Cet article présente principalement l'implémentation simple de l'instance ThinkPHP5, qui a une certaine valeur de référence. Les amis intéressés peuvent s'y référer. J'espère que cela aide tout le monde.
J'ai récemment appris ThinkPHP5 et pour la première fois j'ai vu TestClass::instance(), une méthode qui peut créer une instance TestClass. J'étais très curieux. J'ai parcouru le code source de ThinkPHP et j'ai généralement compris ses idées de conception.
Ancienne règle, allez directement dans le code :
<?php class TestClass { public static function instance() { return new self(); } public $data = []; public function __set($name, $val) { return $this->data[$name] = $val; } public function __get($name) { return $this->data[$name]; } } $app1 = TestClass::instance(); $app1->key = 'Application 1'; echo $app1->key . '<br />'; ?>
Afin de faciliter l'appel, j'ai également imité ThinkPHP et écrit une fonction d'assistance
<?php function app() { return TestClass::instance(); } $app2 = app(); $app2->key = 'Application 2'; echo $app2->key . '<br />'; ?>
Dans de cette façon, l'instance est simplement implémentée.
Cependant, il y a un petit problème avec cette méthode. Imaginez ce qui suit : si vous l'appelez 100 fois, vous devez créer 100 instances.
Ajoutez un attribut statique à la classe Test et enregistrez l'instance créée ici. Si vous devez l'appeler la prochaine fois, appelez directement cette instance.
<?php class TestClass { public static $instance; //用于缓存实例 public $data = []; public static function instance() { //如果不存在实例,则返回实例 if (empty(self::$instance)) { self::$instance = new self(); } return self::$instance; } public function __set($name, $val) { return $this->data[$name] = $val; } public function __get($name) { return $this->data[$name]; } } function app($option = []) { return TestClass::instance($option); } header('content-type:text/plain'); $result = []; $app1 = app(); $app1->key = "Application 1"; //修改 key 为 Application 1 $result['app1'] = [ 'app1' => $app1->key, //实例中 key 为 Application 1 ]; // 创建 app2,因为 instance 已经存在实例,直接返回 缓存的实例 $app2 = app(); $result['app2'] = [ 'setp1' => [ 'app1' => $app1->key, // Application 1 'app2' => $app2->key, //因为直接调用的实例的缓存,所以 key 也是 Application 1 ], ]; // 无论 app1,app2 都对在内存中 对应的同一个实例,无论通过谁修改,都能改变值 $app1->key = "Application 2"; $result['app2']['setp2'] = [ 'app1' => $app1->key, // Application 2 'app2' => $app2->key, // Application 2 ]; print_r($result); ?>
Grâce à l'expérience ci-dessus, vous pouvez voir que peu importe le nombre de fois qu'elle est appelée, la même instance sera utilisée. Cela résout le problème de la faible efficacité.
Jusqu'à présent, cela satisfait fondamentalement la plupart des situations. Le seul petit défaut est que les paramètres initiaux des instances peuvent être différents, ce qui rend impossible un appel flexible (généralement, comme le même programme appelant deux bases de données) . Cela peut être résolu en modifiant légèrement l'exemple ci-dessus, en utilisant les paramètres entrants comme clés et en mettant en cache les instances déraisonnables dans un tableau.
<?php class TestClass { public static $instance = []; //用于缓存实例数组 public $data = []; public function __construct($opt = []) { $this->data = $opt; } public static function instance($option = []) { // 根据传入的参数 通过 serialize 转换为字符串,md5 后 作为数组的 key $instance_id = md5(serialize($option)); //如果 不存在实例,则创建 if (empty(self::$instance[$instance_id])) { self::$instance[$instance_id] = new self($option); } return self::$instance[$instance_id]; } public function __set($name, $val) { return $this->data[$name] = $val; } public function __get($name) { return $this->data[$name]; } } function app($option = []) { return TestClass::instance($option); } header('content-type:text/plain'); $result = []; //传入 初始数据 $app1 = app(['key' => '123']); $result['init'] = $app1->key; // 使用 传入的数据,即:123 $app1->key = "app1"; $result['app'] = $app1->key; // 现在值改为了 自定义的 app1了 print_r($result); $result = []; // 创建 app2,注意 初始参数不一样 $app2 = app(); // 因为初始参数不一样,所以还是创建新的实例 $app2->key = "app2"; $result['app1'] = $app1->key; // app1 $result['app2'] = $app2->key; // app2 print_r($result); $result = []; // 创建 app3,传入的参数 和 app1 一样,所以会直接返回 和app1相同 的 实例 $app3 = app(['key' => '123']); $result['log'] = [ 'app1' => $app1->key, // app1 'app2' => $app2->key, // app2 'app3' => $app3->key, // app1 ]; // 设置 app3 的key,会自动修改 app1 的值,因为他们两个是同一个实例 $app3->key = 'app3'; $result['app3_set'] = [ 'app1' => $app1->key, // app3 'app2' => $app2->key, // app2 'app3' => $app3->key, // app3 ]; // 同理,设置 app1 的key,app3 的 key 也会修改 $app1->key = 'app1'; $result['app1_set'] = [ 'app1' => $app1->key, // app1 'app2' => $app2->key, // app2 'app3' => $app3->key, // app1 ]; print_r($result); ?>
Recommandations associées :
méthode thinkphp5 pour télécharger des images et générer des vignettes
Exemples détaillés d'URL et de fonctions de routage thinkphp5
Le didacticiel de pagination personnalisé ThinkPHP5 le plus détaillé
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!