多平台统一管理软件接口,如何实现多平台统一管理软件接口
215
2023-10-19
首先,将之前清单中的文档块解析器与反射API集成在一起。通过扩展核心的Reflecticn
类并且将解析器作为静态方法添加进去,就可以做到这一点。
首先,将之前清单中的文档块解析器与反射API集成在一起。通过扩展核心的Reflecticn
类并且将解析器作为静态方法添加进去,就可以做到这一点。
代码显示了这一扩展。将这段代码和所有随后的反射类都放到一个名为
DocumentingReflection.php的公共的包含文件中。
集成文档注释解析器(DocumentingReflection.php)
Class DocumentingReflection extends Reflection{
Public static function ParseDocComment($docComment){
$returnData =$comments = $tags =$array();
$tagNames = $tagData = array();
$tokens =docblock_tokenize($docComment,true);
Foreach($tokens as $token){
Switch($token[0]){
Case DOCBLOCK_TEXT:
If(!isset($tagId)){
$comments[] = $token[1];
}else{
If(array_key_exists($tagId,$tagData)){
$tagData[$tagId] .=’’.trim($token[1]);
}else{
$tagData[$tagId] = trim($token[1]);
}
}
Break;
Case DOCBLOCK_TAG:
$tagId = uniquid();
$tagNames[$tagId] = trim($token[1],’@’);
Break;
}
}
Foreach($tagData as $tagId =>$data){
$tagName = $tagNames[$tagId];
If(array_key_exists($tagName,$tags)){
If(!is_array($tags[$tagName])){
$backupData = $tags[$tagName];
$tags[$tagName] = array();
$tags[$tagName] = $backupData;
}
$tag[$tagName] = $data;
}else{
$tags[$tagName] = $data;
}
}
$returnData[‘comments’] = $comments;
$returnData[‘tags’] = $tags;
$returnData[‘tokens’]=$tokens;
Return $returnData;
}
}
现在已经定义了静态函数ParseDocComment.这正是添加附加的处理逻辑功能的地方,例如处理行内标签的功能。但是在实现这些功能之前,需要扩展另外一些反射类。
扩展反射类
下一个要扩展的类是ReflectionMethod类。这是因为它是最全面的反射实现类,它仍然包含了getDocComment()方法。还需要扩展ReflectionParameter类,但是需要从相关联的方法中获取数据,然后这个方法类的扩展才能实现。下面代码,创建了DocumentingReflectionMethod类,将reflectionMethod类与ParseDocComment类集成。
创建DocumentingReflectionMethod类(DocumentingReflection.php)
Class DocmentingReflectionMethod extends ReflectionMethod{
Protected $_comments,$_tags,$_tokens,$_declaringClass;
Public function __construct($object,$method){
Parent::__construct($object,$method);
$docComment = $this->getDocComment();
$this->_declaringClass = $object;
$parsedComment = DocumentingReflection::ParseDocComment($docComment);
$this->_comments = $parsedComment[‘comments’];
$this->_tags=$parsedComment[‘tags’];
$this->_tokens=$parsedComment[‘tokens’];
}
Public function printDocTokens(){
Foreach($this->_tokens as $token){
Echo $token[0].”=”;
Echo docblock_token_name($token[1]).’=’;
Print_r($token[1]);
Echo “\n”;
}
}
Public function getParseTags(){
Return $this->_tags;
}
Public function getParsedComments(){
Return $this->_comments;
}
}
DocumentingReflectionMethod类从ReflectionMethod类继承,从而继承了ReflectionMethod类的所有功能。然后通过调用parent::__construct函数,对基数进行初始化。这个父类的构造过程必须在重写的构造器的第一行上完成,否则,可能出现错误,而且,甚至可能出现没有任何错误解释就崩溃的代码。
在基类实例初始化完成之后,文档扩展开始起作用。这个类调用了之前定义的用来解析文档注释的静态方法,并传入了它自身的文档注释,而且还将结果保存到几个受保护的成员变量中。最后,还在这个类中添加了几个访问器方法,一遍查看运行是否正常。
有了DocumentReflection.php文件中代码。创建另外文件test.php
例子测试DocumentingReflection类(test.php)
Require_once(‘DocumentingReflection.php’);
Class demo{
/*
*这个方法是用于演示功能的。
*它引入了一个参数并且返回这个参数
*@param mixed $param1 一个返回的变量。
*$returns mixed 返回输入的变量
*/
Public function demoMethod($param1){
Return $param1;
}
}
$reflector = new DocumentingReflectionMethod(‘demo’,’demoMethod’);
$reflector->printDocTokens();
Print_r($reflector->getParsedTags());
Print_r($reflector->getParsedComments());
运行结果如下:
1=DOCBLOCK_NEWLINE=
1=DOCBLOCK_NEWLINE=
2=DOCBLOCK_WHITESPACE=
36=DOCBLOCK_TEXT=This method is for demonstration purposes.
1=DOCBLOCK_NEWLINE=
1=DOCBLOCK_NEWLINE=
2=DOCBLOCK_WHITESPACE=
36=DOCBLOCK_TEXT=It takes a single parameter and returns it.
1=DOCBLOCK_NEWLINE=
1=DOCBLOCK_NEWLINE=
2=DOCBLOCK_WHITESPACE=
5=DOCBLOCK_TAG=@param
36=DOCBLOCK_TEXT=mixed $param1 A variable to return.
1=DOCBLOCK_NEWLINE=
2=DOCBLOCK_WHITESPACE=
5=DOCBLOCK_TAG=@returns
36=DOCBLOCK_TEXT=mixed The input variable is returned.
1=DOCBLOCK_NEWLINE=
结果:
Array(
[param]=>mixed $param1 A variable to return.
[returns]=>mixed The input variable is returned
)
Array(
[0]=>This method is for demonstration purposes
[1]=>It takes a single parameter and returns it.
)
下一步,需要为ReflectionParameter创建一个扩展类.如果没有与参数相关联的文档注
释,就需要从相关联方法的文档注释的param标签中获得参数数据。
要做到这一点,必须自定义ReflectionParameter以便从方法中获取数据,代码所示。
Public void ReflectionParameter::__construct(mixed function,mixed parameter);
值得注意的是,函数参数是混合类型的. 这个参数可能会被传入一个数据数组,其中包含了类名字符串或者对象实例以及方法名字符串。
ReflectionParameter的代码。
Class DocumentingReflectionParameter extends ReflectionParameter{
Protected $_reflectionMethod,$_reflectionClass,$_comment,$_type;
Public function __construct($method,$parameter){
Parent::__construct($method,$parameter);
$this->_comment=’’;
$this->_type =’undefined’;
$this->_reflectionMethod=new DocumentingflectionMethod($method[0],$method[1]);
$tags = $this->_reflectionMethod->getParsedTags();
If(array_key_exists(‘param’,$tags)){
$params = $tags[‘param’];
If(is_array($params)){
Foreach($params as $param){
If($this->_isParamTag($this->getName(),$param)){
$paramFound = $param;
}
}
}else{
If($this->_isParamTag($this->getName(),$params)){
$paramFound = $params;
}
}
If(isset($paramFound)){
$tokens = preg_split(‘/[\s\t]+/’,$paramFound,3);
$this->_comment = $cokens[2];
$this->_type = $tokens[0];
}
}
}
Public function getDeclaringFunction(){
Return $this->_reflectionMethod;
}
Public function getComment(){
Return $this->_comment;
}
Public function getType(){
Return $this->_type;
}
Private function _isParamTag($paramName,$paramData){
$paramSplit = preg_split(‘/[\s\t]+/’,$paramData,3);
$explodedName = trim($paramSplit[1],’$,.’);
If($explodedName == $paramName){
Return ture;
}else{
Return false;
}
}
}
这个类比之前的类要复杂得多。这个类大多数的注释解析过程是在构造函数中实现的。
首先,需要构造这个类井调用父类的方法。如果没有相关联的文档注释,还需要给成员变量赋默认值。然后便可以开始处理过程了。
使用传递给构造函数的信息,对DocumentingReflectionMethod对象进行实例化。这个类使用getParsedTags()方法向你提供访问文档注释信息的功能。下一步,这段代码在$tags数组中查找是否存在’param’标签。如果存在,首先确定这个标签项是数组还是.单个的字符串值,从而做出相应的处理。
在这一过程中,这段代码还调用了私有成员函数_isParamTag()以确定参数是否是标签描
述的那个,将paran标签分割为三部分,这个函数就可以确定这一点。分割是基于将字符串分解为标识符的一个正则表达式来完成的,用tab字符或者空格字符来对标识符进行分解。函数的第三个参数表示字符串只会被分割三次,这会形成一个拥有类型、变量名称和注释的数组。
然后,这段代码会检查变量名称项以确定它是否与ReflectionParameter类自身的名称相
匹配.如果匹配。当前被检测的标签就属f那个参数。
一旦找到正确的标签,数据就会被分割开,并保存到受保护的成员变量_comment和_type中。之后,通过get函数访问这些数据。
现在,可以对这个类进行试用.如代码所示,
实验DocumentingReflection的用法(Experiment.php)
Require_once(‘DocumentingReflection.php’);
Class demo{
/*
*@param string $param 这是一个注释
*/
Public function demoMethod($param=’test’){}
}
$refparam = new DocumentingReflectionParameter(array(
‘demo’,’demoMethod’),
‘param’
);
Var_dump($refparam->getComment());
Var_dump($refparam->getType());
运行会输出一下结果
String(19)” this is the comment”
String(6) “string”
通常你不会希望提供太多信息去访问参数。我们来修改一下DocumentingReflectionMethod类,重写getParameters()函数,使它返回DocumentingReflectionParameter[],而不是ReflectionParameter[].在DocumentingReflectionMethod类中包含代码
Public function getParameters(){
$parameters =array();
If(is_object($this->_declaringClass)){
$class = get_class($this->_declaringClass);
}else if(is_string($this->_declaringClass)){
$class = $this->_declaringClass;
}
Foreach(parent::getParameters() as $parameter){
$parameters[]= new DocumentingReflectionParameter(
Array($class,$this->getName()),
$parameter->getName()
);
}
Return $parameters;
}
这一方法首先检查在构造时保存的声明类,看它是对象还是字符串。因为在下一步操作中需要一个字符串,所以需要使用get_class()函数来检查对象的类型。
接着,需要调用父类的getParameters()方法。这个函数会返回ReflectionParameter对象的一个数组,而不是DocumentingReflectionParameter对象。这个函数的全部用途是用来挑用扩展的文档形式,而不是内置的形式。
为了测试重写的getParameters()函数,可以写如下代码
Require_once(‘DocumentingReflection.php’);
Class demo{
/*
* @param mixed $param1 第一个注释
*$param string $param2 第二个注释
*/
Public function demoMethod($param1,$param2){}
}
$reflector = new DocumentingReflectionMethod(‘demo’,’demoMethod’);
Foreach($reflector->getParameters() as $param){
Echo $param->getName().””;
Echo $param->getType().””;
Echo $param->getComment();
Echo “\n”;
}
运行结果:
Param1 mixed The first comment
Param2 string The second comment
现在你已经完成了扩展的方法和参数。那么如何完成类的扩展?DocumentingReflectionClass正是需要创建的下一个类。
//创建DocumentingReflectionClass类(DocumentingReflection.php)
Class DocumentingReflectionClass extends ReflectionClass{
Protected $_Comments,$_tags,$_tokens;
Public function __construct($class){
Parent::__construct($class);
$docComment = $this->getDocComment();
$parsedComment = DocumentingReflection::ParseDocComment($docComment);
$this->_comments = $parseComment[‘comments’];
$this->_tags = $parsedComment[‘tags’];
$this->_tokens = $parsedComment[‘tokens’];
}
Public function getMethods(){
$methods =array();
Foreach(parent::getMethods() as $method){
$methods[] = new DocumentingReflectionMethod(
$this->getName90,$method->getName()
);
}
Return $methods;
}
Public function printDocTokens(){
Foreach($this->_tokens as $token){
Echo $token[0] .’=’;
Echo docblock_token_name[$token[0]].’=’;
Print_r($token[1]);
Echo ‘\n’;
}
}
Public function getParseTags(){
Return $this->_tags;
}
Public function getParseComments(){
Return $this->_comments;
}
}
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
API文档是一个技术内容交付文件,包含如何有效地使用和集成api的说明。它是一个简明的参考手册,包含了使用API所需的所有信息,详细介绍了函数、类、返回类型、参数等,并有教程是示例支撑。
API文档传统上是使用常规内容创建和维护工具和文本编辑器完成的。API描述格式如OpenAPI /Swagger规范具有自动文档编制流程,它使得团队更容易生成和维护API文档。
采用模式在技术领域已经开始向开发者转移。拥有良好的API文档的一个重要原因是它提高了使用API的开发者体验,它与API的采纳有直接的关系。
API函数包含在位于系统目录下的DLL文件中。你可以自己输入API函数的声明,但VB提供了一种更简单的方法,即使用API Text Viewer。 要想在你的工程中声明API函数,只需运行API Text Viewer,打开Win32api.txt或MDB。
如果你已经把它转换成了数据库的话,这样可以加快速度。 使用预定义的常量和类型也是同样的方法。 API除了有应用“应用程序接口”的意思外,还特指API的说明文档,也称为帮助文档。
扩展资料:
API,往往是和SDK放在一起的。SDK即软件开发工具包。
软件开发工具包是一些被软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等创建应用软件的开发工具的集合,一般而言SDK即开发 Windows 平台下的应用程序所使用的 SDK。
它可以简单的为某个程序设计语言提供应用程序接口 API的一些文件,但也可能包括能与某种嵌入式系统通讯的复杂的硬件。
一般的工具包括用于调试和其他用途的实用工具。SDK 还经常包括示例代码、支持性的技术注解或者其他的为基本参考资料澄清疑点的支持文档。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~