Heim  >  Artikel  >  Backend-Entwicklung  >  Ein einfaches Beispiel für die Instanzimplementierung in ThinkPhp5

Ein einfaches Beispiel für die Instanzimplementierung in ThinkPhp5

黄舟
黄舟Original
2018-05-16 11:05:262969Durchsuche

Dieser Artikel stellt hauptsächlich die einfache Implementierung der thinkphp5-Instanz vor, die einen gewissen Referenzwert hat.

 Ich habe kürzlich ThinkPHP5 studiert und zum ersten Mal die Methode TestClass: :instance() gesehen kann eine TestClass-Instanz erstellen. Ich war sehr neugierig und habe den Quellcode von ThinkPHP durchgesehen und seine Designideen verstanden.

Alte Regel, gehen Sie direkt zum 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 = &#39;Application 1&#39;;
echo $app1->key . &#39;<br />&#39;;
?>

Um den Aufruf zu erleichtern, habe ich auch ThinkPHP nachgeahmt und eine Hilfsfunktion geschrieben

<?php
function app() {
 return TestClass::instance();
}
 
$app2 = app();
$app2->key = &#39;Application 2&#39;;
echo $app2->key . &#39;<br />&#39;;
?>

In Auf diese Weise wird die Instanz einfach implementiert.

Es gibt jedoch ein kleines Problem bei dieser Methode. Wenn Sie es 100 Mal aufrufen, müssen Sie 100 Instanzen erstellen.

Fügen Sie der Testklasse ein statisches Attribut hinzu und speichern Sie die erstellte Instanz hier. Wenn Sie es das nächste Mal aufrufen müssen, rufen Sie diese Instanz direkt auf.

<?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(&#39;content-type:text/plain&#39;);
 
$result = [];
$app1 = app();
$app1->key = "Application 1"; //修改 key 为 Application 1
$result[&#39;app1&#39;] = [
 &#39;app1&#39; => $app1->key, //实例中 key 为 Application 1
];
 
// 创建 app2,因为 instance 已经存在实例,直接返回 缓存的实例
$app2 = app();
$result[&#39;app2&#39;] = [
 &#39;setp1&#39; => [
  &#39;app1&#39; => $app1->key, // Application 1
  &#39;app2&#39; => $app2->key, //因为直接调用的实例的缓存,所以 key 也是 Application 1
 ],
];
 
// 无论 app1,app2 都对在内存中 对应的同一个实例,无论通过谁修改,都能改变值
$app1->key = "Application 2";
$result[&#39;app2&#39;][&#39;setp2&#39;] = [
 &#39;app1&#39; => $app1->key, // Application 2
 &#39;app2&#39; => $app2->key, // Application 2
];
print_r($result);
?>

Durch das obige Experiment können Sie sehen, dass unabhängig von der Häufigkeit des Aufrufs dieselbe Instanz verwendet wird. Dies löst das Problem der geringen Effizienz.

Bisher erfüllt es grundsätzlich die meisten Situationen. Der einzige kleine Fehler besteht darin, dass die Anfangsparameter der Instanzen unterschiedlich sein können, was einen flexiblen Aufruf unmöglich macht (ein häufiges Beispiel ist, dass dasselbe Programm zwei Datenbanken aufruft). ). Dies kann durch eine leichte Modifikation des obigen Beispiels gelöst werden, indem die eingehenden Parameter als Schlüssel verwendet und die unvernünftigen Instanzen in einem Array zwischengespeichert werden.

<?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(&#39;content-type:text/plain&#39;);
 
$result = [];
//传入 初始数据
$app1 = app([&#39;key&#39; => &#39;123&#39;]);
$result[&#39;init&#39;] = $app1->key; // 使用 传入的数据,即:123
$app1->key = "app1";
$result[&#39;app&#39;] = $app1->key; // 现在值改为了 自定义的 app1了
print_r($result);
 
$result = [];
// 创建 app2,注意 初始参数不一样
$app2 = app();
// 因为初始参数不一样,所以还是创建新的实例
$app2->key = "app2";
$result[&#39;app1&#39;] = $app1->key; // app1
$result[&#39;app2&#39;] = $app2->key; // app2
print_r($result);
 
$result = [];
// 创建 app3,传入的参数 和 app1 一样,所以会直接返回 和app1相同 的 实例
$app3 = app([&#39;key&#39; => &#39;123&#39;]);
$result[&#39;log&#39;] = [
 &#39;app1&#39; => $app1->key, // app1
 &#39;app2&#39; => $app2->key, // app2
 &#39;app3&#39; => $app3->key, // app1
];
 
// 设置 app3 的key,会自动修改 app1 的值,因为他们两个是同一个实例
$app3->key = &#39;app3&#39;;
$result[&#39;app3_set&#39;] = [
 &#39;app1&#39; => $app1->key, // app3
 &#39;app2&#39; => $app2->key, // app2
 &#39;app3&#39; => $app3->key, // app3
];
 
// 同理,设置 app1 的key,app3 的 key 也会修改
$app1->key = &#39;app1&#39;;
$result[&#39;app1_set&#39;] = [
 &#39;app1&#39; => $app1->key, // app1
 &#39;app2&#39; => $app2->key, // app2
 &#39;app3&#39; => $app3->key, // app1
];
print_r($result);
?>

Das obige ist der detaillierte Inhalt vonEin einfaches Beispiel für die Instanzimplementierung in ThinkPhp5. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn