单例模式与静态变量在PHP中
在PHP中,没有普遍意义上的静态变量。与Java、C++不同,PHP中的静态变量的存活周期仅仅是每次PHP的会话周期,所以注定了不会有Java或者C++那种静态变量。
静态变量在PHP中
在PHP中,静态变量的存在意义仅仅是在某个结构体中(方法或者类)中传递一个变量,其作用域在此文件内。
function test(){
static $var = 1;
echo $var++.'';
}
test();
test();
test();
//OutPut
//1
//2
//3
在函数test的三次调用中,变量$var在三次调用中都是存在的,并且每次会递增1,而并没有清空或者重置
所以可以得出一个结论,静态变量在当前结构体所在的生命周期中一直存在。当前的例子中,test函数的生命周期就是当前PHP脚本,只要程序没释放都是有效的。
静态变量在类中
而在类中,代码大概是这样子的
class A
{
private static $a = 1;
private $b = 2;
public function add()
{
echo self::$a++.'';
echo $this->b++.'';
}
}
$class1 = new A();
$class1->add();
$class1->add();
$class2 = new A();
$class2->add();
$class2->add();
//Output
//1
//2
//2
//3
//3
//2
//4
//3
从上面的类的运行结果来看,也得到了在函数中相同的结果
那么大概总结一下就是
PHP的静态变量在所在对应的结构体的生命周期中永久存在,并且值保持一致,不论这个结构体被调用或者实例化了多少次。
其实这就是动态变量和静态变量的区别,具体看此篇文章。动态变量只在类中有效,而静态变量在当前php脚本。
静态变量在单例模式中
再反过来看单例模式
class A
{
private static $instance = null;
private $b = 1;
public static function get_instance()
{
if(self::$instance == null){
$classname = __CLASS__;
self::$instance = new $classname();
}
return self::$instance;
}
public function add()
{
$this->b++;
}
public function show()
{
echo $this->b;
}
}
$a = A::get_instance();
$b = A::get_instance();
//此处$a和$b变量完全相同!
$a->add();
$a->show();
echo '';
$b->show();
//output
//2
//2
此时,由于单例模式存在,使得$a和$b完全是同一个对象,所以之间如果需要共享数据,完全不需要静态变量(废话,就是自己。因为在任何时候,应用程序中都只会有这个类仅有的一个实例存在!无论你调用多少次单例,里面的数据是不会被重新实例化的。)
所以,在单例模式中,静态变量根本就没有存在的意义。当然,如果你没事干,非要使用new方法来初始化对象的话,也行,此时单例模式被打破,回归到无单例模式的状态。
如果为了防止使用new来实例化对象,那么可以考虑对类的__construct函数设置为private属性
class A
{
private static $instance = null;
private $b = 1;
private function __construct()
{
//Code in this function
//could not be get out of the class
}
public static function get_instance()
{
if(self::$instance == null){
$classname = __CLASS__;
self::$instance = new $classname();
}
return self::$instance;
}
public function add()
{
$this->b++;
}
public function show()
{
echo $this->b;
}
}
$a = A::get_instance();
$b = A::get_instance();
//此处$a和$b 变量完全相同!
$a->add();
$a->show();
echo '
';
$b->show();
//output
//2
//2 //如果尝试用new来实例化的话
$c = new A();
//output
//Fatal error: Call to private A::__construct() from invalid context in
//如果需要A类的实例化对象,只能通过开放的get_instance静态方法进行初始化
优点:单例模式可以避免大量的new操作,因为每一次new操作都会消耗内存资源和系统资源
缺点:在PHP中,所有的变量无论是全局变量还是类的静态成员,都是页面级的,每次页面被执行时,都会重新建立新的对象,都会在页面执行完毕后被清空,这样似乎PHP单例模式就没有什么意义了,所以PHP单例模式我觉得只是针对单次页面级请求时出现多个应用场景并需要共享同一对象资源时是非常有意义的
单例模式与静态变量在PHP中的更多相关文章
- [转]单例模式与静态变量在PHP中
在PHP中,没有普遍意义上的静态变量.与Java.C++不同,PHP中的静态变量的存活周期仅仅是每次PHP的会话周期,所以注定了不会有Java或者C++那种静态变量. 所以,在PHP中,静态变量的存在 ...
- 单例模式与静态变量在PHP中 (转载)
在PHP中,没有普遍意义上的静态变量.与Java.C++不同,PHP中的静态变量的存活周期仅仅是每次PHP的会话周期,所以注定了不会有Java或者C++那种静态变量. 所以,在PHP中,静态变量的存在 ...
- 内部类访问外部类的变量必须是final吗,java静态方法中不能引用非静态变量,静态方法中不能创建内部类的实例
内部类访问外部类的变量必须是final吗? 如下: package com.java.concurrent; class A { int i = 3; public void shout() { cl ...
- 解析Java中静态变量与实例变量的区别
java类的成员变量有俩种:一种是被static关键字修饰的变量,叫类变量或者静态变量:另一种没有static修饰,为实例变量. 在语法定义上的区别:静态变量前要加static关键字,而实例 ...
- java中的成员变量、静态变量与局部变量
java中的变量分为成员变量(又叫实例变量).静态变量和局部变量. 1.成员变量 1.1 成员变量(实例变量)是在类中定义的非static修饰的变量,可以不用赋初始值,不同的数据类型有默认的初始值. ...
- Qt中静态变量使用方法
静态变量可以在各个页面之前使用 先定义一个用于存放静态变量的类 例如datavar 在datavar.h中添加如下代码 #ifndef DATAVAR_H #define DATAVAR_H #inc ...
- Java中的静态变量static
package com.wangcf; public class Test { String name="你好"; static String sex="男"; ...
- matlab中的静态变量与全局变量
matlab中的静态变量和全局变量 1.静态变量 在matlab中,和其他语言一样,函数中的变量一把都是局部变量,也就是说,在函数调用完毕后,变量就会被释放.但是有些时候回希望上次改变的变量在下一次调 ...
- Java中静态变量与非静态变量的区别
感谢大佬:https://www.cnblogs.com/liuhuijie/p/9175167.html ①java类的成员变量有俩种: 一种是被static关键字修饰的变量,叫类变量或者静态变量 ...
随机推荐
- VMware Ubuntu 安装
最近对Linux系统有兴趣,本想装个双系统,考虑自己是以Windows为主,所以装了个虚拟机 VMware Workstation 12 Pro 版Ubuntu镜源文件下载地址:https://www ...
- 写个神经网络,让她认得我`(๑•ᴗ•๑)(Tensorflow,opencv,dlib,cnn,人脸识别)
训练一个神经网络 能让她认得我 阅读原文 这段时间正在学习tensorflow的卷积神经网络部分,为了对卷积神经网络能够有一个更深的了解,自己动手实现一个例程是比较好的方式,所以就选了一个这样比较有点 ...
- AOJ/树二叉搜索树习题集
ALDS1_7_A-RootedTree. Description: A graph G = (V, E) is a data structure where V is a finite set of ...
- USACO section 1.1 C++题解
USACO section1.1:DONE 2017.03.03 TEXT Submitting Solutions DONE 2017.03.04 PROB Your Ride Is Here [A ...
- C语言中的指针
请先看C++中的指针概述,这里只是扩充 数组指针 其实这里主要说的就是c++中的指针运算 /* 数组元素指针: 一个变量有地址,一个数组包含若干个元素,每个数组元素都有相应的地址, 指针变量可以指向数 ...
- (转)html中 cookie设置
box=="checkBox '是否记住用户密码'": window.onload=function init() { var box = getCookie(" ...
- MNIST机器学习
MNIST是一个入门级的计算机视觉数据集,它包含各种手写数字图片: 1. MNIST数据集 MNIST,是不是听起来特高端大气,不知道这个是什么东西? == 手写数字分类问题所要用到的(经典)MNIS ...
- 如何使用RSYNC搭建备份服务器
1. RSYNC介绍 RSYNC是一款开源的,快速的,多功能的,可实现全量及增量的本地或远程数据同步备份的优秀工具.Rsync软件适用于unix/linux/windows等多种操作系统平台. 远程数 ...
- 状态(State)模式
状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的 ...
- BeanInstantiationException: Failed to instantiate [java.time.LocalDateTime]
错误提示: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationExce ...