Heim  >  Artikel  >  PHP-Framework  >  Wie gibt der ThinkPHP-Container eine Instanz zurück?

Wie gibt der ThinkPHP-Container eine Instanz zurück?

咔咔
咔咔Original
2020-10-12 12:51:251302Durchsuche
"

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[&#39;app&#39;] = 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[&#39;think\App&#39;]不存在走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[&#39;app&#39;] = 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[&#39;think\App&#39;] = $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;">&#39;__make&#39;</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;">&#39;__make&#39;</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;">&#39;class not exists: &#39;</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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn