【解惑】由namespace引起的關於加載的思考

1.命名空間到底解決了什麼問題?

PHP在5.3.0入了namespace關鍵字以及__NAMESPACE__魔術常量,命名空間的做用是爲了解決重名問題。固然,這也是它惟一的做用了。php

2.使用命名空間須要注意的點在哪?

你在當前文件下引入兩個名字相同,命名空間不一樣的類,你能夠經過use命名空間時,as出來兩個別名的方式使類實例化的時候區分開使用。但你若是沒有引入這兩個類,僅僅use命名空間了,那麼這兩個類是不能實例化的。
這裏你能夠簡單的測試一下,看看已有命名空間的狀況下,引入類文件和沒有引入可否found到類文件。json

3.咱們使用ide(phpstorm)的時候,直接敲出來這個類,而後ide會use須要的類命名空間,彷佛就完成類文件的引入了?

重點:命名空間並無作include/require文件的工做。
你要知道使用框架和沒有使用框架是不同的,框架會幫助你完成不少事。
相信你在第二步的時候。發現了php腳本狀況下只引入命名空間是找不到類的這個事實。
so,迴歸php自己,甭管你有沒有use這個類,當進程運行到須要使用到這個類的時候,php都會把它當作一個陌生的類。若是框架沒有幫助引入類的設計,那麼就會直接報錯not found class了。php框架

4.命名空間use在什麼時候解析?

先上例子:app

test.phpcomposer

<?php
use my\name;
require_once("/home/yejianfeng/handcode/test/namespace1.php");
$a = new my\name\A();
$a->Print1();

namespace1.php框架

<?phpphpstorm

namespace my\name;
class A {
        public function Print1(){
                echo 11;
        }
}

雖然require_once在use下面,也是能夠正常運行的,由於程序只有在new mynameA()的時候纔去加載命名空間myname,use至關於一種聲明。ide

5.有命名空間的類,框架怎麼實現引入的工做呢?

此時有兩個函數能夠幫到你,__autoload()和spl_autoload_register().函數

當你引用不存在的類時,__autoload()就會被調用,而且你的類名會被做爲參數傳送過去(當你同時使用命名空間,包含命名空間部分會一塊兒做爲參數傳送)。測試

首先有一個類文件Aritst.class.php:

<?php 
 
class Aritst { 
 
 function doThing() {
  echo 'hello aritst!';
 }
}
?>

在你的index.php文件裏有個全局函數,能夠簡單的理解成這個樣子:

function __autoload($classname){
     $classpath="./".$classname.'.php';
     if(file_exists($classpath)){
     require_once($classpath);
     }
     else{
      echo 'class file'.$classpath.'not found!';
     }
}

在index.php中去實例化Artist類

$obj = new Artist();
$obj->doThing();

運行index.php後正常輸出hello aritst!。
在index.php中,因爲沒有包含Aritst.class.php,在實例化Aritst時,自動調用__autoload函數,參數$class的值即爲類名Aritst,此時Aritst.class.php就被引進來了。

__autoload能夠有不少寫法和不一樣的用法,php框架在此基礎上能夠添加命名空間的映射,實現根據命名空間加載對應目錄的工做。

再看spl_autoload_register(),這個函數與__autoload有與曲同工之妙,當看個簡單的例子:

<?
function autoRequire( $class ) {
 $file = $class . '.class.php';  
 if (is_file($file)) {  
  require_once($file);  
 } 
} 
 
spl_autoload_register( 'autoRequire' ); 

$obj = new PRINTIT();
$obj->doPrint();
?>

它告訴PHP碰到沒有定義的類就執行autoRequire()。

6.composer內部的命名空間又是怎麼維護的?

兄弟,引入幾個有現代php編碼風格的開發包,而後打開你的composer.json文件,認真的閱讀它,

"autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    },

在這裏,指明瞭命名空間和目錄結構映射的關係,若是你想個性化定製命名空間,能夠在這裏添加上,好比:

"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Martistcn\\" : "app/martistcn"
    } 
},

運行composer命令:

composer dumpautoload

就會增長一條映射關係:

// vendor/composer/autoload_psr4.php
return array(
    'App\\' => array($baseDir . '/app'),
    / ***** /
    'Martistcn\\' => array($baseDir . '/app/martistcn'),
);

so,有址可循。

相關文章
相關標籤/搜索