当前位置: 首页 > 后端技术 > PHP

让你深入了解yii2

时间:2023-03-29 15:20:55 PHP

的九个概念与laravel相比,Yii2将配置(依赖定义)外化,使用行为(更类似于python中的编织)类来弥补Trait的一些不足。好处是Actions可以动态扩展。至于事件处理,大同小异。有意思的是,在命名上,yii2借用了jquery事件系统的一套,on,off,trigger。当然也有相似之处,比如应用都是建立在容器之上的。与其他面向领域和面向接口的编程相比,Yii2使用模块对小型应用进行分层、分中心、细化大型架构。还有getter/setter,还有filter,java痕迹太明显了。组件是ComponentYii应用程序的主要构建块。yii\base\Component类或其子类的实例主要由属性(Property)、事件(Event)和行为(Behavior)组成。它们比常规对象(Object)稍重,需要额外的内存和CPU时间来处理事件和行为当不需要事件和行为时,继承自yii\base\Object,支持属性(Property)函数重写Component或Object,总是调用父类的构造函数pass在重写的构造函数的最后输入$config作为构造函数方法的最后一个参数,由父构造函数调用并在应用配置之前进行初始化。如果重写BaseObject::init()方法,确保init方法开头调用的是父类的init方法组件实例实例化组件类有2种方式,新建组件类,组件公用参数+ 组件配置属性参数,通过\Yii::createObject静态方法创建组件实例。第一个数组参数类关联的是组??件类名,后面关联的元素依次是组件实例属性和第二个数组参数的值。组件的公共参数。Yii::createObject()基于依赖注入容器。执行yii\base\BaseObject类的生命周期。构造方法中的预初始化过程是通过$config配置的。init()方法用于调用完成工作对象初始化后的方法。以上步骤都是在对象的构造方法中完成的,即实例已经初始化完毕,可以使用了。PropertyYii引入yii\base\Object的基类,支持类内基于Getter和setter(reader和setter)方法定义属性getter和setter定义属性规则和限制此类属性的名称不区分大小写,源自PHP方法名是不区分大小写的如果是类属性名与类成员变量相同,以后者为准。类属性不支持可见性(访问限制)。此类属性的getter和setter方法只能定义为非静态的。不确定是否有魔法方法(getter或setter)正常调用property_exists()不会生效。如果有这样的需求,使用canGetProperty()orcanSetProperty()Events事件可以将自定义代码“注入”到现有代码中的特定执行点,将自定义代码附加到某个Event上,当这个事件被触发时,这些代码会自动执行事件处理EventHandlers事件处理程序是一个PHP回调函数,或者以可调用对象字符串的形式指定的PHP全局函数,例如以'trim'对象名称和方法名称的数组形式指定的对象方法,[$object,$method]以类名和方法名数组的形式指定的静态类方法,如[$class,$method]匿名函数,如function($event){...}事件对象$eventeventname:eventnameeventsender:calltr??igger()方法的对象customdata附加事件处理器时传入的数据,默认为空附加的事件处理器调用组件类的on方法,如\yii\base\Component::on()publicvoidon($name,$handler,$data=null,$append=true)事件处理程序顺序(EventHandlerOrder)当事件被触发时,附加的处理程序将按照顺序调用添加。如果需要停止同一事件后续处理程序的调用,可以将event参数的yii\base\Event::event参数的'yii\base\Event::handled属性设置为true。当第四个参数$append为false时,可以在处理器队列的最前面插入一个新的处理器触发事件??(TriggeringEvents),事件通过调用yii\base\Component::trigger()方法触发publicvoidtrigger($name,yii\base\Event$event=null)建议使用类常量表示事件名称,事件对象必须是yii\basehandler=null)类级别的事件处理程序应用场景希望一个类的所有实例都响应一个触发的事件调用静态方法yii\base\Event::on()在类级别的事件处理程序内部附加处理程序,通过$event->sender获取触发事件的对象当对象触发事件时,首先调用实例级处理程序,然后调用类级处理程序静态方法yii\base\Event::trigger()触发类级事件,去掉签名publicstaticbooleanoff($class,$name,$handler=null)withoff调用Event::on()并使用接口类名作为第一个Aparameter在实现该接口的事件类中可以触发该事件,但并不是所有实现该接口的类都可以触发该事件全局事件需要一个全局可访问的单例,比如不调用自身trigger()方法的应用实例事件触发器,而是调用单例的trigger()方法触发全局事件。优点是在给对象触发的事件附加处理程序时,不需要生成对象的通配符事件WildcardEventsfoo.event.*,通配符模式支持实例或类级别的事件行为行为是yii\base\Behavior或其子类的实例,也称为mixins,类似于原生Trait函数,可以在不改变类继承关系的情况下增强现有的组件类。当行为附加到组件后,会将其方法和属性“注入”到组件的行为中,组件可以通过这些行为响应触发的事件,从而自定义或调整组件正常执行处理的代码事件使行为响应对应组件的事件触发,应该重写yii\base\Behavior::events()方法行为的events()方法返回事件列表和对应的处理程序,并指定事件处理程序格式如下指向行为类的方法名的字符串对象或者类名和方法名的数组,如[$object,'methodName'];匿名方法附加行为覆盖要附加的组件类的behaviors()方法的静态附加行为behaviors()方法返回一个行为配置列表,每个行为配置可以是一个行为类名或者是配置数组和对应的指定行为配置数组的key可以为行为关联一个名称。这种行为称为命名行为。相反,匿名行为或命名行为动态附加行为并在相应组件中调用yii\base\Component::attachBehavior()。方法或yii\base\Component::attachBehaviors()方法一次附加多个行为publicvoidattachBehaviors(array$behaviors)通过配置附加行为['asmyBehavior2'=>MyBehavior::className()]行为必须首先附加到component类或其子类组件,则可以通过访问组件来访问行为的公共成员变量。如果两个行为都定义了相同的属性或方法,并且都附加到同一个组件,那么先附加的优先将行为附加到组件的命名行为,可以使用这个名称来访问行为对象,$组件->getBehavior('myBehavior');获取所有附加到该组件的行为getBehaviors()移除行为可以调用yii\base\Component::detachBehavior()方法使用与行为关联的名称实现Yii2内置行为类yii\behaviors\TimestampBehavior来存储在ActiveRecord中时自动更新其时间戳属性。自动填充指定的属性,其值可以在URL中使用,如slugyii\behaviors\AttributeBehavior在特定事件发生时自动为ActiveRecord对象的一个??或多个属性赋值yii2tech\ar\softdelete\SoftDeleteBehavior提供软删除和软恢复ActiveRecord的yii2tech\ar\position\PositionBehavior方法允许通过提供重排序方法BehaviorVSTraits将自己的属性和方法“注入”到主类中,两者类似互补类和不可替代行为类的优点行为类像普通类一样支持继承行为可以在不修改组件类的情况下动态附加到组件或从组件中删除行为是可配置的,而特征是不可行的行为可以通过响应事件来定制代码componentstraits的执行Traits之所以多比Behaviors更高效的地方在于,Behaviors是需要时间和内存的对象,导致的命名冲突需要通过重命名受影响的属性或方法来手动解决。配置概述在创建新对象和初始化现有对象时使用配置。该值还可以包含一组将附加到对象事件的句柄,和一组将附加到对象的行为使用Yii::createObject()方法接受一个配置数组,并根据数组中指定的类名创建一个对象。对于已经存在的对象,可以使用Yii::configure()方法来配置来初始化它的属性Yii::configure($object,$config)注意如果配置一个已经存在的对象,配置数组不应该包含带有指定的类名。配置类元素的格式指定了要创建的对象的完整性。限定类名propertyName元素指定对象属性的初始值,键名是属性名,值是属性对应的初始值。只能配置由getter/setter定义的公共成员变量和属性。oneventName元素指定附加在对象上的事件句柄,数组的键名由on前缀和事件名组成。asbehaviorName元素指定附加到对象的行为,值表示创建的行为的配置信息。应用配置应用类有很多可配置的属性,事件组件属性可以通过应用接收配置数组并注册为组件yii2.0.11+系统配置支持使用container属性配置依赖注入容器widget配置yii\base\Widget::widget()和yii\base\Widget::begin()方法两者都可用于通过使用配置自定义其属性来创建小部件。请注意,当给出类名时,配置数组不需要包含类键。默认配置Yii::createObject()方法基于依赖注入容器。使用Yii::creatObject()创建对象时,它可以将一组默认配置附加到指定类的任何实例。默认配置可以通过在入口脚本中调用Yii::$container->set()来设置和解析别名来定义。使用Yii::setAlias()为文件路径或URL定义别名,调用Yii::getAlias()命令将根别名解析为相应的文件路径或URL。应用程序提供了一个名为aliases的可写属性,可以在应用程序配置中设置它以使用Yii中的别名PathpropertyacceptsaliasesYii2predefinedaliasesExtensionaliases通过Composer安装的扩展自动添加一个别名,在引导类自动加载期间定义YiiautoloaderEach类必须放在命名空间下,每个类都必须保存为单独的文件添加自定义命名空间以自动加载对于自动加载器,需要使用Yii::setAlias()为命名空间的根目录定义一个别名类映射。类映射函数建立了从类名到类文件路径的映射。映射表中有这样一个类吗?您可以使用Yii::$classMap方法将类添加到映射表。其他自动加载器在其他自动加载器安装成功后,包含Yii.php(yii的自动加载器)使Yii成为第一个响应任何类自动加载请求的自动加载器。Yii自动加载器支持自动加载扩展类。autoload部分需要在composer.json文件中正确定义。服务定位器定义提供了各种应用程序。服务定位器中服务(或组件)的对象,每个组件只有一个实例,由ID唯一标识在Yii中,服务定位器是yii\di\ServiceLocator或其子类的实例最常用应用场景中的服务定位器是应用(application)对象,可以通过\Yii::$app访问。每个模块对象本身也是一个服务定位器。模板可以看作是一个子应用程序。使用服务定位器注册相关组件通过yii\di\ServiceLocator::set()方法注册相关组件publicvoidset($id,$definition)$definition可以是类名、配置数组、php可调用对象或对象实例本身允许通过组件ID访问组件,就像访问属性值一样定位器将返回相同的一个组件的单例yii\di\ServiceLocator::has()检查一个组件ID是否被注册yii\di\ServiceLocator::get()Tree遍历模块允许任意嵌套;Yii应用程序本质上是模块树模块中组件的配置永远不会与父模块中组件的配置合并依赖注入容器依赖注入容器是一个知道如何初始化和配置对象以及所有对象的对象它依赖于Yii,通过yii\di\Container类提供DI容器特性构造注入容器会尝试获取它所依赖的类或接口的实例,然后通过构造方法注入到一个新的对象中,方法注入可以提供依赖setter和属性注入setter只需要类的单个方法,而属性注入是通过配置提供的,会通过相应的Setter或property提供给容器注入依赖。PHP可调用注入(PHPCallableInjection)容器将使用注册的PHP回调来构造类yii\di\的新实例Container::get()方法将其第三个参数作为配置数组应用到正在创建的对象中Registerdependenciesforclassconstructors使用yii\di\Container::set()来注册依赖注册会使用一个依赖名和一个依赖定义,键值对可以递归,方便容器管理实例,类似于laravel的别名系统依赖name可以是类名,接口名或者别名,依赖的定义可以是类名,配置数组,通过set()注册的PHP回调,每次都会生成一个新的实例使用yii\di\Container::setSingleton()来注册一个单例的依赖解析。依赖解析是递归的。注册依赖后,容器会自动解析依赖,实例化依赖并注入到新创建的对象中。依赖名,可以通过set()或setSingleton()注册,也可以是类的构造函数参数数字列表和配置用于配置新创建的对象。当使用依赖注入在应用程序的入口脚本中引入Yii.php文件时,Yii会创建一个DI容器。调用Yii::createObject()时可以通过Yii::$container访问DI容器,这个方法实际上会调用这个容器的get()方法来创建一个新的对象。组件调用中给出的属性将始终覆盖DI容器中的定义。如果报错无法实例化,需要通知容器如何处理依赖高级实用程序可以一次配置多个定义,将配置数组传递给setDefinitions()或setSingletons()方法配置数组格式键:类名、接口名或别名值:与类关联的定义,与类Defined关联,'identifies'参数值将传递给set()方法,可选地以依赖项的构造函数参数作为第三个参数Instance::of('tempFileStorage')符号,容器将隐式提供一个以tempFileStorage名称注册的依赖项应用场景内部配置依赖项通过set()注册的依赖项将在每次需要时实例化依赖项驻留(DI)容器在其之上实现其服务定位器.当服务定位器尝试创建新的对象实例时,它会将调用转发给DI容器。优秀的PHP架构师教程目录,只要你看得懂,保证你的薪水更上一层楼(持续更新中)。以上内容希望对大家有所帮助。很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写的太多了。没有方向感,不知道从哪里开始提高。我整理了一些资料,包括但不限于:分布式架构、高扩展性、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等知识点,需要进阶干货的可以免费分享给你。有需要的可以点击进阶PHP月薪30k>>>架构师成长之路【免费获取视频和面试资料】