Home  >  Article  >  Backend Development  >  Discuz! Passport Passport Integration_PHP Tutorial

Discuz! Passport Passport Integration_PHP Tutorial

WBOY
WBOYOriginal
2016-07-21 15:52:531162browse


解决办法:
第一步: 到dz的数据库表cdb_settings 找到下面这几行修改为

第二步: 删除dz安装目录/forumdata/cache/cache_settings.php
第三步: 重新访问论坛


登陆和注册整合流程
用户从登陆或注册表单提交帐号密码信息 ==>
主站程序检验用户登陆或注册,成功(注册需要生成新用户)则 ==>
设置主站自身的cookie或session    ==>
url传递 返回地址forward和编码后的用户信息和其他信息 到dz/api/passport.php

整合之前请先仔细阅读官方passport技术文档: http://www.discuz.net/usersguide/advanced_passport.htm
//该文档保存为login.php
//首先将接口技术文档里的加密解密函数拷贝
//为了不让代码太乱,我拷贝到文档的结尾处
//假设自己的用户数据库表里用户名字段为UserName, 密码字段为Pwd, Email字段为 Email
//注册页实现方法差不多,可自行实现,疑问加我QQ:2666556

$act=(isset($_GET['act']))?$_GET['act']:"login";
if(function_exists($act)) $act();else login();

function login()
{
$ErrMsg=UserCheck();
if($ErrMsg!="")echo $ErrMsg;
//后面加上显示你的登陆表单的代码 如
?>


用户名:
密码:

}//end function

function logout()//登出
{
$passportkey="1234567890";//这里换成你论坛通行证设置的passportkey
$auth=$_COOKIE['auth'];
setcookie("auth", "",time() - 3600);
$forward=$_GET['forward'];
if($forward=="")$forward="../../index.php";//这里换成你的主页绝对地址或相对地址
$verify = md5('logout'.$auth.$forward.$passportkey);
$auth=rawurlencode($auth);
$forward=rawurlencode($forward);
header("Location: bbs/api/passport.php?action=logout&auth=$auth&forward=$forward&verify=$verify");
}

function UserCheck()
{
$passportkey="1234567890";//这里换成你论坛通行证设置的passportkey

//===========验证输入=====================
if(!isset($_POST['submit'])) return; // login表单的按钮需要与此同名
$usnm=$_POST['username'];//username换成你登陆表单里的用户名域
$pwd=$_POST['password'];//password换成你登陆表单里的密码域
if($usnm=="") return "请输入用户名!";
if($pwd=="") return "请输入密码!";

//=========数据库处理==========================
$db=mysql_connect("localhost", "root", "");
mysql_select_db("your_db_name");
$sql="Select * from `user` where UserName='".$usnm."' Limit 1";
$rs = mysql_query($sql,$db) ;
$row = mysql_fetch_array($rs);
if(!$row)return "该用户不存在";
if($row["Pwd"]!=md5($pwd))return "密码错误";
mysql_free_result($rs);

//==============header到bbs=====================
$member = array
(
'time' => time(),
                        'username' => $row["UserName"],
                        'password' => $row["Pwd"],
                        'email'    => $row["Email"]
        );
        $auth = passport_encrypt(passport_encode($member), $passportkey);
        setcookie("auth",$auth,($_POST["Cookie"]? time()+(int)$_POST["Cookie"] :0));
        $forward=$_POST['forward'];
        if($forward=="")$forward="../../index.php";                                       
        $verify = md5('login'.$auth.$forward.$passportkey);
        $auth=rawurlencode($auth);
        $forward=rawurlencode($forward);
        header("Location: bbs/api/passport.php?action=login&auth=$auth&forward=$forward&verify=$verify");                       

}


//=============================================================
//=============以下为拷贝过来的函数============================
function passport_encrypt($txt, $key) {
        srand((double)microtime() * 1000000);
        $encrypt_key = md5(rand(0, 32000));       
        $ctr = 0;
        $tmp = '';
        for($i = 0; $i < strlen($txt); $i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $encrypt_key[$ctr].($txt[$i] ^ $encrypt_key[$ctr++]);
}
return base64_encode(passport_key($tmp, $key));
}

