本文来自pilishen.com----原文连接; 欢迎来和pilishen一块儿学习php&Laravel;学习群:109256050php
该篇属于《Laravel底层核心技术实战揭秘》这一课程《laravel底层核心概念解析》这一章的扩展阅读。因为要真正学好laravel底层,有些PHP相关的知识必须得了解,考虑到学员们的基础差别,为了不视频当中过于详细而连篇累牍,故将一些laravel底层实现相关的PHP知识点以文章形式呈现,供你们预习和随时查阅。laravel
以前咱们讲过静态调用绑定(late static binding),nice,如今来考考你呗~ :smirk:bash
<?php
class Foo {
protected static $instance;
public static function setInstance($ins)
{
static::$instance = $ins;
}
public static function getInstance()
{
return static::$instance;
}
}
class Bar extends Foo {
}
Bar::setInstance('pilishen.com');
echo Bar::getInstance() .'<br>';
echo Foo::getInstance() .'<br>';
?>
复制代码
你说两个输出结果分别是啥呢?app
echo Bar::getInstance() .'<br>';
输出的确定是pilishen.com
,问题是echo Foo::getInstance() .'<br>';
.post
咱们知道static::
指向的是实际调用它的class,因此Bar::setInstance('pilishen.com');
执行的时候,在setInstance()
方法里至关因而Bar::$instance = 'pilishen.com'
,也便是class Bar
的静态属性$instance
设置成了pilishen.com
,而父类class Foo
的静态属性$instance
没动着它,因此应该仍是空的,对吧?学习
现实是残酷的: :open_mouth:测试
pilishen.com
pilishen.com
复制代码
好吧,现实是须要接受的,继续做! :smiling_imp:ui
...
class Baz extends Foo {
}
Bar::setInstance('pilishen.com');
echo Bar::getInstance() .'<br>';
echo Foo::getInstance() .'<br>';
echo '<hr>';
Baz::setInstance('laravel');
echo Baz::getInstance() .'<br>';
echo Bar::getInstance() .'<br>';
echo Foo::getInstance() .'<br>';
?>
复制代码
咱们又搞了一个class Baz
,也是扩展了class Foo
,而后Baz::setInstance('laravel');
,这个时候很显然Baz
的$instance
是laravel
了,问题是Bar
和Foo
的呢?咱们知道它两个以前都是pilishen.com
,再来接受下现实? :scream:this
pilishen.com
pilishen.com
laravel
laravel
laravel
复制代码
好吧,牵一发动全身!子类能改变父类?!子类能改变子类?!厉害了哦~ :thumbsup:spa
为了测试这只是静态属性的问题,也即证实一下咱们传统的关于属性继承的思路没错,咱们改一下:
<?php
class Foo {
protected $instance='Null';
public function setInstance($ins)
{
$this->instance = $ins;
}
public function getInstance()
{
return $this->instance;
}
}
class Bar extends Foo {
}
class Baz extends Foo {
}
$bar = new Bar;
$bar->setInstance('pilishen.com');
echo $bar->getInstance() .'<br>';
echo (new Foo)->getInstance() .'<br>';
echo '<hr>';
$baz = new Baz;
$baz->setInstance('laravel');
echo $baz->getInstance() .'<br>';
echo $bar->getInstance() .'<br>';
echo (new Foo)->getInstance() .'<br>';
?>
复制代码
如今的现实就是能够接受的了:
pilishen.com
Null
laravel
pilishen.com
Null
复制代码
因此,静态属性的继承跟咱们默认想象的不同哦: :sunglasses:
尽管咱们在子类里能够获取它,能够修改它,可是这个它,指向的都是父类里的那个静态属性,确实是子类能改变父类,子类能改变子类。也或者说,全部的父类和子类,都是共享这一个静态属性。
固然,上面的状况仅发生在你的子类里,没有额外定义一个同名静态属性的状况下,若是这样:
<?php
class Foo {
protected static $instance='null';
public static function setInstance($ins)
{
static::$instance = $ins;
}
public static function getInstance()
{
return static::$instance;
}
}
class Bar extends Foo {
protected static $instance;
}
class Baz extends Foo {
protected static $instance;
}
Bar::setInstance('pilishen.com');
echo Bar::getInstance() .'<br>';
echo Foo::getInstance() .'<br>';
echo '<hr>';
Baz::setInstance('laravel');
echo Baz::getInstance() .'<br>';
echo Bar::getInstance() .'<br>';
echo Foo::getInstance() .'<br>';
?>
复制代码
这里咱们在子类里面都额外定义了一个同名的$instance
,这个时候就是各自的是各自的了,就不是共享了:
pilishen.com
null
laravel
pilishen.com
null
复制代码
好了,知道这些个有什么用呢?
laravel里大量使用了静态属性,固然也包括静态调用绑定,那么你在查看源码的时候就要注意这一点喽~父类和子类是共享的一个静态属性吗?仍是子类里面有从新定义呢?子类更改静态属性,会影响父类吗? :sleeping:
最简单的,laravel如何保证整个程序,那么多个类,他们在运行的时候都是用的同一个laravel实例自己呢?都是同一个$app
呢?如今明白了吧~ :unamused:
不明白也没关系,回头咱们在《Laravel底层核心技术实战揭秘》中一一详解,记得有这么回事就好~ :muscle: