stanx / extdirect
PHP 与 Ext.Direct 集成
Requires
- php: >=7.1
This package is auto-updated.
Last update: 2024-09-13 03:44:13 UTC
README
PHP 与 Ext.Direct 集成非常简单
原作者:J. Bruni
Fork:stanx
如何使用
- PHP
<?php require 'ExtDirect.php'; class Server { public function date($format) { return date($format); } } ExtDirect::provide('Server', true);
在这里,“服务器”是我们希望从 JavaScript 代码中提供访问的 PHP 类。它可以是任何其他类。
- HTML
<script type="text/javascript" src="ext-direct.php"></script>
在这里,“ext-direct.php”指向第1项中显示的 PHP 文件。如果您想为 Ext Designer 输出 API,必须添加“?json”查询字符串,因为默认输出是javascript格式。它可以由 $default_api_output
更改。
- JavaScript
Ext.php.Server.date( 'Y-m-d', function(result) { alert('Server date is ' + result); });
在这里,要调用 PHP “服务器”类中的“date”方法,我们在默认命名空间 Ext.php 前添加了前缀。第一个参数是 $format 参数。第二个参数是 AJAX 调用完成后将执行的 JavaScript 回调函数。这里,一个警告框显示了结果。
特性
- 使用多个类声明 API(不仅限于单个类)
- API
url
、namespace
和descriptor
设置(“ExtDirect”类在您不指定的情况下自动分配它们) - 两种 API 输出格式:
json
(用于与 Ext Designer 一起使用)和javascript
(默认:javascript) - 您可以选择操作“len”属性是否仅计算 PHP 方法的所需参数,还是计算所有参数(默认:所有参数)
- 您可以选择是否在 API 中声明继承的方法(默认:不声明)
- 您可以选择是否在 API 中声明静态方法(默认:不声明)
- 您可以选择是否从 API 中排除特定的公共方法(@extdirect-exclude)
- 如果调用的是静态方法,是否实例化对象?您选择!(默认:不实例化)
- 是否使用操作参数调用类构造函数?您选择!(默认:不调用)
- “debug”选项用于在 API 操作结果输出中发送服务器异常(默认:关闭)
- “utf8_encode”选项用于在 API 操作结果中自动应用 UTF8 编码(默认:关闭)
- 您可以选择是否将参数转换为关联数组(默认:不转换)
- 处理表单
- 处理文件上传 配置 - 如何操作
简单。如果配置选项名称是“configuration_name”,并且配置值是 $value,使用此语法
ExtDirect::$configuration_name = $value;
就是这样。
配置选项
- name:
api_classes
type: 字符串数组或键值对
meaning: 发布到 Ext.Direct API 的类名。可以是字符串或键值对:键是 API 名称,值是类。
default:empty
comments: 如果您为ExtDirect::provide
方法提供了非空的api_classes
参数,则此选项将被覆盖。选择一个或另一个。如果您想声明单个类,可以将api_classes
设置为字符串,而不是数组
example
ExtDirect::$api_classes = ['MyClass', 'AnotherClass'=>'MyNamespace\\AnotherClass'];
- name:
api_classes_discovery_dirs
type: 数组 meaning: 这些目录将被递归扫描,并添加具有@extdirect-api
属性的类到api_classes
选项。
键是路径,值是命名空间。
default:empty
comments: 警告:如果发现目录中有许多文件,此选项可能会减慢响应时间。您可以从ExtDirect::discover_api_classes()
获取发现类并将它们保存到缓存中
example
ExtDirect::$api_classes_discovery_dirs = [__DIR__ . '/MyNamespace/MyAPI' => 'MyNamespace\\MyAPI'];
- name:
url
type: 字符串
meaning: Ext.Direct API 属性 "url"
default:$_SERVER['PHP_SELF']
comments: 有时,PHP_SELF 可能不是我们想要的。因此,可以手动指定 API URL
example
ExtDirect::$url = '/path/to/my_php_script.php';
- name:
namespace
type: 字符串
意义:Ext.Direct API 属性 "namespace"
默认值:Ext.php
注释:请根据 ExtJS 的命名空间规则自由选择您的命名空间。
example
ExtDirect::$namespace = 'Ext.php';
- 名称:
descriptor
type: 字符串
意义:Ext.Direct API 属性 "descriptor"
默认值:Ext.php.REMOTING_API
注释:请根据 ExtJS 的规则和所选命名空间自由选择您的描述符。
example
ExtDirect::$descriptor = 'Ext.php.REMOTING_API';
- 名称:
id
type: 字符串
意义:Ext.Direct 提供者属性 "id"
default:empty
example
ExtDirect::$id = 'MyProvider';
- 名称:
max_retries
类型:int
意义:调用失败时重新尝试发送的次数
默认值:1
example
ExtDirect::$max_retries = 1;
- 名称:
timeout
类型:int
意义:在此远程 API 中,每个方法调用使用的超时时间(毫秒)
默认值:30000
example
ExtDirect::$timeout = 30000;
- 名称:
count_only_required_params
类型:boolean
意义:将此设置为 true 以仅计算方法的 API "len" 属性的必需参数
默认值:false
example
ExtDirect::$count_only_required_params = true;
- 名称:
include_static_methods
类型:boolean
意义:将此设置为 true 以在 API 声明中包含静态方法
默认值:false
example
ExtDirect::$include_static_methods = true;
- 名称:
include_inherited_methods
类型:boolean
意义:将此设置为 true 以在 API 声明中包含继承的方法
默认值:false
example
ExtDirect::$include_inherited_methods = true;
- 名称:
instantiate_static
类型:boolean
意义:将此设置为 true 以创建一个类对象实例,即使被调用的方法是静态的
默认值:false
example
ExtDirect::$instantiate_static = true;
- 名称:
constructor_send_params
类型:boolean
意义:将此设置为 true 以调用动作类构造函数并向其发送动作参数
默认值:false
example
ExtDirect::$constructor_send_params = true;
- 名称:
constructor_params
类型:array
意义:要发送到类构造函数的参数(使用类键作为名称)
默认值:[]
example
ExtDirect::$constructor_params = ['MyNamespace\\MyClass' => ['param1', 'param2']];
- 名称:
debug
类型:boolean
意义:将此设置为 true 以允许输出异常详细信息
默认值:false
example
ExtDirect::$debug = true;
- 名称:
utf8_encode
类型:boolean
意义:将此设置为 true 以通过 utf8_encode 函数传递所有动作方法调用的结果
默认值:false
example
ExtDirect::$utf8_encode = true;
- 名称:
params_enforce_associative
类型:boolean
意义:将此设置为 true 以通过 json_decode(json_encode($params), true) 传递所有动作参数
默认值:false
example
ExtDirect::$params_enforce_associative = true;
- 名称:
default_api_output
类型:string 意义:API 输出格式 - 可用选项为 "json"(适用于 Ext Designer)和 "javascript"
默认值:javascript
注释:另一种强制 "json" 输出的方法是,在您的 PHP 脚本 URL 的末尾附加 "?json" 查询字符串;在引用您的 API 的 HTML<script>
标签中这样做
example
ExtDirect::$default_api_output = 'javascript';
表单处理器
有两种不同的方法可以将方法标记为 formHandler
。
方法 1:使用新的 ExtDirect::$form_handlers
配置选项。
- 名称:
form_handlers
类型:字符串数组
意义:要标记为 Ext.Direct API 中的 formHandler 的类/方法名称
默认值:[]
注释:每个方法的字符串格式必须是 "className::methodName"
example
ExtDirect::$form_handlers = ['someClass::someMethod', 'MyNamespace\\Server::date'];
方法 2:在方法的 DOC 注释中包含 @extdirect-formHandler
。
示例
class FTP_Manager { /** * Sets FTP password for a specific account * * @extdirect-formHandler * @param string $account Name of the account * @param string $password New password * @param string $password_confirm New password confirmation * @return string */ public function set_ftp_password($account, $password, $password_confirm) { // do stuff return 'result'; } }
在上面的示例中,由于方法 DOC 注释中的 @extdirect-formHandler
字符串,它将被标记为 formHandler
方法。
它具有与以下相同的效果
ExtDirect::$form_handlers[] = 'FTP_Manager::set_ftp_password';
接收参数
表单发送的参数被调整为可以由类方法接收。
请注意,这不是常规操作。
我将使用上面的 "set_ftp_password" 方法作为示例。
首先,请注意我们不想所有 formHandler
方法都有相同的不友好签名,如下所示
function set_ftp_password($data){}; function do_something($data){}; function do_something_completely_different($data){};
$data
是用户输入(通常是 $_POST
)
因此,为了能够保持正常的方法签名,如下所示...
function set_ftp_password($account, $password, $password_confirm){}
...我已经实现了以下解决方案
当方法/操作函数是 formHandler
时,其参数值是从与参数名称匹配的输入名称中获取的。
所以... $_POST['account']
将自动成为 $account
参数...
$_POST['password']
的值将是 $password
参数的值...
...那么 $password_confirm
参数的值从哪里来?是的!从 $_POST['password_confirm']
就是这样:方法参数的名称与 $_POST
数组的键匹配。
优点
- 不需要担心参数顺序
- 可以使用有意义且清晰的函数签名
- 不需要检查
$_POST
数组 - ExtDirect 控制器会为我们做这件事(忘记 "isset" 检查...如果某个参数值未在$_POST
数组中设置,则传递默认值(如果有)或 null 给方法/函数)
缺点
- 输入名称必须与方法/函数参数名称匹配(在我看来,这是一个优点!)
- 这种方法可能并不适合你(在这种情况下,只需忽略所有这些内容,直接使用
$_POST
/$_GET
/$_REQUEST
数组!)
当然,所有输入数据的验证/过滤/净化都必须仔细考虑。
关于文件上传的附加说明
如果你的文件输入名称是 userFile
,它将作为名为 $userFile
的参数可用
换句话说:你的 $userFile
参数将接收到来自 $_FILES['userFile']
的值
拦截函数
declare_method_function
authorization_function
instantiate_function
transform_result_function
transform_response_function
使用 declare_method_function
,你可以确定是否允许方法声明。
现在,你能够指定一个 authorization_function
,在那里你可以检查用户权限并相应地返回 true 或 false,允许或不允许 API 调用。
instantiate_function
将在 API 动作调用中调用,以实例化类的对象。如果你使用 DI 容器实例化类,这将很有用。
使用 transform_result_function
,你可以在 API 方法调用执行后修改其结果,但在发送到客户端之前。
最后,使用 transform_response_function
,你可以修改响应结构。这允许触发服务器端事件,并将额外的服务器端数据与 RPC 结果一起发送。
// New configuration option ExtDirect::$id = 'my_api'; // All "function" configurations accept parameters of callback type ExtDirect::$declare_method_function = 'declare_method'; ExtDirect::$authorization_function = 'authorize'; ExtDirect::$instantiate_function = 'instantiate'; ExtDirect::$transform_result_function = 'transform_result'; ExtDirect::$transform_response_function = 'transform_response'; function declare_method(string $class, string $method) : bool { // return boolean - declare the method in the API or not return in_array($class . '::' . $method, MyFramework::$user->permissions); } function authorize(ExtDirectAction $action, callable $callback, array $parameters) : bool { // return boolean - authorize the action call or not return declare_method($action->class, $action->method); } function instantiate(ExtDirectAction $action) : object { // return instance of class return DI::get($action->class); } function transform_result(ExtDirectAction $action, mixed $result) : mixed { if ($action->form_handler) $result = ['success' => $result]; // return modified result return $result; } function transform_response(ExtDirectAction $action, array $response) : array { $response['error_msg'] = MyFramework::$errors; $response['success_msg'] = MyFramework::$success; // return modified response return $response; }