php项目在已有自动加载机制下使用TopSdk.php钉钉SDK

钉钉提供的SDK中主要是引用TopSdk.php这个文件,而且不得改变该php sdk的文件结结构,其中被 TopSdk.php包含的Autoloader.php文件 使用了 自动加载 机制spl_autoload_register('Autoloader::autoload');如果我们的php开发过程中本身已经使用了一套自动加载机制(如:spl_autoload_register('Loader::autoload');  ) 那么如果想在初始的自动加载的类文件里面使用钉钉sdk该如何解决呢?

一、php的 spl_autoload_register 注册机制支持注册多个自动加载机制

所以,可以在你原先注册自动加载机制的语句 spl_autoload_register('Loader::autoload');  下,再次写上注册自动加载机制 spl_autoload_register('Autoloader::autoload'); 因为钉钉sdk文件内本身已经写了注册自动加载机制,所以你只需要引用TopSdk.php文件即可。

<?php
……………………
……………………
spl_autoload_register('Loader::autoload'); 
include('../xx/xxx/TopSdk.php');
//spl_autoload_register('Autoloader::autoload');//上面的php文件中已有此自动注册语句。

注意:自动注册加载器函数中不要出现die、exit等退出php脚本的代码,因为spl_autoload_register会按顺序进行自动加载,如果在第一个里面没有找到可申明的类文件,它会使用下一个 spl_autoload_registe 方法进行类文件查找及申明,如果你在第一个方法里判断因为没找到文件就直接退出的话  if (file_exists($file)) { xxx}else{die('没有找到类文件');}下一个 spl_autoload_registe 方法 将不会执行!

二、消除命名空间带来的影响

做完上面一步你会发现还是不能在已有的类文件中使用钉钉sdk中的类方法。主要是一般我们自己使用自动注册机制为了方便控制类的不重复以及与物理路径对应方便自动加载,使用了namespace命名空间。如果你在某一个php文件中的类需要应用钉钉SDK可以使用use语句来解决(前提是你已经在php项目原自动注册加载机制后面引用了TopSdk.php文件)。

<?php
namespace application;//此处的application会直接导致class中的类文件都在application\xxx下进行查找
//在自己本身已经使用自动注册机制的前提下,程序运行到这里,说明前面已经include了TopSdk.php文件,否则下面的use语句仍然无效
//use 语句需要放到namespace后
use DingTalkClient;//必不可少,否则提示找不到类文件
use DingTalkConstant;//use哪些 取决于下面的calss中用到了哪些类
use OapiGettokenRequest;//
class dingding{

    function getDingToken(){//获取token状态

        //require('extend/dingding/TopSdk.php');
        require_once('setting/basesetting.php');
        
        $c = new DingTalkClient(DingTalkConstant::$CALL_TYPE_OAPI, DingTalkConstant::$METHOD_GET , DingTalkConstant::$FORMAT_JSON);
        $req = new OapiGettokenRequest;
        $req->setAppkey(APP_KEY);
        $req->setAppsecret(APP_SECRET);
        $resp = $c->execute($req, $access_token='', "https://oapi.dingtalk.com/gettoken");
        var_dump($resp);

    }

}

php中use的用法

use是你在当前php文件需要引用哪个类时用到的语句(需要在当前文件的代码前进行声明,有namespace的情况需要放在namespace语句后)。use关键字是不会进行文件的自动引入的!它主要作用是声明要使用的类处于 use关键字后面的命名空间下(使用use申明时并不会进行脚本加载,只有真正使用到对应类库的时候才会加载),在调用通过use声明的类库时会自动调用 spl_autoload_register( )函数并将调用的类库名称传递到参数中(这里的类库名称是包含命名空间的全名称)。

//备忘--
第一个类文件a.php
<?php 
namespace aa\bb\cc;
class Test{
    function helloworld(){
    echo 'helloword aa\bb\cc Test\helloworld';
    }
}

class Test1{
    function helloworld1(){
    echo 'helloword aa\bb\cc Test1\helloworld1';
    }

}
?>

第二个类文件b.php
<?php 
namespace a1\b1\c1;
class Test{
    function helloworld(){
    echo 'helloword a1\b1\c1 Test\helloworld';
    }
}
?>

第三个文件index.php
<?php 
require('a.php');
require('b.php');

//示范错误用法,因为在不同的命名空间中存在同名的类
use aa\bb\cc\Test;//实例化a.php中的Test类
$t = new Test();
$t->helloword();
//运行报错PHP Fatal error:  Cannot use aa\bb\cc\Test as Test because the name is already in use 

//示范正确用法1
use aa\bb\cc\Test as Testa;//实例化a.php中的Test类,这里使用as给类取别名
$t = new Testa();//之前的new Test() 变成了new Testa() !!!
$t->helloworld();
//输出 helloword aa\bb\cc Test\helloword
use aa\bb\cc\Test1;//因为Test1类名没有重复
$t1 =new Test1;
$t1->helloworld1();
//输出 helloword aa\bb\cc Test1\helloworld1



//示范正确用法2
$t2 = new \aa\bb\cc\Test;//注意前面有反斜杠\aa\bb\cc\Test
$t2->helloworld();
//输出 helloword aa\bb\cc Test\helloword
//

?>

基于互联网精神,在注明出处的前提下本站文章可自由转载!

本文链接:https://ranjuan.cn/dingtalk-use-spl-autoload-register/

赞赏

微信赞赏支付宝赞赏

发表评论