Heim > Artikel > PHP-Framework > Wie gibt der ThinkPHP-Container eine Instanz zurück?
"Im vorherigen Artikel haben wir die Containerklasse kurz geklärt, und der nächste Schritt besteht darin, eine detaillierte Analyse eines der Details durchzuführen.
"
Containerinstanz ruft die Make-Methode auf
In diesem Artikel gibt es nicht viel Textanalyse, die den Ausführungsprozess in Codekommentaren erklärt.
Codestatic::getInstance()
Nachdem die Instanz von Container zurückgegeben wurde, wird die Make-Methode dieser Klasse aufgerufen. Der nächste Schritt besteht darin, die Make-Methode im Detail zu erklären.
Bevor wir mit dem Lesen des Quellcodes in der Make-Methode beginnen, müssen wir einige Attribute kurz klären.
Diese vier Attribute müssen einigermaßen beeindruckend sein und Instanzen und Instanzen müssen unterschieden werden.
Eines dieser beiden Attribute ist der Singleton-Modus, der die Instanz der aktuellen Klasse zurückgibt, und das andere sind alle Instanzen im Container.
Erstes Ausführungsergebnis
<span style="display: block; background: url(https://my-wechat.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #282c34; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"></span><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; padding-top: 15px; background: #282c34; border-radius: 5px;"> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 创建类的实例<br/> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@access</span> public<br/> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@param</span> string $abstract 类名或者标识<br/> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@param</span> array|true $vars 变量<br/> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@param</span> bool $newInstance 是否每次创建新的实例<br/> * <span class="hljs-doctag" style="color: #c678dd; line-height: 26px;">@return</span> object<br/> */</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">public</span> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">make</span><span class="hljs-params" style="line-height: 26px;">($abstract, $vars = [], $newInstance = false)</span><br/> </span>{<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 判断$vars这个变量是否为true</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> (<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">true</span> === $vars) {<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 总是创建新的实例化对象</span><br/> $newInstance = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">true</span>;<br/> $vars = [];<br/> }<br/><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// app 这里就是在容器别名里获取传递过来的app 如果没有则就是app</span><br/> $abstract = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract]) ? <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract] : $abstract;<br/> <br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 从容器实例中获取 如果存在则直接返回对应的实例 也就是使用注册树模式</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> (<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract]) && !$newInstance) {<br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract];<br/> }<br/><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// think\App 从容器标识中获取</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> (<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bind[$abstract])) {<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 将think\App 复制给$concrete变量</span><br/> $concrete = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bind[$abstract];<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 用于代表匿名函数的类 判断是不是闭包</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> ($concrete <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">instanceof</span> Closure) {<br/> $object = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->invokeFunction($concrete, $vars);<br/> } <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">else</span> {<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// $this->name['app'] = think\App</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract] = $concrete;<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 在执行一次本类的make方法,也就是本方法</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->make($concrete, $vars, $newInstance);<br/> }<br/> } <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">else</span> {<br/> $object = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->invokeClass($abstract, $vars);<br/> }<br/><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> (!$newInstance) {<br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract] = $object;<br/> }<br/><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> $object;<br/> }<br/></code>
Dies ist der zweite Ausführungsprozess
<span style="display: block; background: url(https://my-wechat.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #282c34; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"></span><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; padding-top: 15px; background: #282c34; border-radius: 5px;"> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">public</span> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">make</span><span class="hljs-params" style="line-height: 26px;">($abstract, $vars = [], $newInstance = false)</span><br/> </span>{<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 判断$vars这个变量是否为true</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> (<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">true</span> === $vars) {<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 总是创建新的实例化对象</span><br/> $newInstance = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">true</span>;<br/> $vars = [];<br/> }<br/><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// app 这里就是在容器别名里获取传递过来的app 如果没有则就是app</span><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 第二次执行时 $abstract = think\App</span><br/> $abstract = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract]) ? <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract] : $abstract;<br/><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 从容器实例中获取 如果存在则直接返回对应的实例 也就是使用注册树模式</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> (<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract]) && !$newInstance) {<br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract];<br/> }<br/><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// think\App 从容器标识中获取</span><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 第二次执行$this->bind['think\App']不存在走else</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> (<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">isset</span>(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bind[$abstract])) {<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 将think\App 复制给$concrete变量</span><br/> $concrete = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bind[$abstract];<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 用于代表匿名函数的类 判断是不是闭包</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> ($concrete <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">instanceof</span> Closure) {<br/> $object = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->invokeFunction($concrete, $vars);<br/> } <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">else</span> {<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// $this->name['app'] = think\App</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->name[$abstract] = $concrete;<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 在执行一次本类的make方法,也就是本方法</span><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// think\App</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->make($concrete, $vars, $newInstance);<br/> }<br/> } <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">else</span> {<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// think\App</span><br/> $object = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->invokeClass($abstract, $vars);<br/> }<br/><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> (!$newInstance) {<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 把创建的容器存起来</span><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">//$this->instances['think\App'] = $object;</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->instances[$abstract] = $object;<br/> }<br/><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> $object;<br/> }<br/></code>
<span style="display: block; background: url(https://my-wechat.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #282c34; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"></span><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; padding-top: 15px; background: #282c34; border-radius: 5px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">public</span> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">invokeClass</span><span class="hljs-params" style="line-height: 26px;">($class, $vars = [])</span><br/> </span>{<br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">try</span> {<br/><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * ReflectionClass Object<br/> (<br/> [name] => think\App<br/> )<br/> */</span><br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 这里就是之前文章提到的反射</span><br/> $reflect = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">new</span> ReflectionClass($class);<br/><br/><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> ($reflect->hasMethod(<span class="hljs-string" style="color: #98c379; line-height: 26px;">'__make'</span>)) {<br/> $method = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">new</span> ReflectionMethod($class, <span class="hljs-string" style="color: #98c379; line-height: 26px;">'__make'</span>);<br/><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> ($method->isPublic() && $method->isStatic()) {<br/> $args = <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bindParams($method, $vars);<br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> $method->invokeArgs(<span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">null</span>, $args);<br/> }<br/> }<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 通过反射获取think\App的构造函数</span><br/> $constructor = $reflect->getConstructor();<br/><br/> $args = $constructor ? <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">$this</span>->bindParams($constructor, $vars) : [];<br/> <span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">// 从给出的参数创建一个新的类实例</span><br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> $reflect->newInstanceArgs($args);<br/><br/> } <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">catch</span> (ReflectionException $e) {<br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">throw</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">new</span> ClassNotFoundException(<span class="hljs-string" style="color: #98c379; line-height: 26px;">'class not exists: '</span> . $class, $class);<br/> }<br/> }<br/></code>
Ausführungsflussdiagramm
Da der Code nun sortiert ist, sortieren wir nun das Ausführungsflussdiagramm, um es klarer zu sehen.
“Beharrlichkeit beim Lernen, Beharrlichkeit beim Bloggen und Beharrlichkeit beim Teilen sind die Überzeugungen, die Kaka seit seiner Karriere immer vertreten hat. Ich hoffe, dass Kakas Artikel im riesigen Internet Ihnen ein wenig helfen können. Ich bin Kaka, bis zum nächsten Mal
“
Das obige ist der detaillierte Inhalt vonWie gibt der ThinkPHP-Container eine Instanz zurück?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!