将 Sencha Ext JS Ext.direct 集成到 PHP 应用程序中的基本组件
该库为 Sencha Ext.direct提供服务器端实现,这是一个 RPC 风格的通信组件,是 Sencha 的Ext JS和Sencha Touch的一部分。
ext direct是一种与平台和语言无关的远程过程调用 (RPC) 协议。 ext direct允许 Ext JS 应用程序的客户端与任何符合规范的服务器平台之间进行无缝通信。 ext direct是无状态且轻量级的,支持 API 发现、调用批处理和服务器到客户端事件等功能。
目前,该库仅用作 teqneers/ext-direct-bundle 的基础,teqneers/ext-direct-bundle 是一个将 * Ext.direct* 集成到基于 Symfony 的应用程序中的 Symfony 包。我们没有尝试将该库用作独立组件或在除 Symfony 环境之外的任何其他上下文中使用,因此以下只是理论上它在没有捆绑包的情况下应该如何工作。我们非常感谢任何帮助和贡献,以使该库在捆绑包之外更有用。
您可以使用composer安装这个库
composer require teqneers/ext-direct
或者直接将包添加到您的composer.json 文件中。
命名策略决定如何将 PHP 类名和命名空间转换为 Javascript 兼容的Ext.direct操作名称。默认命名策略将 namspapce 分隔符转换为
.
。因此MyNamespaceService
被翻译为My.namespace.Service
。请注意,转换必须是可逆的( My.namespace.Service
=> MyNamespaceService
)。
$ namingStrategy = new TQ ExtDirect Service DefaultNamingStrategy ();
服务注册表使用jms/metadata
数据库中的元数据工厂和关联的注释驱动程序(该驱动程序又使用doctrine/annotations
注释读取器)来读取有关可能的注释服务类的元信息。
$ serviceRegistry = new TQ ExtDirect Service DefaultServiceRegistry (
new Metadata MetadataFactory (
new TQ ExtDirect Metadata Driver AnnotationDriver (
new Doctrine Common Annotations AnnotationReader ()
)
),
$ namingStrategy
);
可以通过调用addServices()
或addService()
或使用TQExtDirectServiceServiceLoader
导入服务来手动填充服务注册表。默认实现TQExtDirectServicePathServiceLoader
可以从一组给定路径读取类。
事件调度程序是可选的,但需要使用参数转换和验证、分析侦听器的结果转换等功能。
$ eventDispatcher = new Symfony Component EventDispatcher EventDispatcher ();
路由器用于将传入的Ext.direct请求转换为对正确服务类的 PHP 方法调用。 ContainerServiceFactory
支持从 Symfony 依赖注入容器检索服务或实例化根本不需要构造函数参数的简单服务。静态服务调用绕过服务工厂。
$ router = new TQ ExtDirect Router Router (
new TQ ExtDirect Router ServiceResolver (
$ serviceRegistry ,
new TQ ExtDirect Service ContainerServiceFactory (
/* a SymfonyComponentDependencyInjectionContainerInterface */
)
),
$ eventDispatcher
);
端点对象是所有Ext.direct服务器端组件前面的外观。通过其createServiceDescription()
方法,我们可以获得符合标准的 API 描述,而handleRequest()
接受SymfonyComponentHttpFoundationRequest
并返回SymfonyComponentHttpFoundationResponse
,其中包含服务调用的Ext.direct响应已收到。
$ endpoint = TQ ExtDirect Service Endpoint (
' default ' , // endpoint id
new TQ ExtDirect Description ServiceDescriptionFactory (
$ serviceRegistry ,
' My.api ' ,
$ router ,
new TQ ExtDirect Router RequestFactory (),
' My.api.REMOTING_API '
)
);
端点管理器只是端点的简单集合,允许使用端点 ID 进行检索。这允许轻松公开多个独立的 API。
$ manager = new TQ ExtDirect Service EndpointManager ();
$ manager -> addEndpoint ( $ endpoint );
$ defaultEndpoint = $ manager -> getEndpoint ( ' default ' );
$ apiResponse = $ defaultEndpoint -> createServiceDescription ( ' /path/to/router ' );
$ apiResponse -> send ();
$ request = Symfony Component HttpFoundation Request:: createFromGlobals ();
$ response = $ defaultEndpoint -> handleRequest ( $ request );
$ response -> send ();
可以通过使用传递到路由器的事件调度程序上的事件侦听器来操纵和增强路由过程。该库提供了四个事件订阅者,允许
附带的参数和结果转换器使用jms/serializer
库来提供扩展(反)序列化功能,而默认参数验证器则使用symfony/validator
库。
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener ArgumentConversionListener (
new TQ ExtDirect Router ArgumentConverter ( /* a JMSSerializerSerializer */ )
)
);
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener ArgumentValidationListener (
new TQ ExtDirect Router ArgumentValidator ( /* a SymfonyComponentValidatorValidatorValidatorInterface */ )
)
);
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener ResultConversionListener (
new TQ ExtDirect Router ResultConverter ( /* a JMSSerializerSerializer */ )
)
);
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener StopwatchListener (
/* a SymfonyComponentStopwatchStopwatch */
)
);
通过Ext.direct API 公开的服务必须使用适当的元信息进行修饰。目前这只能使用注释(例如 Doctrine、Symfony 或其他现代 PHP 库中已知的注释)。
每个将作为Ext.direct操作公开的服务类都需要使用TQExtDirectAnnotationAction
进行注释。对于既不是静态的也不能使用无参数构造函数实例化的服务, Action
注释可以选择采用服务 id 参数。
use TQ ExtDirect Annotation as Direct ;
/**
* @DirectAction()
*/
class Service1
{
// service will be instantiated using the parameter-less constructor if called method is not static
}
/**
* @DirectAction("app.direct.service2")
*/
class Service2
{
// service will be retrieved from the dependency injection container using id "app.direct.service2" if called method is not static
}
此外,在Ext.direct操作上公开的每个方法都需要使用TQExtDirectAnnotationMethod
进行注释。 Method
注释可以选择采用true
将方法指定为表单处理程序(采用常规表单帖子),或采用false
将方法指定为常规Ext.direct方法(这是默认值)。
/**
* @DirectAction("app.direct.service3")
*/
class Service3
{
/**
* @DirectMethod()
*/
public function methodA ()
{
// regular method
}
/**
* @DirectMethod(true)
*/
public function methodB ()
{
// form handler method
}
}
Ext.direct规范中描述的扩展功能(例如命名参数和严格命名参数)当前未通过注释系统公开。
进入通过Ext.direct请求调用的方法的参数也可以进行注释以应用参数验证。这要求TQExtDirectRouterEventListenerArgumentValidationListener
注册到适当的事件调度程序。
use Symfony Component Validator Constraints as Assert ;
/**
* @DirectAction("app.direct.service4")
*/
class Service4
{
/**
* @DirectMethod()
* @DirectParameter("a", { @AssertNotNull(), @AssertType("int") })
*
* @param int $a
*/
public function methodA ( $ a )
{
}
}
如果被调用方法的签名公开带有SymfonyComponentHttpFoundationRequest
和/或TQExtDirectRouterRequest
类型提示的参数,则传入的 Symfony HTTP 请求和/或原始Ext.direct请求会自动注入到方法调用中。这对于 form 表单处理方法尤其重要,因为没有其他方法可以访问传入的 HTTP 请求参数(表单 post)。
一旦启用TQExtDirectRouterEventListenerArgumentConversionListener
,就可以在服务方法上使用严格类型的对象参数。这些参数将自动从传入的 JSON 请求中反序列化,并注入到方法调用中。
从服务方法调用返回对象也是如此。如果启用TQExtDirectRouterEventListenerResultConversionListener
,则返回值会自动序列化为 JSON,即使它们是重要对象。
参数和返回值转换都基于 Johannes Schmitt 优秀的jms/serializer
库。请参阅文档以获取更多信息。
ext direct规范可以在 Sencha 的文档网站上找到。
麻省理工学院许可证 (MIT)
版权所有 (c) 2015 TEQneers GmbH & Co. KG
特此免费授予获得本软件和相关文档文件(“软件”)副本的任何人不受限制地使用本软件,包括但不限于使用、复制、修改、合并的权利、发布、分发、再许可和/或销售软件的副本,并允许向其提供软件的人员这样做,但须满足以下条件:
上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。
本软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有者均不对因本软件或本软件中的使用或其他交易而产生或与之相关的任何索赔、损害或其他责任负责,无论是合同、侵权行为还是其他行为。软件。