摘要:更多參考自動加載機制命名空間命名沖突在團隊協作引入第三方依賴代碼時,往往可能會出現類函數和接口重名的情況。多個有同名函數時,引入將發生命名沖突,使用來指明使用哪個的函數。
原文:wuYin/blog,轉載注明來源即可。
前言Laravel 框架因為其組件化的設計并恰當使用設計模式,使得框架本身簡潔易擴展。區別于 ThinkPHP 那種整合式功能的框架(功能要么全用要么全不用),Laravel 使用 composer 工具進行 package 的管理,想加功能直接添加組件即可。比如你寫爬蟲使用頁面采集組件: composer require jaeger/querylist
本文簡要介紹 Laravel 中頻繁用到的 PHP 特性與新語法,具體可參考。
組件化開發Laravel 進行組件化開發,得益于遵循 PSR-4 規范的 composer 工具,其利用命名空間和自動加載來組織項目文件。更多參考:composer 自動加載機制
命名空間 命名沖突在團隊協作、引入第三方依賴代碼時,往往可能會出現類、函數和接口重名的情況。比如:
因為同時定義了類 User 導致命名沖突:
解決辦法從 PHP 5.3 開始引入,參考 PHP 手冊 能知道命名空間有 2 個作用:避免命名沖突、保持命名簡短。比如使用命名空間后:
name . PHP_EOL; } }name . PHP_EOL; } } /* 保持了命名簡短 */ // 如果沒有命名空間,為了類名也不沖突,可能會出現這種函數名 // $user = new Google_User(); // Zend 風格并不提倡 $user = new GUser(); // 為了函數名也不沖突,可能會出現這種函數名 // $user->google_get_name() $user->getName(); $user = new User(); $user->getName();運行:
$ php demo.php google minePSR 規范其實 namespace 與文件名無關,但按 PSR 標準要求:命名空間與文件路徑一致 & 文件名與類名一致。比如 Laravel 默認生成的 laravel-demo/app/Http/Controllers/Auth/LoginController.php,其命名空間為 AppHttpControllersAuth & 類名為 LoginController
遵循規范,上邊的 mine.php 和 google.php 都應叫 User.php
namespace 操作符與__NAMESPACE__ 魔術常量... // $user = new User(); $user = new namespaceUser(); // 值為當前命名空間 $user->getName(); echo __NAMESPACE__ . PHP_EOL; // 直接獲取當前命名空間字符串 // 輸出 Mine三種命名空間的導入全局命名空間如果引用的類、函數沒有指定命名空間,則會默認在當在 __NAMESPACE__下尋找。若要引用全局類:
多重導入與多個命名空間// use 可一次導入多個命名空間 use Google, Microsoft; // 良好實踐:每行一個 use use Google; use Microsoft;導入常量、函數從 PHP 5.6 開始,可使用 use function 和 use const 分別導入函數和常量使用:
# google.php const CEO = "Sundar Pichai"; function getMarketValue() { echo "770 billion dollars" . PHP_EOL; }# mine.php use function GooglegetMarketValue as thirdMarketValue; use const GoogleCEO as third_CEO; thirdMarketValue(); echo third_CEO;運行:
$ php mine.php google 770 billion dollars Sundar Pichaimine Mine文件包含 手動加載使用 include 或 require 引入指定的文件,(字面理解)需注意 require 出錯會報編譯錯誤中斷腳本運行,而 include 出錯只會報 warning 腳本繼續運行。
include 文件時,會先去 php.ini 中配置項 include_path 指定的目錄找,找不到才在當前目錄下找:
自動加載void?__autoload(string?$class?) 能進行類的自動加載,但一般都使用 spl_autoload_register 手動進行注冊:
在 composer 生成的自動加載文件 laravel-demo/vendor/composer/autoload_real.php 中可看到:
class ComposerAutoloaderInit8b41a { private static $loader; public static function loadClassLoader($class) { if ("ComposerAutoloadClassLoader" === $class) { // 加載當前目錄下文件 require __DIR__ . "/ClassLoader.php"; } } public static function getLoader() { if (null !== self::$loader) { return self::$loader; } // 注冊自己的加載器 spl_autoload_register(array("ComposerAutoloaderInit8b41a6", "loadClassLoader"), true, true); self::$loader = $loader = new ComposerAutoloadClassLoader(); spl_autoload_unregister(array("ComposerAutoloaderInit8b41a6a", "loadClassLoader")); ... } ... }這里只提一下,具體 Laravel 整體是怎么做自動加載的,后邊的文章會細說。
反射參考 PHP 手冊,可簡單的理解為在運行時獲取對象的完整信息。反射有 5 個類:
ReflectionClass // 解析類名 ReflectionProperty // 獲取和設置類屬性的信息(屬性名和值、注釋、訪問權限) ReflectionMethod // 獲取和設置類函數的信息(函數名、注釋、訪問權限)、執行函數等 ReflectionParameter // 獲取函數的參數信息 ReflectionFunction // 獲取函數信息比如 ReflectionClass 的使用:
name = $name; $this->age = $age; } public function intro() { echo "[name]: " . $this->name . PHP_EOL; echo "[age]: " . $this->age . PHP_EOL; } } reflect("User"); // ReflectionClass 反射類使用示例 function reflect($class) { try { $ref = new ReflectionClass($class); // 檢查是否可實例化 // interface、abstract class、 __construct() 為 private 的類均不可實例化 if (!$ref->isInstantiable()) { echo "[can"t instantiable]: ${class} "; } // 輸出屬性列表 // 還能獲取方法列表、靜態常量等信息,具體參考手冊 foreach ($ref->getProperties() as $attr) { echo $attr->getName() . PHP_EOL; } // 直接調用類中的方法,個人認為這是反射最好用的地方 $obj = $ref->newInstanceArgs(); $obj->intro(); } catch (ReflectionException $e) { // try catch 機制真的不優雅 // 相比之下 Golang 的錯誤處理雖然繁瑣,但很簡潔 echo "[reflection exception: ]" . $e->getMessage(); } }運行:
$ php reflect.php name age [name]: Laruence [age]: 35其余 4 個反射類參考手冊 demo 即可。
后期靜態綁定參考 PHP 手冊,先看一個例子:
輸出:
$ php late_static_bind.php [called]: Base [called]: Child在對象實例化時,self:: 會實例化根據定義所在的類,static:: 會實例化調用它的類。
trait 基本使用參考 PHP 手冊,PHP 雖然是單繼承的,但從 5.4 后可通過 trait 水平組合“類”,來實現“類”的多重繼承,其實就是把重復的函數拆分成 triat 放到不同的文件中,通過 use 關鍵字按需引入、組合。可類比 Golang 的 struct 填鴨式組合來實現繼承。比如:
logger = $logger; } public function log($message, $level) { $this->logger->log($message, $level); } } class Foo { // 直接引入 Loggable 的代碼片段 use Loggable; } $foo = new Foo; $foo->setLogger(new DemoLogger); $foo->log("trait works", 1);運行:
$ php trait.php [message]: trait works [level]: 1更多參考:我所理解的 PHP Trait
重要性質 優先級當前類的函數會覆蓋 trait 的同名函數,trait 會覆蓋父類的同名函數( use trait 相當于當前類直接覆寫了父類的同名函數)
trait 函數沖突同時引入多個 trait 可用 , 隔開,即多重繼承。
多個 trait 有同名函數時,引入將發生命名沖突,使用 insteadof 來指明使用哪個 trait 的函數。
重命名與訪問控制使用 as 關鍵字可以重命名的 trait 中引入的函數,還可以修改其訪問權限。
其他trait 類似于類,可以定義屬性、方法、抽象方法、靜態方法和靜態屬性。
下邊的蘋果、微軟和 Linux 的小栗子來說明:
getMarketValue(); // trait 中可以定義靜態方法 $linux::staticFunc(); // 在 trait Top 中已解決過沖突,輸出庫克 $linux->getCEO(); // $linux->noCEO(); // Uncaught Error: Call to private method Linux::noCEO() // trait 中可以定義靜態變量 $linux->staticValue(); $linux->staticValue();運行:
$ php trait.php [Linux Market Value]: Infinity [MicroSoft Static Function] [Apple CEO]: Tim Cook [MicroSoft Static Value]: 1 [MicroSoft Static Value]: 2總結本節簡要提及了命名空間、文件自動加載、反射機制與 trait 等,Laravel 正是恰如其分的利用了這些新特性,才實現了組件化開發、服務加載等優雅的特性。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28778.html
摘要:判斷是否存在構造函數,不存在直接實例化,存在則通過來獲取輸入函數,并有相應的方法解決依賴參數問題,實現依賴注入。 Laravel 框架關鍵技術解析·讀書筆記(一) 第一章 入口文件 請求訪問的入口文件,主要完成幾部分工作,分別是: 自動加載函數的添加 服務器實例化與服務注冊 路由加載 請求實例化與路由分發 相應生成與發送 其中,自動加載函數用于包含引用文件,改文件是composer...
摘要:一路由目錄眾所周知,對于我們熟知的任何一款框架,例如路由系統都是極其重要的存在。文件用于定義界面的路由。定義在中的路由都是無狀態的,并且被分配了中間件組。生成的控制器為每個行為保留了方法,同時還包括了處理動作和的聲明注釋。 一、路由目錄 眾所周知,對于我們熟知的任何一款PHP框架,例如TP、CI、YII、路由系統都是極其重要的存在。 對于laravel框架也一樣,對于數據庫的操作,無非...
摘要:全書分三大部分共章第章介紹的基礎知識安裝和基本語法第章介紹的基本編程機器學習基礎及中常用的第三方庫函數,并介紹數據預處理的基本方法第章分別介紹常用的機器學習分析算法及深度學習等。每章都采用多個經典案例圖文并茂地介紹機器學習的原理和實現方法。 最近在學習Java和全棧開發,推薦一些有用的書籍 書架主要針對Java后端和全棧開發用的 書籍介紹 《Spring Boot 2.0企業級應用開發...
摘要:全書分三大部分共章第章介紹的基礎知識安裝和基本語法第章介紹的基本編程機器學習基礎及中常用的第三方庫函數,并介紹數據預處理的基本方法第章分別介紹常用的機器學習分析算法及深度學習等。每章都采用多個經典案例圖文并茂地介紹機器學習的原理和實現方法。 最近在學習Java和全棧開發,推薦一些有用的書籍 書架主要針對Java后端和全棧開發用的 書籍介紹 《Spring Boot 2.0企業級應用開發...
閱讀 986·2021-09-26 10:15
閱讀 2064·2021-09-24 10:37
閱讀 2580·2019-08-30 13:46
閱讀 2631·2019-08-30 11:16
閱讀 2421·2019-08-29 10:56
閱讀 2591·2019-08-26 12:24
閱讀 3473·2019-08-23 18:26
閱讀 2662·2019-08-23 15:43