When coding PHP programs, in order to better maintain and understand the code in the future, use some appropriate design patterns It is essential. Let me first share with you the singleton mode. If there is any error or inappropriateness, I hope PHPers can help me point it out
The survival period of objects in PHP is from the beginning of the script to the end of the script, so PHP's singleton mode is only used multiple times in one page (which may include many other pages, not a single page in a narrow sense) This object will only take effect, and the new object will not be repeated when used multiple times (when multiple people work on a project, it is inevitable that an object will be instantiated multiple times in one request), and unnecessary time will not be consumed. resources (the effect of data control connection operation is obvious), and another point is that it can ensure that the entire script is the same object. How is this mode implemented? There are several points to pay attention to in its implementation:
1. The first thing is to define the __construct() method as a private method, so that you cannot get a new instance through new. The singleton mode cannot be instantiated externally, but it can be instantiated internally within itself. ;
2. Also shield the __clone() method to prevent cloning from outside the class
2. Then define a private variable used to save the instance and a public function getInstance() to obtain the private variable.
<?<span>php </span><span>/*</span><span>* * 设计模式——单例模式 * @author 燕睿涛(luluyrt@163.com) </span><span>*/</span> <span>class</span><span> Singlemodel{ </span><span>/*</span><span>* * 保存Singlemodel实例的变量 * @var Singlemodel $_instance </span><span>*/</span> <span>private</span> <span>static</span> <span>$_instance</span> = <span>null</span><span>; </span><span>/*</span><span>* * 屏蔽掉通过new来实例化该对象 </span><span>*/</span> <span>private</span> <span>function</span><span> __construct(){ </span><span>//</span><span>空函数就行</span> <span> } <span> /*</span><span>*</span></span>
<span><span> * 屏蔽掉通过clone来克隆该对象</span></span>
<span><span>*/</span> </span>
<span> <span>private</span> <span>function</span><span> __clone(){ </span></span>
<span><span>//</span><span>空函数就行</span> </span>
<span> <span>}</span> </span><span>/*</span><span>* * 通过该方法获取实例,防止多次实例化 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span><span> getInstance(){ </span><span>if</span>(!(self::<span>$_instance</span><span> instanceof self)){ self</span>::<span>$_instance</span> = <span>new</span><span> self(); } </span><span>return</span> self::<span>$_instance</span><span>; } }</span>
It is empty talk and these theories are not convincing. Let’s take a look at the specific effect difference through examples
<?<span>php </span><span>/*</span><span>* * 设计模式——单例模式——测试 * @author 燕睿涛(luluyrt@163.com) </span><span>*/</span> <span>class</span><span> Singlemodel{ </span><span>/*</span><span>* * 保存Singlemodel实例的变量 * @var Singlemodel $_instance </span><span>*/</span> <span>private</span> <span>static</span> <span>$_instance</span> = <span>null</span><span>; </span><span>private</span> <span>$_link</span> = <span>null</span><span>; </span><span>/*</span><span>* * 屏蔽掉通过new来实例化该对象(也可以去掉) * 这里来测试数据库连接 </span><span>*/</span> <span>private</span> <span>function</span><span> __construct(){ </span><span>$this</span>->_link = <span>mysqli_connect</span>("localhost","root","","mysql"<span>); } </span><span>/*</span><span>* * 通过该方法获取实例,防止多次实例化 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span><span> getInstance(){ </span><span>if</span>(!(self::<span>$_instance</span><span> instanceof self)){ self</span>::<span>$_instance</span> = <span>new</span><span> self(); } </span><span>return</span> self::<span>$_instance</span><span>; } </span><span>/*</span><span>* * 测试1,通过使用单例模式 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span><span> testOne(){ </span><span>return</span> self::<span>getInstance(); } </span><span>/*</span><span>* * 测试1,通过使用单例模式 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span><span> testTwo(){ </span><span>return</span> <span>new</span><span> self(); } } </span><span>$obj</span> = <span>array</span><span>(); </span><span>$begin</span> = <span>microtime</span>(<span>true</span><span>); </span><span>for</span>(<span>$i</span>=0;<span>$i</span><100;<span>$i</span>++<span>){ </span><span>/*</span><span> * 这里进行两次测试,testOne应用了单例模式,testTwo没有应用单例模式, * 我们分别看看他们占用的资源和耗费的时间 </span><span>*/</span> <span>//</span><span>$obj[$i] = Singlemodel::testOne();</span> <span>$obj</span>[<span>$i</span>] = Singlemodel::<span>testTwo(); } </span><span>echo</span> "程序运行期间最大内存占用:".memory_get_peak_usage()."bytes\r"<span>; </span><span>echo</span> "程序运行耗时:".<span>floatval</span>(<span>microtime</span>(<span>true</span>) - <span>$begin</span>)."s\r";
First comment out the line $obj[$i] = Singlemodel::testTwo();. Using singleton mode, we can get the following Result
$obj[$i] = Singlemodel::testOne();, using non-singleton mode, we get the following results
can be seen
100次测试 | 单例模式 | 普通模式 | 普通/单例(倍) |
内存(bytes) | 143816 | 847376 | 5.89 |
时间(s) | 0.0112519 | 0.2541389 | 22.59 |
5次测试 | |||
bytes | 140432 | 168984 | 1.20 |
s | 0.0112612 | 0.0173110 | 1.54 |
You can see that when the number of links executed by a script is 100, the performance of the singleton mode is nearly 6 times better than the normal mode in terms of memory usage and nearly 23 times faster in time. When the number of connections continues to increase, the multiple will be larger, because the memory and time consumed by the singleton mode have basically remained unchanged, and the non-singleton mode will continue to increase. One thing to note here is that in the non-singleton mode, an error will be reported when the number of links increases to a certain extent." mysqli_connect(): (08004/1040): Trop de connexions in", which means there are too many concurrent connections. For testing, we can check the setting of the maximum number of mysql connections through the following command. This needs to be noted, so as not to know why the error is reported. .
show variables <span>like</span> <span>'</span><span>max_connections</span><span>'</span>;
At this point, if you test it yourself, you will find that when the number of connections is relatively small, the difference is relatively small (just like when there are 5 connections in one request above). In fact, there are many instantiations in one request. It is also relatively small, so does this mean that it has no effect? Of course not, if you think about it, first of all, this can avoid multiple instantiations and reduce resource consumption; secondly, even if it is a 10ms level gap, It is also useful in high-concurrency systems. We have many benefits from using it.
That’s all for the singleton pattern. I’ll talk about other design patterns next time. If there’s anything wrong, please leave a message or email and point it out. Thank you very much!
send Me~