function passport_decrypt($txt, $key) {
$txt = passport_key(base64_decode($txt), $key);
$tmp = '';
for ($i = 0; $i < strlen($txt); $i++) {
$tmp .= $txt[$i] ^ $txt[++$i];
}
return $tmp;
}

function passport_key($txt, $encrypt_key) {
$encrypt_key = md5($encrypt_key);
$ctr = 0;
$tmp = '';
for($i = 0; $i < strlen($txt); $i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
}
return $tmp;
}

function passport_encode($array) {
$arrayenc = array();
foreach($array as $key => $val) {
                   $arrayenc[] = $key.'='.urlencode($val);
        }
        return implode('&', $arrayenc);

}
//=========================================================================
//===========================拷贝结束======================================
?>

第二篇:php168 v3.5与discuz v4.10的整合
168整站 与 discuz的passport整合


php168整站v3.5与discuz v4.1.0的整合(带视频)

使用说明
请注意自己所用的程序的版本号
login.php 登陆和退出的整合
register.php 注册的整合


整合前请先核对一下你使用的php168的login.php 和 register.php 是否和 整合文件.rar中[原文件] 文件夹下的文件相同
如果不同..请不要整合

(一)准备工作
1.下载php168 v3.5
2.下载discuz bbs v4.1.0


(二)安装和整合 (请参考视频安装)

1.安装php168 v3.5 (如已安装 到第2步) (如何安装请参考php168的安装说明)
2.进入php168的后台管理界面关闭168的论坛整合功能 (新安装可跳过)
3.在php168的安装目录下建立名称为bbs的文件夹
4.下载安装discuz bbs v4.1.0的upload/下的所有文件拷贝到bbs文件夹下
5.运行discuz bbs的install.php 进行安装
6.到discuz的后台管理设置开启通行证
具体参数如下
启用通行证:       是
应用程序 URL 地址: http://localhost/php168/ 根据具体情况设置
通行证私有密匙:   1234567890 (如果这里改了..两个整合文件中的$passportkey的值也必须改成相同的值)
验证字串有效期(秒): 3600
应用程序注册地址:   register.php
应用程序登录地址:   login.php
应用程序退出地址:   login.php?action=quit
积分同步选项:     不同步积分
7.将整合压缩包中的login.php 和 register.php替换 php168下同名的文件
安装完成


/请保留以下信息,以方便其他网友在整合时遇到问题可以获得更多帮助
//整合贡献者: huozhe3136 疑问请加我qq: 2666556 (提供整合效果的演示)
//视频贡献: 一热心网友
//关于整合的更多内容请访问http://www.discuz.net/thread-304838-1-1.html


程序打包下载地址:http://www.photoxtd.com/chinaylrc/php168_discuz.rar
视频演示下载地址:http://www.photoxtd.com/chinaylrc/php168vcr.rar
apmserv5.12 下载地址: http://down.chinaz.com/s/7558.asp
/tech/uploadfile/200702/20070227023513192.rar


第三篇: asp程序与discuz v4.10的整合方法
1.文件discuz_passport.asp
<%
'请保留以下信息以备出现问题时使用
'贡献者 huozhe3136 QQ:2666556
'=====================================================
'============仿discuz passport编码函数================
'=====================================================

function passport_encrypt(txt, key)
dim encrypt_key, encrypt_key_ary,txt_ary
dim ctr,tmp,i
Randomize
encrypt_key=md5(Int(32000* Rnd),32)
encrypt_key_ary=strtoary(encrypt_key)
txt_ary=strtoary(txt)
ctr = 0
tmp = ""
for i = 0 to StrLength(txt)-1
if ctr=len(encrypt_key) then ctr=0 else ctr=ctr
tmp = tmp & encrypt_key_Ary(ctr) & mxor(txt_ary(i),encrypt_key_ary(ctr))
ctr=ctr+1
next
passport_encrypt=strAnsi2Unicode(base64Encode(passport_key(tmp, key)))
end function


'=====================================================
'============仿discuz passport解码函数================
'=====================================================
function passport_decrypt(txt, key)
Dim txt_ary,tmp,i
txt = passport_key(base64Decode(strUnicode2Ansi(txt)), key)
txt_ary = AnsiToAry(txt)
' 变量初始化
tmp = ""
for i = 0 To lenb(txt)-1
tmp = tmp & mxor(txt_ary(i),txt_ary(i+1))
i=i+1
next
passport_decrypt = strAnsi2Unicode(tmp)
end function

'=====================================================
'==========仿discuz Passport 密匙处理函数=============
'=====================================================
function passport_key(ansitxt, encrypt_key)
dim encrypt_key_tmp,encrypt_key_ary,txt_ary
dim ctr,tmp,i
encrypt_key_tmp = md5(encrypt_key,32)
encrypt_key_ary=StrToAry(encrypt_key_tmp)
txt_ary=AnsiToAry(ansitxt)
ctr = 0
tmp = ""
for i=0 to lenb(ansitxt)-1
if ctr=len(encrypt_key_tmp) then ctr=0 else ctr=ctr
tmp= tmp & mxor(txt_ary(i),encrypt_key_ary(ctr))
ctr=ctr+1
next
passport_key=tmp
end function

'=====================================================
'=================将字符串转换为Ansi数组==============
'=====================================================
function StrToAry(str)
dim ary(),length,tmpstr,i
tmpstr=strUnicode2Ansi(str)
length=lenb(tmpstr)
redim ary(length)
for i=0 to length-1
ary(i)=midb(tmpstr,i+1,1)
next
StrToAry=ary
end function

'=====================================================
'=================将Ansi字符串转换为Ansi数组==========
'=====================================================
function AnsiToAry(str)
dim ary(),length,i
length=lenb(str)
redim ary(length)
for i=0 to length-1
ary(i)=midb(str,i+1,1)
next
AnsiToAry=ary
end function


'=====================================================
'=================异或操作============================
'=====================================================
function mxor(chrb1,chrb2)
if chrb1<>"" and chrb2 <>"" then
        mxor=chrb(ascb(chrb1) xor ascb(chrb2))
        end if       
end function


Function StrLength(str)
        ON ERROR RESUME NEXT
        Dim WINNT_CHINESE
        WINNT_CHINESE    = (len("中国")=2)
        If WINNT_CHINESE Then
                Dim l,t,c
                Dim i
                l=len(str)
                t=l
                For i=1 To l
                        c=asc(mid(str,i,1))
                        If c<0 Then c=c+65536
If c>255 Then
                                t=t+1
                        End If
                Next
                strLength=t
        Else
                strLength=len(str)
        End If
        If err.number<>0 Then err.clear
End Function

%>

2.文件 login.asp



<%
'asp的整合方法已更新,,中文注册乱码问题已解决
'================================================================
'=====================用法示例==疑问加我QQ:2666556===============
'================================================================
dim PassportKey,YourAspWeb_Url,DiscuzBbs_Url
PassportKey="1234567890"  '这里换成你discuz论坛通行证设置的passportkey
YourAspWeb_Url="http://localhost/test2/login.asp"  '这里换成你的主页绝对地址或相对地址
DiscuzBbs_Url="http://localhost:8080/discuz/"          '这里换成你的discuz论坛绝对地址或相对地址

select case request.QueryString("act")
        case "login"   call login()
        case "logout"  call logout()
end select

if request.Cookies("username")<>"" then
        dim str
        str=request.Cookies("username") & " 你好 你已登陆成功" &_
    " 点击这里退出登陆" &_
    " 点击这里访问论坛
"
    response.Write(str)
end if

function logout()
        dim auth,forward,verify
        auth=request.Cookies("auth")       
        response.Cookies("username")=""
        response.Cookies("auth")=""       
        forward=request.QueryString("forward")
        if forward="" then forward=YourAspWeb_Url                                         
        verify = md5("logout"& auth & forward & PassportKey ,32)
        auth=server.URLEncode(auth)
        forward=server.URLEncode(forward)
        response.Redirect(DiscuzBbs_Url & "api/passport.php?action=logout&auth=" & auth & "&forward=" & forward & "&verify=" & verify)
end function

 

function login()
        dim auth,forward,verify,member_info
        '需根据实际情况修改,这里只作最简单的验证
        if request.Form("username")="admin" and request.Form("password")="123456" then
                '设置自己的cookie 或 session
                response.Cookies("username")=request.Form("username")

                '========================================================
                '===============passport 整合开始========================
                '========================================================
                '假设从用户数据库里取出email 为abc@hotmail.com
                member_info="time="  & datediff("s","1970-1-1 00:00:00",now) &_
                                                        "&username=" & request.Form("username") &_
                                                        "&password=" & md5(request.Form("password"),32) &_
                                                        "&email="    & "abc@hotmail.com
                auth = passport_encrypt(member_info , PassportKey)               
                response.Cookies("auth")=auth
                forward=request.form("forward")
                if forward="" then forward=YourAspWeb_Url       
                verify = md5("login" & auth & forward & PassportKey,32)
                auth=server.URLEncode(auth)
                forward=server.URLEncode(forward)       
                response.Redirect(DiscuzBbs_Url & "api/passport.php?action=login&auth=" & auth & "&forward=" & forward & "&verify=" & verify)                       
                '========================================================
                '===============passport 整合结束========================
                '========================================================

        else
                        response.Write("登陆失败
")
        end if
end function

%>


  用户名:
 
 

  密 码:
 
 

  ">    
 

/tech/uploadfile/200702/20070227024221846.rar


第四篇 :Asp整合实例-PowerEasy2006 SP2普及版 与 discuz v4.10的整合

PowerEasy下载地址:http://www.powereasy.net/Soft/PE_soft/181.html

步骤1:
        下载安装powerEasy,下载安装discuz v4.10

步骤2:
        将user_chklogin.asp 覆盖到 powereasy安装根目录/user/user_chklogin.asp
        将user_logout.asp   覆盖到 powereasy安装根目录/user/user_logout.asp
        将user_regpost.asp  覆盖到 powereasy安装根目录/reg/user_regpost.asp
        拷贝discuz_passport文件夹到Powereasy安装根目录

步骤3:  修改discuz_passport里的config.asp文件部分变量
        Discuz_PassportKey="1234567890"                  '这里换成你discuz论坛通行证设置的passportkey
        Discuz_YourAspWeb_Url="http://localhost:8080/"  '这里换成你的主页绝对地址或相对地址
        Discuz_Bbs_Url="http://localhost/discuz/"       '这里换成你的discuz论坛绝对地址或相对地址

步骤4:
        到discuz论坛后台通行证设置开启通行证
        启用通行证:                 是
        应用程序 URL 地址:         http://localhost:8080/        '这里换成你的主页绝对地址或相对地址
        通行证私有密匙:         1234567890                '这里必须与Discuz_Passportkey的值相同
        验证字串有效期(秒):        3600
        应用程序注册地址:        Reg/User_Reg.asp
        应用程序登录地址:        index.asp
        应用程序退出地址:        User/User_Logout.asp
        具体请参照论坛设置图片


第五篇 主站与discuz同服务器无需Passport的整合方法

//discuz同服务器下无passport登陆整合方法
//贡献:huozhe3136 QQ:2666556
//假设discuz安装在网站根目录下的bbs/中
//用法事例
error_reporting(E_ALL);

$path_bbs="bbs/";//请修改为你的论坛的相对路径
$check_username="admin";//测试时这个用户名必须在论坛里也存在
$check_password="123456";
define('IN_DISCUZ', TRUE);//为了包含discuz下的文件这个必须定义
require_once "$path_bbs/config.inc.php";//获得论坛数据库的配置
require_once "$path_bbs/include/db_mysql.class.php";

if(@$_GET[act]=="logout"){
foreach ($_COOKIE as $key => $value) {
        setcookie($key,'',time() - 3600,$cookiepath,$cookiedomain,0);            
            header("Location:".$_SERVER['PHP_SELF']);         
    }
}
if(isset($_POST["submit"])){//检查是否点击了提交按钮
    $username=trim($_POST['username']);
    $pwd=trim($_POST['password']);
    //主站验证登陆,为简单起见,这里只作简单的示范
    if($username==$check_username && $pwd==$check_password){//测试时这个用户名必须在论坛里也存在
        $db = new dbstuff;
        $db->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect);//$dbhost,$dbuser,$dbpw,$dbname,$pconnect是在bbs/config.inc.php里定义的变量
        $sql="select * from {$tablepre}members where username='$username'";
        $rs = $db->query($sql);
        if($dzmember = $db->fetch_array($rs)){
            setcookie('myusername',$username,time()+3600,$cookiepath,$cookiedomain,0);//设置主站自身的cookie
            setcookie("{$tablepre}sid",'',time() - 3600,$cookiepath,$cookiedomain,0);//让discuz的sid过期是为了让discuz重新分配一个新的sid
            setcookie("{$tablepre}auth", authcode("$dzmember[password]\t$dzmember[secques]\t$dzmember[uid]", 'ENCODE'),time()+3600,$cookiepath,$cookiedomain,0);//$cookiepath和$cookiedomainbbs/config.inc.php里定义的变量
            header("Location:".$_SERVER['REQUEST_URI']);
        }
    }
}

//下面这个函数是discuz的用户cookie编码函数,已修改,原型在$path_bbs/include/global.func.php
function authcode($string, $operation) {
    global $_SERVER, $_DCACHE,$path_bbs;
    require_once "$path_bbs/forumdata/cache/cache_settings.php";//需要获取论坛的authkey
    $discuz_auth_key = md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);
    $coded = '';
    $keylength = strlen($discuz_auth_key);
    $string = $operation == 'DECODE' ? base64_decode($string) : $string;
    for($i = 0; $i < strlen($string); $i += $keylength) {
$coded .= substr($string, $i, $keylength) ^ $discuz_auth_key;
}
$coded = $operation == 'ENCODE' ? str_replace('=', '', base64_encode($coded)) : $coded;
return $coded;
}
?>
if(@$_COOKIE['myusername']==''){
?>


用户名:测试用户名为admin,请更改为你的用户名

密码:测试密码为123456



}
else echo("登陆成功,请到论坛检查登陆
退出登陆 ");
?>

第六篇 C#与discuz5.0的整合实例

using System;
using System.Security.Cryptography;
using System.Text;

///


/// c#与discuz的passport整合事例
/// 请保留以下信息以备出现问题时使用
/// 整合贡献:huozhe3136 QQ:2666556
/// 调试工具:Microsoft Visual Web Developer 2005
///

public partial class _Default : System.Web.UI.Page {
    //------------------------需要修改的设置---------------------------------
    string webUrl           = "http://localhost:1627/webapp/Default.aspx";//这里修改为你的测试主站的地址,不要缺少最后的'/'号
    string dzUrl            = "http://localhost:8080/discuz/";//这里修改为你的dz地址,不要缺少最后的'/'号
    string dzPassportKey    = "1234567890";//这里修改为你的dz后台通行证设置里的possportkey
    string dzForward        = "";
    string dzAuth           = "";
    string dzVerify         = "";

 

    protected void Page_Load(object sender, EventArgs e){
        dzForward = Request.QueryString["forward"];
        if (Request.QueryString["act"] == "logout") logout();
        if(Session["username"]!=null) Response.Write(Session["username"].ToString()+ "登陆成功! 点击这里退出登陆 访问论坛
");
    }

    protected void logout(){
        Session["username"] = null;
        dzForward           = Request.QueryString["forward"];//获取返回地址
        if (dzForward == "") dzForward = webUrl;//如果返回地址为空,则返回设置的页
        dzVerify            = md5("logout" + dzForward + dzPassportKey);
        dzForward           = Server.UrlEncode(dzForward);
        Response.Redirect(dzUrl + "api/passport.php?action=logout&auth=&forward=" + dzForward + "&verify=" + dzVerify);

    }


    protected void Button1_Click(object sender, EventArgs e){
        string postUsername;
        string postPwd;
        postUsername        = username.Text.ToString().Trim();
        postPwd             = password.Text.ToString();

        if(postUsername=="admin" && postPwd=="123456"){
            Session["username"]=postUsername;//设置主站自身的cookie或session;

            //---------------------------passport注册或登陆整合开始-----------------------------
            string memberInfo = "username=" + postUsername
                        + "&password=" + md5(postPwd)
                        + "&time="+ time()//获取当前时间与格林威治的秒差
                        + "&email="+"abc@abc.com";//需要email的值,实际整合通常情况是从数据库里获取用户email
            dzAuth          = passport_encrypt(memberInfo , dzPassportKey);
            dzForward       = forward.Value.ToString().Trim();//获取返回地址
            if(dzForward=="") dzForward = webUrl;//如果返回地址为空,则返回设置的页
            dzVerify        = md5("login" + dzAuth + dzForward + dzPassportKey);
            dzAuth          = Server.UrlEncode(dzAuth);
            dzForward       = Server.UrlEncode(dzForward);
            Response.Redirect(dzUrl + "api/passport.php?action=login&auth=" + dzAuth + "&forward=" + dzForward + "&verify=" + dzVerify);
            //---------------------------passport注册或登陆整合结束-----------------------------
        }else Response.Write("登陆失败
");
    }


    //------------------------------------以下为一些关键函数------------------------------
    // 将字符串转换为byte数组    
    public byte[] strToByteAry(string str){
        return Encoding.Default.GetBytes(str);
    }

   // c# dz通信证编码函数
   public string passport_encrypt(string txt, string key){
        byte[] randomNumber = new byte[1];
        RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider();
        Gen.GetBytes(randomNumber);
        int rand = Convert.ToInt32(randomNumber[0]);
        string encrypt_key = md5(rand.ToString());

        byte[] txtAry = strToByteAry(txt);
        byte[] encryAry = strToByteAry(encrypt_key);
        int j = 0;
        int ctr = 0;
        byte[] tmp = new byte[2 * txtAry.Length];
        for (int i = 0; i < txtAry.Length; i++)
        {
            ctr = ctr == encryAry.Length ? 0 : ctr;
            tmp[j++] = encryAry[ctr];
            tmp[j++] = xor(txtAry[i], encryAry[ctr++]);
        }
        return Convert.ToBase64String(passport_key(tmp, key));
    }

   
    // c# dz通行证解码函数
    public string passport_decrypt(string txt, string key){
        byte[] t = Convert.FromBase64String(txt);
        byte[] btxt = passport_key(t, key);
        byte[] btmp = new byte[btxt.Length];
        int j = 0;
        for (int i = 0; i < btxt.Length; i++, j++)
            btmp[j] = xor(btxt[i], btxt[++i]);
        return Encoding.Default.GetString(btmp);
    }



    // c# dz通行证密匙处理函数   
    public byte[] passport_key(byte[] btxt, string key){
        key = md5(key);
        byte[] keyAry = strToByteAry(key);
        int ctr = 0;
        byte[] tmp = new byte[btxt.Length];
        for (int i = 0; i < btxt.Length; i++){
            ctr = (ctr == keyAry.Length) ? 0 : ctr;
            tmp[i] = xor(btxt[i], keyAry[ctr++]);
        }
        return tmp;
    }

   
    // 针对byte的异或    
    public byte xor(byte a, byte b){
        return Convert.ToByte(a ^ b);
    }

    // 获取UNIX时间戳   
    public string time(){
        DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
        DateTime dtNow = DateTime.Parse(DateTime.Now.ToString());
        TimeSpan toNow = dtNow.Subtract(dtStart);
        string timeStamp = toNow.Ticks.ToString();
        timeStamp = timeStamp.Substring(0, timeStamp.Length - 7);
        return timeStamp;
    }

   
    // md5加密
    public string md5(string str){
        MD5 md5Hasher = MD5.Create();
        string re="";
        byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(str));
        for (int i = 0; i < data.Length; i++)
            re += data[i].ToString("x2");       
        return re;
    }
}

/tech/uploadfile/200702/20://www.tenwe.com/tech/uploadfile/200702/20070227024435342.rar" target=_blank>/tech/uploadfile/200702/20070227024435342.rar

070227024435342.rar

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/318821.htmlTechArticle解决办法: 第一步: 到dz的数据库表cdb_settings 找到下面这几行修改为 第二步: 删除dz安装目录/forumdata/cache/cache_settings.php 第三步: 重新访问论...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn