釘釘jsapi簽名php(釘釘上個性簽名)

本文目錄一覽:

釘釘如何設置簽名

我們打開手機桌面,在手機桌面上找到釘釘軟件

2進入到釘釘的界面內後,我們點擊公司主頁即可。

3然後進入到公司的主頁面內後,我們選擇釘郵即可。

4然後進入到釘郵的界面內後,我們點擊其右上角的設置

5進入到設置內後,我們點擊選擇其中的郵件簽名即可。

6然後在郵件簽名的界面內,我們只要在個人簽名內進行編寫即可。

php jsapi ticket怎麼獲取

1、開啟使用了jsapi的頁面的wx.config的debug,提示signature簽名錯誤

2、既然簽名錯誤就一步步打印獲取這個數據的步驟上的中間數據,看是哪個錯了

3、結果是用php curl模擬get  ;type=jsapi 這個去獲取jsapi_ticket時報錯400,請求參數錯誤

請求參數錯誤!!!困擾了很久!之前能成功!

原因:問題出在ACCESS_TOKEN上,這個token的格式會不會出現特殊字符騰訊沒有說明,而「JSSDK說明文檔」中說用http GET方式請求jsapi_ticket時也沒說明 這個 token中會出現特殊字符!!!

在PHP中沒有對該token進行urlencode,於是當token中有特殊字符時就出現400

解決

get和post開放API時,對格式不明的請求參數使用urlencode

小白想請問form表單提交數據到釘釘,這個接口該怎麼寫 求詳細

一、免登問題

1.如何在App及後台獲取企業及用戶相關信息

(1)微應用主頁支持使用$CORPID$模板參數表示corpid,用戶訪問微應用的時候釘釘將把$CORPID$替換成用戶所屬企業的corpid,例如

(2)獲取用戶信息需要通過免登服務,詳情免登服務

2.釘釘微應用OAuth2授權打開一個應用時提示對不起您無權限查看該頁面

可能的原因:

(1)如果其他應用正常,或者企業其他人打開應用沒問題,可能是緩存問題引起,請清除下緩存

(2)參數redirect_uri的值沒有做url編碼

(3)redirect_uri的域名和微應用的域名不一致

3.免登Code的時效性

免登授權碼是一次性的,團隊(未認證的企業)失效時間五分鐘

二、JSAPI問題

1.jsapi權限校驗失敗,錯誤碼080003是什麼原因

請先按照文檔,先檢查參數agentid傳值是否正確,agentId查看方式:

(1)如果是isv應用,需要通過-獲取企業的應用信息

(2)企業自建應用,通過oa後台查看開發環境準備

2.jsapi權限校驗時返回{message:”權限校驗失敗”,errorcode:3}

(1)首先檢查用來生成簽名(signature)的jsapi_ticket是否過期(jsapi_ticket有效期為7200秒,而且當你請求了新的ticket之後,舊的ticket就失效了)

(2)其次檢查生成簽名的Url參數,與調用dd.config 所在的url是否一致

生成簽名用的url需要去除hash部分,e.g. 如果當前頁面url是;n=456#opq,則用於生成簽名的url是;n=456,可以使用調試工具來生成jsapi_ticket和signature,並和你實際使用的進行對比

(3)提示權限校驗失敗,errorcode:3,錯誤碼52019,請檢查corpid是否正確

3.使用JSAPI返回簽名或者Ticket獲取失敗

JSAPI返回失敗主要有兩種錯誤

(1)[錯誤碼:52011] [jsapi ticket 讀取失敗]

a.確認agentId參數正確傳入

b.確認以傳入agentId對應的企業身份獲取過jsapi_ticket,也就是調用過get_jsapi_ticket方法

c.確認agentId對應的企業身份獲取的jsapi_ticket沒有過期.即在兩個小時的有效期之內

(2)[錯誤碼:52013][簽名校驗失敗]

a.確認agentId參數正確傳入

b.oa後台設置uri和權限校驗uri不一致(去掉hash部分)

c.確認獲得的jsapi_ticket為最新的,沒有其他服務同時調用get_jsapi_ticket方法,導致生成簽名的jsapi_ticket過期

d.確認生成jsapi簽名正確,可以使用debug工具進行調試

4.ios 單頁面應用更改url#後面的參數(如:localhost:8100/#/test1 變成 localhost:8100/#/test2),調用jsapi無效

ios單頁面應用更改url參數,導致調用jsapi無效問題,將在2.7版本隨新版本發佈;

若是老版本(2.7以前版本),需要打開頁面時重新授權,調用jspai即可正常

5.jspai 調用返回errCode7 錯誤原因

(1)請查看在dd.config的jsApiList中,是否已配置要使用的jsapi,未配置的話會報錯

(2)ios 單頁面應用提示 errCode7 Jsapi Should NOT CallselectorString

同問題5,單頁面應用更改url參數,導致調用jsapi無效,老版本(2.7以前版本)需要重新授權,調用jsapi正常

(3)requestJsApis() not invoked,errorCode:7

dd.ready一定要在dd.config之後執行

6.如何獲取JSAPI權限(需再詳細些)

可以參照客戶端開發文檔,要使用的jsapi必須進行權限驗證配置,在dd.config中進行配置,可參照權限驗證配置-beta

7.工具欄顏色如何設置

在頁面需要引入js文件的前提下,通過url參數設置導航欄顏色,參數名為dd_nav_bgcolor

比如微應用當前頁面鏈接為:,要設置的顏色為FF112233(前兩位默認FF,後面6位112233是對應的色值),可設置頁面url為:

8.device.geolocation.get 提示unauthorized errcode 4

用戶設備禁用了手機的定位功能

9. 釘釘發送會話消息,cid如何獲取

使用場景示例:用戶在微應用中拉起本地聊天窗口列表(通過調用jsapi-獲取會話信息),選擇某一個聊天窗口,微應用將收到釘釘返回的cid,通過這個cid會送會話消息。

a.前提條件:jsapi可使用,即已經配置到dd.config,且通過jsapi的權限校驗

b.通過jsapi獲取會話cid,詳見獲取會話信息

10.errorMessage:」err msg redirect_uri domain is not secure domain」,」errorCode」:」3」

在oa後台設置微應用首頁地址(域名設置為可信域名,即可安全訪問授權)

11.讀取nfc芯片接口無法使用

[font=微軟雅黑, ‘Microsoft Yahei’, ‘Hiragino Sans GB’, tahoma, arial, 宋體]目前nfc芯片接口只支持android(文檔中已註明,請查看文檔)

三、服務端API

1.調用管理通訊錄接口返回43004,無效的HTTP HEADER Content-Type如何解決

管理通訊錄的部分接口採用了POST請求,請求體使用JSON格式,請在HTTP請求頭中設置Content-Type:application/json

2.上傳文件不成功

使用multipart/form-data請求上傳文件,需要附加文件標示信息,參數名為media;java示例代碼為

HttpEntity requestEntity =MultipartEntityBuilder.create().addPart(“media”, new FileBody(file, ContentType.APPLICATION_OCTET_STREAM, file.getName())).build();

3.新建部門和員工信息為中文時,創建不成功

請檢查編碼格式,確認是utf-8編碼

4.註冊事件回調接口,每個corpid只能註冊一個回調url嗎

一個企業的一個套件,只能註冊一個回調url

5.返回系統繁忙錯誤

(1)調試調用接口過程中出現,請先確保是否是JSON格式錯誤,比如POST時有的JSON里缺少了這種括號[ ]

(2)請檢查url是否正確,如免登接口,通過code換取用戶信息,/getuserinfo,實際應為/user/getuserinfo

(3)調用其他接口也返回系統繁忙,請您立刻在答疑群或論壇等反饋給釘釘人員

四、ISV接入問題

1.開發者平台創建套件校驗url有效性問題

如果返回字符串不匹配,提示錯誤代碼71009,可以通過以下常見問題確認具體原因:

a.可以通過將加密數據在本地解密下,看解密後的數據是否正確

b.查看是否是各字段名字錯誤,如timeStamp,卻寫成了timestamp

2.ISV接入回調接口沒有suiteticket推送

註冊套件之後,釘釘服務器會向填寫的回調接口推送suite_ticket;接收到推送之後需要返回加密後的字符串「success」,如果不返回或返回錯誤,釘釘服務器將連續推送,直到推送次數超過100次,就不再推送;

此時需要進入開發者後台,進入套件管理頁面,點擊『重新推送』按鈕,即可重新推送

3.回調地址接收釘釘服務器推送下來的數據,遇到計算解密文字錯誤

請查看加解密庫和demo下載第二個步驟,見加解密庫和demo下載

4.模擬測試企業發起授權所有套件,收不到臨時授權碼,而是change_auth

在開發者平台,目前授權行為只能發起一次,如已經收到臨時授權碼,模擬測試企業發起授權行為,收到change_auth事件;

測試企業解授權功能近期會上線,請關注文檔及論壇更新

5.不存在的臨時授權碼

臨時授權碼只能使用一次,使用後再次使用會提示「不存在的臨時授權碼」

6. isv開發中,如果permanentCode沒有存下來,如何獲取到

目前沒有辦法獲取,可以通過解除授權再次授權重新獲取,解除授權功能暫時未開放,請在文檔及論壇關注開放時間

7. 微應用性能測試提供的測試號碼加不進去

微應用性能測試提供的3個測試號碼,使用釘釘開放平台通訊錄接口添加的話,有最多加入5個非認證企業限制;建議通過釘釘管理後台()的通訊錄進行添加

8.微應用性能測試報告中的圖像中,顯示無權查看該頁面可能原因

請將在測試的h5地址直接在釘釘會話中打開,如找一個聊天會話,把要測試的h5地址直接貼在會話中,並點擊打開

a.如果打開提示無權查看該頁面,則是h5地址問題;

b.如果打開正常,請聯繫釘釘值班同學反饋;

10.IP白名單問題,返回errcode”:60020″,訪問ip不在白名單之中

調用釘釘API的機器需要配置在開發者平台中配置白名單

11.如何解除開發者平台的釘釘賬號綁定

暫未提供開發者平台、雲市場與釘釘賬號解綁功能,請關注官方文檔及論壇,若提供會同步更新

12.第三方ISV的套件開發完,如何與釘釘接入合作,讓其他企業授權使用套件

ISV開發完成套件後,需要對微應用進行性能評測等(微應用性能評測),以及在釘釘應用市場進行上架後,才可被其他企業用戶搜索到,並進行購買授權等操作;

可關注文檔對應用市場內容的更新,可發送郵件至郵件組open-dingtalk@list.alibaba-inc.com進行諮詢

13.isv如何獲取企業中用的mobile和email

如果在開發者後台勾選了郵箱字段,則可以獲取用戶的email;mobile暫不提供

14.isv demo中返回創建套件時返回解密文字或corpid或者suiteKey不匹配

(1)在 ENV文件中

[font=’Helvetica Neue’, Helvetica, Arial, sans-serif]public static final String CREATE_SUITE_KEY = “suite4xxxxxxxxxxxxxxx”;//首次創建套件校驗url時使用;

public static final String SUITE_KEY = “”;//已有套件時使用

(2)IsvReceiveServlet中

dingTalkEncryptor = new DingTalkEncryptor(Env.TOKEN, Env.ENCODING_AES_KEY, Env.SUITE_KEY);

第三個參數使用,如果首次創建校驗url使用 Env.CREATE_SUITE_KEY,即

dingTalkEncryptor = new DingTalkEncryptor(Env.TOKEN, Env.ENCODING_AES_KEY, Env. CREATE_SUITE_KEY);

如果已有套件,使用Env.SUITE_KEY,且在ENV文件中將public static final String SUITE_KEY = “xxxx”;賦值,即

dingTalkEncryptor = new DingTalkEncryptor(Env.TOKEN, Env.ENCODING_AES_KEY, Env.SUITE_KEY);

五、通用問題

1.isv接入demo

最近收到isv接入demo存在加解密失敗問題,這部分demo正在更新,近期會更新(加解密庫和demo下載)

2.釘釘https下使用oss Js SDK請求ERRSSLPROTOCOLERROR

六、常見需求及建議回復

1.發Ding的接口是否支持

釘釘不對外提供提供服務端ding接口

2.釘釘是否開放公告接口

釘釘暫不開放公告接口

3.釘釘是否提供審批、簽到等微應用接口,便於第三方系統數據對接

目前只提供了管理日曆接口接入,詳見管理日曆接入指南;

其他暫未提供

4.釘釘產品如何與企業內部的ERP系統實現對接

(1)可以基於釘釘開放平台開發一個報表的微應用,釘釘提供免登機制獲取用戶信息,報表權限由你開發的微應用進行控制

(2)微應用是基於H5開發的,因此可以基於H5開發圖標展示

(3)企業內部的文件可以通過釘盤進行存儲,也可以存放在自己的服務器,在微應用內進行下載

以上實現均需開發微應用

釘釘電子簽名怎麼弄

釘釘支持電子簽名的功能,重要事項審批在手機上就可以完成簽字了,簽字還可以打印在審批單上留檔,保證重要事項審批安全合規。那釘釘電子簽名怎麼弄?

釘釘電子簽名怎麼弄?

1、管理員在企業後台管理的「工作台」界面點擊【審批】。

2、進入審批模板編輯,在「流程高級設置」中打開【手寫簽名】開關。

本文以華為matebook x pro 2021為例適用於windows 11系統釘釘V6.3.25版本

php怎麼獲取釘釘員工授權信息?

做過一個E應用,使用lumen框架,和你的思路是一樣的,新用戶點進去就自動授權註冊應用,數據存到我們自己的數據庫中,不依賴釘釘,我們還同步了部門信息,如果粘貼複製和下面的那個同學一樣,看上去你也會覺得懵,方法都是封裝好了的。

建議你這樣試試看:

 獲取AccessToken:

後端通過corpid,corpsecret請求接口gettoken?corpid=idcorpsecret=secrect獲取AccessToken

獲取釘釘用戶userid:

前端需要相應的處理,攜帶authCode請求,加上AccessToken這兩個參數請求接口/user/getuserinfo?access_token=access_tokencode=authCode這個

獲取釘釘用戶詳情:

使用access_token和上一步的釘釘userid 請求接口 /user/get?access_token=ACCESS_TOKENuserid=

插入釘釘用戶的數據到你的 數據庫中

我們這樣做的:

/**

* 釘釘免登陸獲獲取用信息

* @param $authCode

* @param $url

* @return array

*/

static function outhLogin($authCode, $url)

{

if (empty($authCode) || empty($url)) {

return self::returnError(‘1101’, self::$errorArray[‘1101’]);

}

$accessToken = ComponentDingtalk::getPcAccessToken();

if ($accessToken[‘code’]) {

self::logError(__CLASS__ . ‘-‘ . __FUNCTION__, ‘獲取access_token失敗’);

return self::returnError(‘1102’, self::$errorArray[‘1102’]);

}

$dingUserId = ComponentDingtalk::getDingUserid($accessToken[‘data’], $authCode);

if ($dingUserId[‘code’]) {

self::logError(__CLASS__ . ‘-‘ . __FUNCTION__, ‘用戶userid獲取失敗(調用釘釘API)’);

return self::returnError(‘1103’, self::$errorArray[‘1103’]);

}

$dinguserInfo = ComponentDingtalk::getDingUserInfo($accessToken[‘data’], $dingUserId[‘data’]);

if ($dinguserInfo[‘code’]) {

self::logError(__CLASS__ . ‘-‘ . __FUNCTION__, ‘用戶信息獲取失敗(調用釘釘API)’);

return self::returnError(‘1104’, self::$errorArray[‘1004’]);

}

$userInfo = $dinguserInfo[‘data’];

return self::transaction(function () use ($accessToken, $userInfo, $url) {

if (\count($userInfo[‘department’]) 1) {

$departIdArr = [];

$departNameArr = [];

for ($i = 0, $iMax = \count($userInfo[‘department’]); $i $iMax; $i++) {

$departInfo[$i] = ServerDepartment::getByDdDepartid($userInfo[‘department’][$i]);

$departIdArr[] = $departInfo[$i][‘id’];

$departNameArr[] = $departInfo[$i][‘name’];

}

$depart[‘id’] = implode(‘,’, $departIdArr);

$depart[‘name’] = implode(‘,’, $departNameArr);

} else {

$ddDepartmentId = implode(‘,’, $userInfo[‘department’]);

$depart = ServerDepartment::getByDdDepartid($ddDepartmentId);

}

//插入用戶

$user = ServerEmployee::getByDdUserid($userInfo[‘userid’]);

if ($user $user[‘status’] == 2) {

return self::returnError(‘1105’, self::$errorArray[‘1105’]);

}

if (empty($user)) {

$roleId = 0;

$departId = $depart[‘id’];

$name = $userInfo[‘name’];

$mobile = $userInfo[‘mobile’];

$departName = $depart[‘name’];

$position = $userInfo[‘position’];

$ddUserid = $userInfo[‘userid’];

$ddStatus = $userInfo[‘active’] ? 1 : 2;

$ddInfo = json_encode($userInfo, JSON_UNESCAPED_UNICODE);

$tokenOverAt = (int)(time() + $_ENV[‘PROJECT_apiAppTokenOverTime’]);

$token = self::_createToken($userInfo[‘userid’], $tokenOverAt);

$status = 1;

$userId = ServerEmployee::insert($roleId, $departId, $name, $mobile, $departName, $position, $ddUserid, $ddStatus, $ddInfo, $token, $tokenOverAt, $status);

if (!$userId) {

self::logError(__CLASS__ . ‘-‘ . __FUNCTION__, ‘用戶初始化創建失敗’);

return self::returnError(‘1106’, self::$errorArray[‘1106’]);

}

}

$userId = $userId ?? $user[‘id’];

// 更新Token

$id = $userId;

$roleId = $user[‘roleId’];

$departId = $depart[‘id’];

$name = $userInfo[‘name’];

$mobile = $userInfo[‘mobile’];

$departName = $depart[‘name’];

$position = $userInfo[‘position’];

$ddUserid = $userInfo[‘userid’];

$ddStatus = $userInfo[‘active’] ? 1 : 2;

$ddInfo = json_encode($userInfo, JSON_UNESCAPED_UNICODE);

$tokenOverAt = (int)(time() + $_ENV[‘PROJECT_apiAppTokenOverTime’]);

$token = self::_createToken($userInfo[‘userid’], $tokenOverAt);

$status = 1;

$updateParams = ServerEmployee::update($id, $roleId, $departId, $name, $mobile, $departName, $position, $ddUserid, $ddStatus, $ddInfo, $token, $tokenOverAt, $status);

if (!$updateParams) {

self::logError(__CLASS__ . ‘-‘ . __FUNCTION__, ‘用戶信息更新失敗’ . json_encode($updateParams, JSON_UNESCAPED_UNICODE) . ‘/’ . json_encode([$id, $roleId, $departId, $name, $mobile, $depart, $position, $ddUserid, $ddStatus, $ddInfo, $token, $tokenOverAt, $status]));

return self::returnError(‘1107’, self::$errorArray[‘1107’]);

}

// 前端的配置信息

// 獲取jsTicket

$jsTicket = ComponentDingtalk::getPcJsTicket($accessToken[‘data’]);

if ($jsTicket[‘code’]) {

self::logError(__CLASS__ . ‘-‘ . __FUNCTION__, ‘獲取jsTicket失敗(調用釘釘API)’);

return self::returnError(‘1111’, self::$errorArray[‘1111’]);

}

// 組裝簽名數據

$curUrl = $url;;

$nonceStr = uniqid(”, true);

$agentId = $_ENV[‘PROJECT_ddInterfaceAgentID’];

$timeStamp = time();

$corpId = $_ENV[‘PROJECT_ddInterfaceCorpId’];

$signature = ComponentDingtalk::getSign($jsTicket[‘data’], $nonceStr, $timeStamp, $curUrl);

$config = array(

‘url’ = urldecode($curUrl),

‘nonceStr’ = $nonceStr,

‘agentId’ = $agentId,

‘timeStamp’ = $timeStamp,

‘corpId’ = $corpId,

‘signature’ = $signature

);

// 獲取當前角色的權限

$roleInfo = ServerRole::getById($roleId);

// 當前用戶的頂級部門(不含根部門)

$departInfo = ServerDepartment::getById($departId);

if ($departInfo[‘parentid’] == 1) {  // 二級部門(總經辦)

$departRootId = $departId;

$departRootName = $departName;

} else {

$sonDepart = ServerDepartment::getById($departInfo[‘parentid’]);//分組

if ($sonDepart[‘parentid’] == 1) {

$departRootId = $sonDepart[‘id’];

$departRootName = $sonDepart[‘name’];

} else {

$grandsonDepart = ServerDepartment::getById($sonDepart[‘parentid’]);//部門

if ($grandsonDepart[‘parentid’] == 1) {

$departRootId = $grandsonDepart[‘id’];

$departRootName = $grandsonDepart[‘name’];

} else {

$grandchildDepart = ServerDepartment::getById($grandsonDepart[‘parentid’]);//分公司

$departRootId = $grandchildDepart[‘id’];

$departRootName = $grandchildDepart[‘name’];

}

}

}

$company = ServerDepartment::get([‘parentid’ = 0, ‘dd_departid’ = 1]);

return self::returnSuccess(array(

‘id’ = $userId,

‘name’ = $name,

‘token’ = $token,

‘tokenOverAt’ = $tokenOverAt,

‘config’ = $config,

‘power’ = $roleInfo[‘power’] ?? ”,

‘departId’ = $departId,

‘departName’ = $departName,

‘departRootId’ = $departRootId,

‘departRootName’ = $departRootName,

‘company’ = $company[‘name’],

));

}, function (\Exception $e) {

echo $e-getMessage();

self::logError(__CLASS__ . ‘-‘ . __FUNCTION__, $e-getMessage());

return self::returnError(‘1108’, self::$errorArray[‘1108’]);

});

}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/283091.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-22 08:06
下一篇 2024-12-22 08:07

相關推薦

  • PHP和Python哪個好找工作?

    PHP和Python都是非常流行的編程語言,它們被廣泛應用於不同領域的開發中。但是,在考慮擇業方向的時候,很多人都會有一個問題:PHP和Python哪個好找工作?這篇文章將從多個方…

    編程 2025-04-29
  • PHP怎麼接幣

    想要在自己的網站或應用中接受比特幣等加密貨幣的支付,就需要對該加密貨幣擁有一定的了解,並使用對應的API進行開發。本文將從多個方面詳細闡述如何使用PHP接受加密貨幣的支付。 一、環…

    編程 2025-04-29
  • 使用PHP foreach遍歷有相同屬性的值

    本篇文章將介紹如何使用PHP foreach遍歷具有相同屬性的值,並給出相應的代碼示例。 一、基礎概念 在講解如何使用PHP foreach遍歷有相同屬性的值之前,我們需要先了解幾…

    編程 2025-04-28
  • PHP獲取301跳轉後的地址

    本文將為大家介紹如何使用PHP獲取301跳轉後的地址。301重定向是什麼呢?當我們訪問一個網頁A,但是它已經被遷移到了另一個地址B,此時若服務器端做了301重定向,那麼你的瀏覽器在…

    編程 2025-04-27
  • PHP登錄頁面代碼實現

    本文將從多個方面詳細闡述如何使用PHP編寫一個簡單的登錄頁面。 1. PHP登錄頁面基本架構 在PHP登錄頁面中,需要包含HTML表單,用戶在表單中輸入賬號密碼等信息,提交表單後服…

    編程 2025-04-27
  • PHP與Python的比較

    本文將會對PHP與Python進行比較和對比分析,包括語法特性、優缺點等方面。幫助讀者更好地理解和使用這兩種語言。 一、語法特性 PHP語法特性: <?php // 簡單的P…

    編程 2025-04-27
  • PHP版本管理工具phpenv詳解

    在PHP項目開發過程中,我們可能需要用到不同版本的PHP環境來試驗不同的功能或避免不同版本的兼容性問題。或者我們需要在同一台服務器上同時運行多個不同版本的PHP語言。但是每次手動安…

    編程 2025-04-24
  • PHP數組去重詳解

    一、array_unique函數 array_unique是php中常用的數組去重函數,它基於值來判斷元素是否重複,具體使用方法如下: $array = array(‘a’, ‘b…

    編程 2025-04-24
  • PHP導出Excel文件

    一、PHP導出Excel文件列寬調整 當我們使用PHP導出Excel文件時,有時需要調整單元格的列寬。可以使用PHPExcel類庫中的setWidth方法來設置單元格的列寬。下面是…

    編程 2025-04-24
  • php擴展庫初探

    一、什麼是php擴展庫? PHP擴展庫(PHP extension)是一些用C語言編寫的動態鏈接庫,用於擴展PHP的功能。PHP擴展庫使得PHP可以與各種數據庫系統相連、SMTP、…

    編程 2025-04-23

發表回復

登錄後才能評論