Home >PHP Framework >ThinkPHP >Simply implement thinkphp5 instance!

Simply implement thinkphp5 instance!

藏色散人
藏色散人forward
2021-03-15 17:46:572430browse

The following tutorial column will introduce you to the simple implementation method of thinkphp5 instance. I hope it will be helpful to friends in need!

Simple implementation of thinkphp5 instanceSimply implement thinkphp5 instance!

Build a car from scratch again (yesterday’s car building: simple implementation of angularjs’s array parameter passing method http://www.miaoqiyuan.cn/p/an...), let’s talk about it Implementation. This article (a simple implementation of thinkphp5 instance) is an original article. The original address is: http://www.miaoqiyuan.cn/p/ph.... Please indicate the source when reprinting.

Old rule, go directly to the 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 />';
?>

In order to facilitate the call, I also imitated ThinkPHP and wrote an assistant function

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

This way, instance is simply implemented.

However, there is a small problem with this method. Just imagine the following. If you call it 100 times, you need to create 100 instances. It is scary to think about it.

Add a static attribute to the Test class and save the created instance here. If you need to call it next time, call this instance directly.

<?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);
?>

Through the above experiment, you can see that no matter how many times it is called, the same instance will be used. This solves the problem of low efficiency.

So far, it basically satisfies most situations. The only small flaw is that the initial parameters of the instances may be different, so it cannot be called flexibly (commonly, the same program calls two databases). This can be solved by slightly modifying the above example, using the incoming parameters as keys and caching the unreasonable instances into an array.

<?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);
?>

The above is the detailed content of Simply implement thinkphp5 instance!. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete