在前面的章节中,我们接触到了很多类似于这样的方法`类名::方法名()`。比如:我们使用`Db::name()`来获取某个数据表模型,使用`Resquest::instance()`来获取请求模型使用了`::get()`来获取单条数据模型,使用`::select()`来获取多条数据模型,使用`::destroy`来销毁数据。
ThinkPHP5大量的使用了这种可以直接使用`::`调用的方法,它们有一个很响亮的名字:静态方法。静态方法的引用,大幅提升了程序的运行效率,降低了资源的占用。在实际项目开发中,由于静态方法的优越性,我们还会大量使用。虽然本教程的前面也简单的对静态方法进行过讲解,但距离『理解』这个程度还不够。
争取通过本章的学习,能够让静态方法在我们心中留下更深的印象。
# 静态方法
为什么要有静态方法?
1. 可以降低内存的占用。
2. 提高程序的执行效率。
什么时候用静态方法?
当这个方法与具体的对象无关时。
* * * * *
##对象、类:
人是一个类,而周润发就是一个对象。
对象,我们认为是存在于现实社会的。而类呢?是存在于我们大脑中的。我们说自行车、汽车、小猫、电脑、笔记本电脑,这些其实都是描述一类具体事件的一些概念。这些概念存在我们大家的大脑中,我们把这个概念性的东西,就叫做类。
我们说『人』是一个类,是由于它代表的是一类事物。类的特点是,当我们进行交流的时候,我们想到的具体事物可能不是一个。比如,今天的任务是:找一个美女(帅哥)搭讪,那么每个人找的美女(帅哥)都会不一样。要求大家每人今天摘一片树叶回来,那么大家摘的树叶也不会一样。原因是因为,美女是指的一类人,树叶,是指的一类事物。美女:我们想像的;树叶:我们想像的。
我们说女人是一个类,因为女人这个概念存在于我们的大脑中,而孙燕姿、贾玲就是一个个对象。
![](https://box.kancloud.cn/2016-06-20_57678335364a7.png)
当然了,我们男孩也是一个类。
![](https://box.kancloud.cn/2016-06-20_5767833557285.png)
我们说王宝强拍的电影是个类,而王宝强拍的『天下无贼』是一个对象;我们说梦云智团队是一个类,而团队中的每个成员都是对象;我们说笔记本是个类,而你正在使用的这台笔记本则是个对象。
总结:
> 类是存在于大脑中的概念,是对具体事物的抽象,并不是实体(实际存在的物体);而对象是一个实体,它具有唯一性,是具体的事物。
* * * * *
##静态方法
对于每一个河北工业大学的学生来讲,不管问我们谁:学校建校有100年了吗?
答案都是:有。
其实河北工业大学有没有100年,和问我们谁没有关系。只要是一个河北工业大的学生,就能准确的回答这个问题。
即:你只要问“河北工业大学的学生”这类人,那么答案可以确定,对于这个方法 ,我们就**可以**声明为静态方法。
而对于,”你的生日是哪天“?这些方法,由于不同的河北工业大学的学生回答的答案可能不同,那么就不能声明为静态方法。
总结(比较抽象):
> 虽然我们把方法都写在了一个类中,但是却有所区别。
> 静态方法:有类,就可以被调用,与类相关联。
> 非静态方法:只有存在对象的时候,这个方法才可以被调用,与对象相关联。
简单总结:
> 如果这个方法中没有用到$this(即没有使用到这个类中的内部变量),就应该声明为静态方法,以提升执行效率。
上面这句话还有另一层含义是:你完全可以不声明为静态方法,绝对不会报错,只是会影响一些执行效率罢了。
### 原来如此
我们重复下上面的问题:
我们把河北工业大学的学生,定义为一类人,这类人,我们起名叫Hebuter,它们的共同属性除了是人,还是大学生,还是一所大学的学生。
比如我现在有一个问题:河北工业大学,建校有100年了吗?
我们想:这个问题凡是这个学校的学生,就会知道正确的答案。
我还有一个问题:你的身份证号是多少?
我们想,每个学生的答案都是唯一的,是有区别的。
那么,针对上面两个问题。在程序中,我们可以这样写:
> 我们将测试代码写到```public```文件夹下的```test.php```中。
~~~
public function test()
{
$Hebuter = new Hebuter;
$xiaohong = $Hebuter::get('xiaohong'); // 小红
$xiaoming = $Hebuter::get('xiaoming'); // 小明
// 小红与小明回答学校是否建校100年,答案一致
var_dump($xiaohong->isSchoolMoreThan100());
var_dump($xiaoming->isSchoolMoreThan100());
// 小红和小明回答自己的身份证号码,答案不一致
var_dump($xiaohong->whatIsYouId());
var_dump($xiaoming->whatIsYouId());
}
~~~
我们将一些和具体的对象无关、而与具体的类有关的方法,往往定义为静态方法。
比如是否建校100年,只要是Hebuter给出的答案就是一致的。
在调用静态方法时,由于并不需要确定是哪个对象,所以可以不必实例化。
而与具体的对象相关,比如这里问你的身份证是多少,那么就不能定义成静态方法。
所以上述代码可以修改为:
~~~
public function test()
{
// 只要是我们学校的学生,回答学校是否建校100年,答案都是一个。
var_dump(Hebuter::isSchoolMoreThan100());
$Hebuter = new Hebuter;
$xiaohong = $Hebuter::get('xiaohong'); // 小红
$xiaoming = $Hebuter::get('xiaoming'); // 小明
// 小红和小明回答自己的身份证号码,答案不一致
var_dump($xiaohong->whatIsYouId());
var_dump($xiaoming->whatIsYouId());
}
~~~
以后我们还会接触越来越多的静态方法,用的多了,自然就理解了,在这里,有个概念就可以了。
完整代码如下:
~~~
<?php
class Test
{
public function test()
{
// 只要是我们学校的学生,回答学校是否建校100年,答案都是一个。
var_dump(Hebuter::isSchoolMoreThan100());
$Hebuter = new Hebuter;
$xiaohong = $Hebuter::get('xiaohong'); // 小红
$xiaoming = $Hebuter::get('xiaoming'); // 小明
// 小红和小明回答自己的身份证号码,答案不一致。
var_dump($xiaohong->whatIsYouId());
var_dump($xiaoming->whatIsYouId());
}
}
class Hebuter
{
private $name; // 姓名
// 设置姓名
public function setName($name)
{
$this->name = $name;
}
// 学校是否有百年历史
static public function isSchoolMoreThan100()
{
return true;
}
// 获取ID信息
public function whatIsYouId()
{
if ($this->name === 'xiaohong')
{
return '1234567';
}
if ($this->name === 'xiaoming')
{
return '7654321';
}
return '88888888';
}
// 根据名字获取Hebuter对象
static public function get($name)
{
$Hebuter = new Hebuter;
$Hebuter->setName($name);
return $Hebuter;
}
}
// 以下是测试代码
$Test = new Test; // 实例化
$Test->test(); // 调用对象中的方法
~~~
访问如下地址进行测试:
![](https://box.kancloud.cn/fc83dc28a3ed5cbc7f6cfd99ddd91735_615x254.png)
好像还有一点点乱对吧,没关系,如果还乱,多找一些关于类与对象的学习资料再看看吧,这个的确是个长久的学习过程。
- 序言
- 第一章 准备知识
- 第一节:XAMPP
- 第二节:NAVICAT
- 第三节:GIT
- 第二章 HelloWorld
- 第一节:下载THINPHP5.0
- 第二节:启动xampp
- 第三节:hello thinkphp
- 第四节:Hello world
- 第五节:MCA
- 第六节:单引号与双引号
- 第三章 教师管理
- 第一节:新建数据库
- 第二节:CURD之R 读数据
- 3.2.1 时序图
- 3.2.2 连接数据库
- 3.2.3 直接读取数据
- 3.2.4 间接读取数据
- 3.2.5 使用V层显示数据
- 3.2.6 引入bootstrap
- 3.2.7 加入bootstrap样式
- 第三节:CURD之 C 增加数据
- 3.3.1 插入数据
- 3.3.2 表单传值
- 3.3.3 存储表单数据
- 3.3.4 自动时间戳
- 3.3.5 增加验证
- 第四节:CURD之 D 删除数据
- 3.4.1 什么是关键字
- 3.4.2 删除数据
- 3.4.3 定制删除链接
- 3.4.4 完善删除
- 第五节:CURD之 U 更新数据
- 3.5.1 读取数据
- 3.5.2 展示数据
- 3.5.3 修改数据
- 3.5.4 传递数据
- 3.5.5 接收数据
- 3.5.6 更新数据 方法一
- 3.5.7 更新数据 方法二
- 第六节:衔接各个action & 重构代码
- 3.6.1 index action
- 3.6.2 add action
- 3.6.3 insert action
- 3.6.4 delete action
- 3.6.5 edit action
- 3.6.6 update action
- 第七节:分页
- 3.7.1 调用内置分页
- 3.7.2 select与paginate(选学)
- 3.7.3 分页原理(选学)
- 3.7.4 调用page(选学)
- 第八节:模糊查询
- 3.8.1 增加查询
- 3.8.2 完善查询
- 第四章 登录与注销
- 第一节:cookie 与 session
- 第二节:静态方法
- 第三节:规划URL跳转
- 第四节:登录
- 4.4.1 登录流程
- 4.4.2 index action
- 4.4.3 login action
- 4.4.4 引入M层
- 4.4.5 异常Exception
- 第五节:注销
- 第六节:验证
- 4.6.1 action增加验证
- 4.6.2 使用构造函数验证
- 4.6.3 使用继承验证
- 第五章 E-R图与数据字典
- 第一节:第一张E-R图
- 第二节:实体间的关系
- 第三节:开发规范
- 第六章 班级管理
- 第一节:建立数据表
- 第二节:数据列表index
- 第三节:增加数据add
- 第四节:编辑数据edit
- 第五节:删除数据delete
- 第七章 学生管理
- 第一节:建立数据表
- 第二节:数据列表
- 7.2.1 显示性别
- 7.2.2 显示创建时间
- 7.2.3 显示班级名称
- 7.2.4 显示辅导员姓名
- 第三节:编辑数据
- 第四节:魔法函数
- 第五节:源码分析
- 第八章 课程管理
- 第一节:建立数据表
- 第二节:新增课程
- 第三节:编辑课程
- 8.3.1 edit
- 8.3.2 update
- 第九章 代码重构
- 第一节:add 与 edit
- 第二节:insert 与 update
- 第三节:模板继承
- 9.3.1 index.html
- 9.3.2 edit.html
- 9.3.3 小结
- 第十章 UML图
- 第一节:E-R图回顾
- 第二节:UML图
- 第十一章 菜单与路由
- 第一节:添加菜单
- 第二节:虚拟主机
- 第三节:定制路由
- 第十二章 开发调试
- 第一节:开启trace
- 第二节:查看日志
- 第十三章:总结