摘要:更多参考自动加载机制命名空间命名冲突在团队协作引入第三方依赖代码时,往往可能会出现类函数和接口重名的情况。多个有同名函数时,引入将发生命名冲突,使用来指明使用哪个的函数。
原文: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 正是恰如其分的利用了这些新特性,才实现了组件化开发、服务加载等优雅的特性。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/28778.html
摘要:判断是否存在构造函数,不存在直接实例化,存在则通过来获取输入函数,并有相应的方法解决依赖参数问题,实现依赖注入。 Laravel 框架关键技术解析·读书笔记(一) 第一章 入口文件 请求访问的入口文件,主要完成几部分工作,分别是: 自动加载函数的添加 服务器实例化与服务注册 路由加载 请求实例化与路由分发 相应生成与发送 其中,自动加载函数用于包含引用文件,改文件是composer...
摘要:一路由目录众所周知,对于我们熟知的任何一款框架,例如路由系统都是极其重要的存在。文件用于定义界面的路由。定义在中的路由都是无状态的,并且被分配了中间件组。生成的控制器为每个行为保留了方法,同时还包括了处理动作和的声明注释。 一、路由目录 众所周知,对于我们熟知的任何一款PHP框架,例如TP、CI、YII、路由系统都是极其重要的存在。 对于laravel框架也一样,对于数据库的操作,无非...
摘要:全书分三大部分共章第章介绍的基础知识安装和基本语法第章介绍的基本编程机器学习基础及中常用的第三方库函数,并介绍数据预处理的基本方法第章分别介绍常用的机器学习分析算法及深度学习等。每章都采用多个经典案例图文并茂地介绍机器学习的原理和实现方法。 最近在学习Java和全栈开发,推荐一些有用的书籍 书架主要针对Java后端和全栈开发用的 书籍介绍 《Spring Boot 2.0企业级应用开发...
摘要:全书分三大部分共章第章介绍的基础知识安装和基本语法第章介绍的基本编程机器学习基础及中常用的第三方库函数,并介绍数据预处理的基本方法第章分别介绍常用的机器学习分析算法及深度学习等。每章都采用多个经典案例图文并茂地介绍机器学习的原理和实现方法。 最近在学习Java和全栈开发,推荐一些有用的书籍 书架主要针对Java后端和全栈开发用的 书籍介绍 《Spring Boot 2.0企业级应用开发...
阅读 991·2021-09-26 10:15
阅读 2073·2021-09-24 10:37
阅读 2585·2019-08-30 13:46
阅读 2635·2019-08-30 11:16
阅读 2425·2019-08-29 10:56
阅读 2596·2019-08-26 12:24
阅读 3479·2019-08-23 18:26
阅读 2665·2019-08-23 15:43