一、開發插件所需資料與工具
1、DiscuzX3 插件機制
插件機制Discuz! 擁有一套完整的插件機制。
合理使用插件機制,你可以更好的將自己的個性功能需求整合到Discuz!產品中的同時,保持代碼獨立,并且不受后續Discuz!產品版本升級的影響。
我們鼓勵并推薦,使用插件機制進行個性需求定制和研發。
插件設計的準備工作
插件實現流程
開始編寫社區插件,您應當首先對插件實現的流程有一個大致的了解,以下是我們推薦的插件編寫流程:
•?
熟練使用 Discuz! 社區系統后,對希望完善或補充的個性化功能進行評估,進而提出插件的功能需求。
•?對插件做一個概括性的設計,例如:需要使用什么菜單、什么參數,配置哪些選項、數據結構如何設計、前后臺實現哪些功能等等。
•?閱讀本文檔并在系統設置中實際體驗 Discuz! 插件接口所實現的功用,例如:您的插件應當如何設計才能良好的掛接到社區系統中來。插件接口能夠實現哪些功能、不能實現哪些功能,插件為此而需要做的優化、改造和取舍。
•?編寫相應程序代碼和模板語句,實現所需的功能并進行代碼測試、兼容性測試和代碼改進。
•?如果需要公開您的插件,可以用插件導出的方式,將插件配置信息導出到一個 XML 文件中,連同相應的程序和模板文件一同打包。同時,編寫一個適合新手的插件的說明書也是必不可少的,其中包括:插件適用的 Discuz! 版本、功能概述、兼容性聲明、安裝方法、使用方法、卸載方法等等。
•?將插件提供給他人,或自己使用,根據使用者反饋,對插件進行完善。插件實現流程至此結束。
•?
文件命名規范
Discuz! 按照如下的規范對程序和模板進行命名,請在設計插件時盡量遵循此命名規范:
•?可以直接通過瀏覽器訪問的普通程序文件,以 .php 后綴命名。
•?被普通程序文件引用的程序文件,以 .inc.php 后綴命名。
•?被普通程序文件,或引用程序文件引用的函數庫或類庫,以 .func.php(函數庫) 或 .class.php(類庫) 后綴命名。
•?模板文件,以 .htm 后綴命名,插件模板文件存在于 source/plugin/identifier/template/ 目錄中,手機版插件模板存在于 source/plugin/identifier/template/mobile/目錄中
•?模板語言包文件,以 .lang.php 后綴命名,插件語言包文件開發時存放于 data/plugindata/ 目錄中,文件名為identifier.lang.php。
•?動態緩存文件,存放于 ./data/cache 目錄中,依據不同的功用進行獨立的命名。
•?使用后臺數據備份功能生成的備份文件,通常以 .sql 為后綴,存放于 data/ 目錄中。
•?有些目錄中存在內容為空白的 index.htm 文件,此類文件是為了避免 Web 服務器打開 Directory Index 時可能產生的安全問題。
•?[X2.5新增內容] 從 Discuz! X2.5 開始,產品對數據表進行了封裝,封裝后的文件統一命名為 Table 類,通過“C::t(Table類文件名)”方式調用。插件如需封裝自己的數據表,可將 Table 類文件存放于 source/plugin/identifier/table/ 目錄下,并以 table_表名.php 格式命名,詳見X2.5的新程序架構。
•?
class_core.php 模塊功能白皮書
source/class/class_core.php 是 Discuz! 的通用初始化模塊程序,其幾乎被所有的外部代碼所引用,在您開始插件設計之前,可以先對該模塊的大致功能做一定的了解。class_core.php 主要完成了以下任務:
•?對不同 PHP 及操作系統環境做了判斷和兼容性處理,使得 Discuz! 可以運行于各種不同配置的服務器環境下。
•?初始化常量 IN_DISCUZ 為 TRUE,用于 include 或 require 后續程序的判斷,避免其他程序被非法引用。
•?讀取社區程序所在絕對路徑,存放于常量 DISCUZ_ROOT 中。
•?加載所需的基本函數庫 source/function/function_core.php。
•?通過 config/config_global.php 中提供的數據庫賬號信息,建立數據庫連接。Discuz! 支持數據表的前綴,如需獲得表的全名,可使用“DB::table('tablename')”方式。
•?判斷用戶是否登錄,如登錄標記 $_G['uid'] 為非 0,同時將 $_G['username'](加了 addslashes 的用戶名,可用于不加修改的插入數據庫)、 $_G['member']['username'](原始的用戶名,可用于頁面顯示)、$_G['member']['password'](用戶密碼的MD5串)等相應用戶信息賦值,其他用戶信息存放于 $_G['member'],更多信息可通過“getuserprofile()”獲取。
•?判斷用戶管理權限,將管理權限標記 $_G['adminid'] 為 1~3 中間的值。0 代表普通用戶;1 代表論壇管理員;2 代表超級版主;3 代表論壇版主。 將用戶權限按照其所在的主用戶組 ID 標記為 $_G['groupid'],相關權限從該 $_G['groupid'] 所對應的系統緩存中讀出,存放于 $_G['group']。
•?預置讀入了每個模塊的各種設置變量。
•?[X2.5變更內容] $_G['username'] 將不進行 addslashes 處理。
插件接口概述
使用管理員賬號登錄 Discuz! 管理中心,在頂部菜單將可以看到“插件”菜單。“插件列表”列出了所有已安裝的插件,是控制插件打開與否、設計插件模塊、菜單、參數和使用權限的地方,插件開發者可以依照設計意圖,在此進行插件的初步設置,這里同時也提供插件導入和插件開關的功能,用于導入他人設計的插件和對插件的可用狀態進行變更。
開始編寫一個新插件,請首先打開 config/config_global.php 文件,在文件結尾添加以下代碼開啟插件設計者模式。
•?$_config['plugindeveloper'] = 1;
在插件管理中選擇“設計新插件”,填寫插件名稱,名稱用于表明此插件的用途,例如設置為“虛擬銀行插件”。惟一標識符用于在后續的插件模塊中調用本插件,不可與現有插件重復,命名規則限制與 PHP 變量命名相同,雖然初次設置后仍可改動,但強烈建議一次性將此配置設置好,否則可能涉及到很多代碼方面的變更,增加編碼的麻煩。請注意:惟一標識符請不要設置的過短,或使用有可能與其他插件重復的命名,例如制作此插件的公司叫做 Comsenz Inc.,插件名稱是“虛擬銀行插件”,惟一標識符可設置為“comsenz_virtual_bank”。最后在 source/plugin/ 目錄中創建與唯一標識符同名的目錄名,如 source/plugin/comsenz_virtual_bank/。
在插件管理中添加插件后,僅僅是增加了一條插件記錄,后面還需要很多相關的設計和設置。在列表中選擇插件的“詳情”進入插件的詳細設置。插件設置分為三個部分:
•?
插件模塊
插件模塊分為程序鏈接、擴展項目和程序腳本 3 類:
程序鏈接 主導航項目:可在主導航欄增加一個菜單項,可自主指派菜單鏈接的 URL,也可以調用插件的一個模塊,模塊文件名指派為 source/plugin/插件目錄/插件模塊名.inc.php”。注意:由于引用外部程序,因此即便設置了模塊的使用等級,您的程序仍需進行判斷使用等級是否合法。
•?程序鏈接 主導航項目 - 插件菜單:可在主導航欄的插件子菜單中增加一個菜單項。
•?程序鏈接 頂部導航項目、底部導航項目、快捷導航項目、家園導航項目:可在各個導航中增加一個菜單項。
•?擴展項目 個人設置:可在個人設置中增加一個菜單項。
•?擴展項目 個人設置 - 個人資料:可在個人設置的個人資料頁上部增加一個菜單項。
•?擴展項目 個人設置 - 積分:可在個人設置的積分頁上部增加一個菜單項。
•?擴展項目 站點幫助:可在站點幫助中增加一個菜單項。
•?擴展項目 我的帖子:可在我的帖子中增加一個菜單項。
•?擴展項目 門戶管理:可在門戶管理面板上部增加一個菜單項。
•?擴展項目 論壇管理 - 基本:可在前臺論壇管理面板側邊上部增加一個菜單項。
•?擴展項目 論壇管理 - 工具:可在前臺論壇管理面板側邊下部增加一個菜單項。
•?擴展項目 管理中心:可在后臺插件欄目中為此插件增添一個管理模塊。
•?程序腳本 頁面嵌入 - 普通版:設置一個包含頁面嵌入腳本的模塊,該模塊用于在普通電腦訪問的頁面顯示。模塊文件名指派為 source/plugin/插件目錄/插件模塊名.class.php”。(頁面嵌入將在后面的《頁面嵌入模塊開發》中詳細說明)
•?程序腳本 頁面嵌入 - 手機版:設置一個包含頁面嵌入腳本的模塊,該模塊用于在手機訪問的頁面顯示。
•?程序腳本 特殊主題:設置一個特殊主題腳本的模塊,模塊文件名指派為 source/plugin/插件目錄/插件模塊名.class.php”。(特殊主題將在后面的《特殊主題模塊開發》中詳細說明)
•?
您可以為每個模塊設置不同的使用等級,例如設置為“超級版主”,則超級版主及更高的管理者可以使用此模塊。
擴展項目模塊可以在社區的特定位置擴展出新的功能,通常用于擴展新的設置項目。項目的腳本文件以 .inc.php 結尾(如 test.inc.php),模版為固定文件名,位于插件目錄的 template/ 子目錄中,文件名與腳本名同名(如 test.htm),擴展名為 .htm。添加相應的擴展項目模塊時,需注明程序模塊、菜單名稱。例如我們添加個人面板項目,程序模塊為 test,菜單名稱是“測試”,當插件啟用后,個人面板即家園的設置中會出現“測試”拓展項目。
在新插件內核中,通過 plugin.php 方式訪問的插件可直接通過 plugin.php?id=xxx:yyy 方式調用而無需再在后臺定義為普通腳本模塊,只要 source/plugin/xxx/yyy.inc.php 文件存在即可。如果 xxx 和 yyy 同名,可直接通過 plugin.php?id=xxx 方式訪問。
插件變量配置
插件接口中提供了一個通用的插件配置管理程序,在大多數情況下可實現插件的參數配置,省卻了插件開發者自行編寫后臺管理模塊(即上面提到的“擴展項目 管理中心”模塊)的麻煩。通常情況下,應優先使用通用插件配置管理程序來實現插件的參數配置,只有在通用程序確實無法實現時,才自行編寫后臺管理模塊。輸入配置名稱和配置變量名、選擇合適的配置類型后,即可為此插件增加一個配置變量,點“詳情”可以編輯此配置變量的更多信息。為了方便插件程序調用使用者配置好的參數,配置變量同樣被存放在了緩存文件中,讀取方法將在后面的《插件的參數讀取與緩存控制》中詳細說明。
注意:您只有在插件管理中將插件設置為“可用”,以上設置才能生效。
插件的參數讀取與緩存控制
•?編寫插件程序時,可能需要讀取一些插件的信息,如果插件需要使用者進行配置,還需要讀取使用者設置的參數值。Discuz! 允許插件程序使用數據庫讀取和緩存讀取這兩種方法獲取插件信息和參數。Discuz! 的插件接口已經對插件信息進行了合理的緩存,使用緩存讀取的方式,將比數據庫讀取速度更快,消耗的資源更是幾乎可以忽略不計。緩存讀取唯一的局限是需要插件使用插件接口提供的通用后臺管理程序。如果使用自定義后臺模塊的方式,需要后臺模塊將參數存放到 pluginvars 數據表中,才能被系統正常緩存。我們強烈推薦您通過緩存讀取插件信息和配置數據。
•?
由于調用系統緩存統一通過“loadcache()”函數調用,并存放于 $_G['cache'] 中,因此“loadcache('plugin')”后插件的變量緩會存放于 $_G['cache']['plugin'] 中。嵌入點插件和以 plugin.php 為主腳本調用的插件無需加載此緩存,系統已自動加載了緩存。變量配置類型為“版塊/*”的變量會保存在 $_G['cache']['forums'][fid]['plugin'] 中。變量配置類型為“用戶組/*”的變量會保存在 $_G['cache']['usergroup_groupid']['plugin'] 和 $_G['group']['plugin'] 中。
頁面嵌入模塊開發
頁面嵌入類型腳本格式<?php//全局嵌入點類(必須存在)class plugin_identifier { function HookId_1() { ...... return ...; } function HookId_2() { ...... return ...; } ......}//腳本嵌入點類class plugin_identifier_CURSCRIPT extends plugin_identifier { function HookId_1() { ...... return ...; } function HookId_2() { ...... return ...; } ......}?>
•?plugin_
•?普通版腳本中的類名以 plugin_ 開頭。手機版腳本中的類名以 mobileplugin_ 開頭。
•?identifier
•?插件的唯一標識符,在插件設置中設置。
•?CURSCRIPT
•?嵌入點位于的腳本名,如 forum.php 為 forum。
•?HookId
函數名 調用位置 聲明位置 參數含義
HookId() 所有模塊執行前被調用 腳本嵌入點類
HookId_output($value) 模塊執行完畢,模板輸出前被調用 腳本嵌入點類 $value: array('template' => 當前要輸出的模版,'message' => showmessage 的信息內容,'values' => showmessage 的信息變量,
)
global_HookId() 模塊執行完畢,模板輸出前被調用 全局嵌入點類
HookId_message($value) showmessage() 執行時調用 腳本嵌入點類 $value: array('param' => showmessage() 函數的參數數組,
)
ad_adId($value) 相應的廣告位中調用
函數名為廣告位腳本 ID 如:ad_headerbanner() 全局嵌入點類
腳本嵌入點類 $value: array('params' => 廣告位參數,'content' => 當前廣告位原本將要顯示的內容,
)
common() 所有模塊執行前被調用 全局嵌入點類
discuzcode($value) discuzcode() 函數執行時調用
用于在帖子內容解析時嵌入自己的功能,函數中 $_G['discuzcodemessage'] 變量為待解析的字串 全局嵌入點類 $value: array('param' => caller 函數的參數數組,'caller' => caller 函數,此嵌入點被哪個函數調用'discuzcode' 被 discuzcode() 調用'messagecutstr' 被 messagecutstr() 調用
)
deletethread($value) deletethread() 函數執行時調用
用于在主題刪除前后嵌入自己的功能,此函數將在 deletethread() 中被調用 2 次,函數中 $_G['deletethreadtids'] 變量為待處理的 TID 數組 全局嵌入點類 $value: array('param' => deletethread() 函數的參數數組,'step' => 刪除的步驟'check' 檢測步驟'delete' 刪除步驟
)
deletepost($value) deletepost() 函數執行時調用
用于在帖子刪除前后嵌入自己的功能,此函數將在 deletepost() 中被調用 2 次,函數中 $_G['deletepostids'] 變量為待處理的 ID 數組 全局嵌入點類 $value: array('param' => deletepost() 函數的參數數組,'step' => 刪除的步驟'check' 檢測步驟'delete' 刪除步驟
)
avatar($value)
(X2.5 新增) avatar() 函數執行時調用
用于在頭像調用時嵌入自己的功能,函數中 $_G['hookavatar'] 變量為新頭像返回值 全局嵌入點類 $value: array('param' => avatar() 函數的參數數組
)
profile_node($post, $start, $end)
(X3.0 新增) 貼內用戶信息標記,返回值為標記顯示內容 全局嵌入點類 $post: 當前帖子信息數組
$start: 用戶填寫的前置字符
$end: 用戶填寫的后置字符
要查看所有的預定義嵌入點,請打開 config/config_global.php 文件,將文件結尾添加的設計者模式值改成“2”,然后更新緩存即可。在頁面源碼中查找"<hook>"可搜索到嵌入點。(詳細內容可參閱的《插件嵌入點列表》)
$_config['plugindeveloper'] = 2;
預定義的嵌入點會在頁面預置好的位置輸出函數返回的內容。函數返回值類型如果是 array 且是空值的,必須輸出一個空數組,如:
return array();
函數名并不限于以上列表,您可以自定義,只要符合以下規則,函數就會在適當的地方被調用。
function CURMODULE_USERDEFINE[_output]()
CURMODULE 指明了此函數在哪個模塊執行,可通過常量 CURMODULE 得到當前頁面的 CURMODULE 值。 USERDEFINE 可自定義,如果函數名以“_output”結尾則會在模板輸出前調用,否則會在模塊執行前調用。 如:attachment_test() 函數會在論壇的下載附件的時候執行。 “_output”結尾的函數的第一個參數為數組,含義為 array('template' => 要輸出的模板名, 'message' => showmessage 的文字) 如:以下函數將在登錄的時候輸出調試文字
function logging_test_output($a) { print_r($a); print_r($_POST);}
plugin_identifier 類中的其它函數為了便于閱讀建議以“_”開頭,如:
<?phpclass plugin_sample { function _updatecache() { ...... return ...; }}class plugin_sample_forum extends plugin_sample { function viewthread_posttop() { ...... return ...; } ......}?>
插件嵌入點列表
• 全局(common/)
extcredits.htm string spacecp_credit_extra faq.htm string faq_extra footer.htm string global_footer string global_footerlink header.htm string global_cpnav_top (X2.5) string global_cpnav_extra1 string global_cpnav_extra2 string global_qmenu_top (X3) string global_qmenu_bottom (X3) string global_nav_extra (X2.5) string global_header userabout.htm array global_userabout_top string userapp_menu_top string userapp_menu_middle array global_userabout_bottom userstatus.htm string global_usernav_extra1 string global_usernav_extra2 string global_usernav_extra3 string global_usernav_extra4 (X2.5)
• 論壇(forum/)
collection_all.htm (X2.5) string collection_index_top string collection_index_bottom collection_comment.htm (X2.5) string collection_nav_extra collection_index.htm (X2.5) string collection_index_top string collection_index_bottom collection_mycollection.htm (X2.5) string collection_index_top string collection_index_bottom collection_nav.htm (X2.5) string collection_nav_extra collection_view.htm (X2.5) string collection_viewoptions string collection_view_top string collection_threadlistbottom string collection_relatedop string collection_view_bottom string collection_side_bottom discuz.htm string index_status_extra string index_nav_extra (X2.5) string index_top string index_catlist_top (X2.5) array index_followcollection_extra (X3) array index_favforum_extra (X2.5) array index_favforum_extra (X3) array index_catlist (X2.5) array index_forum_extra (X2.5) array index_forum_extra (X2.5) array index_datacollection_extra (X3) string index_middle string index_bottom string index_side_top string index_side_bottom discuzcode.htm array viewthread_attach_extra (X2.5) editor_menu_forum.htm string post_image_btn_extra string post_image_tab_extra string post_attach_btn_extra string post_attach_tab_extra forumdisplay.htm string forumdisplay_leftside_top string forumdisplay_leftside_bottom string forumdisplay_forumaction string forumdisplay_modlink string forumdisplay_top string forumdisplay_middle string forumdisplay_postbutton_top string forumdisplay_threadtype_inner (X2.5) string forumdisplay_filter_extra (X2.5) string forumdisplay_threadtype_extra (X2.5) string forumdisplay_bottom string forumdisplay_side_top string forumdisplay_side_bottom forumdisplay_fastpost.htm string forumdisplay_fastpost_content string forumdisplay_fastpost_func_extra string forumdisplay_fastpost_ctrl_extra string global_login_text string forumdisplay_fastpost_upload_extend (X3) string forumdisplay_fastpost_btn_extra string forumdisplay_fastpost_sync_method forumdisplay_list.htm string forumdisplay_filter_extra array forumdisplay_thread array forumdisplay_thread_subject (X2.5) array forumdisplay_author array forumdisplay_thread (X2.5) array forumdisplay_author (X2.5) string forumdisplay_threadlist_bottom (X2.5) string forumdisplay_postbutton_bottom forumdisplay_sort.htm (X2.5) string forumdisplay_postbutton_bottom forumdisplay_subforum.htm (X2.5) array forumdisplay_subforum_extra array forumdisplay_subforum_extra guide.htm string guide_nav_extra string guide_top string guide_bottom index_navbar.htm string index_navbar post.htm string post_top string post_middle string post_btn_extra string post_sync_method string post_bottom string post_upload_extend (X3) post_activity.htm string post_activity_extra post_debate.htm string post_debate_extra post_editor_attribute.htm (X3) string post_attribute_extra string post_attribute_extra_body post_editor_body.htm string post_editorctrl_right string post_editorctrl_left string post_editorctrl_top string post_editorctrl_bottom post_infloat.htm string post_infloat_top string post_infloat_middle string post_infloat_btn_extra post_poll.htm string post_poll_extra string post_poll_upload_extend (X3) post_reward.htm string post_reward_extra post_trade.htm string post_trade_extra topicadmin_modlayer.htm string forumdisplay_modlayer string modcp_modlayer trade_info.htm string viewthread_tradeinfo_extra viewthread.htm string viewthread_top string viewthread_postbutton_top string viewthread_modoption string viewthread_beginline (X2.5) string viewthread_title_extra string viewthread_title_row string viewthread_middle string viewthread_bottom viewthread_activity.htm string viewthread_activity_extra1 string viewthread_activity_extra2 viewthread_album.htm (X3) string viewthread_beginline string viewthread_useraction_prefix string viewthread_useraction string viewthread_bottom viewthread_fastpost.htm string viewthread_fastpost_side string viewthread_fastpost_content string viewthread_fastpost_func_extra string viewthread_fastpost_ctrl_extra string global_login_text string viewthread_fastpost_upload_extend (X3) string viewthread_fastpost_btn_extra (X2.5) viewthread_from_node.htm array viewthread_postheader array viewthread_postheader array viewthread_postheader array viewthread_endline viewthread_node.htm array viewthread_profileside array viewthread_imicons array viewthread_magic_user array viewthread_avatar array viewthread_sidetop array viewthread_sidebottom array viewthread_postheader string viewthread_modaction (X2.5) string viewthread_share_method string viewthread_useraction array viewthread_postsightmlafter (X2.5) array viewthread_postfooter array viewthread_postaction (X2.5) string viewthread_magic_thread array viewthread_magic_post array viewthread_endline viewthread_node_body.htm array viewthread_posttop string global_login_text array viewthread_postbottom viewthread_poll.htm string viewthread_poll_top string viewthread_poll_bottom viewthread_portal.htm string viewthread_useraction_prefix string viewthread_useraction string viewthread_side_bottom viewthread_preview_node.htm (X3) array viewthread_postheader array viewthread_endline viewthread_trade.htm array viewthread_trade_extra
• 群組(group/)
group.htm string group_navlink string forumdisplay_navlink string group_navlink string forumdisplay_navlink string group_top string forumdisplay_top string group_nav_extra string forumdisplay_nav_extra string group_bottom string forumdisplay_bottom string group_side_bottom string forumdisplay_side_bottom group_list.htm string forumdisplay_postbutton_top string forumdisplay_filter_extra array forumdisplay_thread string forumdisplay_postbutton_bottom group_my.htm string my_header string my_bottom string my_side_top string my_side_bottom group_right.htm string group_index_side string group_side_top string forumdisplay_side_top index.htm string index_header string index_top string index_bottom string index_side_top string index_side_bottom type.htm string index_top array index_grouplist string index_bottom string index_side_top string index_side_bottom
• 家園(home/)
editor_image_menu.htm (X3) string spacecp_blog_upload_extend string portalcp_top_upload_extend follow_feed.htm string follow_nav_extra string follow_top string follow_upload_extend (X3) string follow_nav_extra (X3) spacecp_avatar.htm string spacecp_avatar_top string spacecp_avatar_bottom spacecp_blog.htm string spacecp_blog_top string spacecp_blog_middle string spacecp_blog_bottom spacecp_credit_base.htm string spacecp_credit_top string spacecp_credit_extra string spacecp_credit_bottom spacecp_credit_log.htm string spacecp_credit_top string spacecp_credit_bottom spacecp_privacy.htm string spacecp_privacy_top string spacecp_privacy_base_extra string spacecp_privacy_feed_extra string spacecp_privacy_bottom spacecp_profile.htm string spacecp_profile_top string spacecp_profile_extra string spacecp_profile_bottom spacecp_promotion.htm string spacecp_promotion_top string spacecp_promotion_bottom spacecp_upload.htm (X3) string spacecp_upload_extend spacecp_usergroup.htm string spacecp_usergroup_top string spacecp_usergroup_bottom string spacecp_usergroup_top string spacecp_usergroup_bottom string spacecp_usergroup_top string spacecp_usergroup_bottom space_album_pic.htm string space_album_pic_top string space_album_pic_op_extra string space_album_pic_bottom string space_album_pic_face_extra space_album_view.htm string space_album_op_extra space_blog_list.htm array space_blog_list_status space_blog_view.htm string space_blog_title string space_blog_share_method (X2.5) string space_blog_op_extra string space_blog_face_extra space_card.htm string space_card_top string space_card_baseinfo_middle string space_card_baseinfo_bottom string space_card_option string space_card_magic_user string space_card_bottom space_comment_li.htm array global_space_comment_op (X3) string global_comment_bottom (X3) space_doing.htm string space_doing_top string space_doing_bottom space_favorite.htm string space_favorite_nav_extra space_friend.htm string space_interaction_extra space_header.htm string global_usernav_extra1 string global_usernav_extra2 space_home.htm string space_home_navlink (X3) string space_home_side_top (X2.5) string space_home_side_bottom string space_home_top string space_home_navlink string space_home_bottom space_magic.htm (X2.5) string magic_nav_extra space_medal.htm (X2.5) string medal_nav_extra space_menu.htm string space_menu_extra space_profile_body.htm string space_profile_baseinfo_top string follow_profile_baseinfo_top (X2.5) string space_profile_baseinfo_middle string follow_profile_baseinfo_middle (X2.5) string space_profile_baseinfo_bottom string follow_profile_baseinfo_bottom (X2.5) string space_profile_extrainfo string follow_profile_extrainfo (X2.5) space_share_li.htm array space_share_comment_op space_status.htm string space_home_doing_sync_method space_wall.htm string space_wall_face_extra
• 注冊/登錄(member/)
login.htm string logging_side_top string logging_top string logging_input string logging_method login_simple.htm string global_login_extra register.htm string register_side_top string register_top string register_input string register_logging_method string register_bottom
• 門戶(portal/)
portalcp_article.htm string portalcp_top string portalcp_extend string portalcp_middle string portalcp_bottom view.htm string view_article_top (X2.5) string view_article_subtitle (X2.5) string view_article_summary (X2.5) string view_article_content (X2.5) string view_share_method string view_article_op_extra (X2.5) string view_article_side_top (X2.5) string view_article_side_bottom (X2.5)
• 排行榜(ranklist/)
side_left.htm string ranklist_nav_extra
• 搜索(search/)
album.htm string album_top string album_bottom blog.htm string blog_top string blog_bottom collection.htm (X3) string collection_top string collection_bottom footer.htm string global_footer string global_footerlink forum.htm string forum_top string forum_bottom group.htm string group_top string group_bottom header.htm string global_usernav_extra1 string global_usernav_extra2 portal.htm string portal_top string portal_bottom
• 應用(userapp/)
userapp_app.htm string userapp_app_top string userapp_app_bottom userapp_index.htm string userapp_index_top string userapp_index_bottom userapp_menu_list.htm string userapp_menu_top string userapp_menu_middle string userapp_menu_bottom
• 手機全局(mobile/common/)
footer.htm string global_footer_mobile header.htm string global_header_mobile
• 手機論壇(mobile/forum/)
discuz.htm string index_top_mobile string index_middle_mobile string index_bottom_mobile forumdisplay.htm string forumdisplay_top_mobile array forumdisplay_thread_mobile string forumdisplay_bottom_mobile viewthread.htm string viewthread_top_mobile array viewthread_posttop_mobile array viewthread_postbottom_mobile string viewthread_bottom_mobile
• 手機論壇(wml/forum/)
discuz.htm string index_top_mobile string index_middle_mobile forumdisplay.htm string forumdisplay_top_mobile array forumdisplay_thread_mobile string forumdisplay_bottom_mobile viewthread.htm string viewthread_top_mobile array viewthread_posttop_mobile array viewthread_postbottom_mobile string viewthread_bottom_mobile
特殊主題模塊開發
•?特殊主題模塊用于創建一個特殊主題,特殊主題類型腳本格式
<?phpclass threadplugin_identifier { var $name = 'XX主題'; //主題類型名稱 var $iconfile = 'icon.gif'; //發布主題鏈接中的前綴圖標 var $buttontext = '發布xx主題'; //發帖時按鈕文字 function newthread($fid) { return ...; } function newthread_submit($fid) { } function newthread_submit_end($fid, $tid) { } function editpost($fid, $tid) { return ...; } function editpost_submit($fid, $tid) { } function editpost_submit_end($fid, $tid) { } function newreply_submit_end($fid, $tid) { } function viewthread($tid) { return ...; }}?>
identifier 插件的唯一標識符,在插件設置中設置。
函數名以及含義
函數名 含義
newthread() 發主題時頁面新增的表單項目,通過 return 返回即可輸出到發帖頁面中
newthread_submit() 主題發布后的數據判斷
newthread_submit_end() 主題發布后的數據處理
editpost() 編輯主題時頁面新增的表單項目,通過 return 返回即可輸出到編輯主題頁面中
editpost_submit() 主題編輯后的數據判斷
editpost_submit_end() 主題編輯后的數據處理
newreply_submit_end() 回帖后的數據處理
viewthread() 查看主題時頁面新增的內容,通過 return 返回即可輸出到主題首貼頁面中
第三方拓展類的開發
目錄 [隱藏]
•?
1 廣告類
•?2 道具類
•?3 任務類
•?4 驗證問答類
•?5 驗證碼類(Discuz! X2.5 新增)
廣告類
腳本位置:source/class/adv/adv_name.php
語言包位置:source/language/adv/lang_name.php
【Discuz! X3.0 新增】
腳本位置:source/plugin/插件目錄/adv/adv_name.php
縮略圖:source/plugin/插件目錄/adv/adv_name.gif
<?phpclass adv_name { var $version = '1.0';//腳本版本號 var $name = 'name';//廣告類型名稱 (可填寫語言包項目) var $description = 'desc';//廣告類型說明 (可填寫語言包項目) var $copyright = 'Comsenz Inc.';//版權 (可填寫語言包項目) var $targets = array('portal', 'home', 'member', 'forum', 'group', 'userapp', 'plugin', 'custom');//廣告類型適用的投放范圍 var $imagesizes = array('120x60', '120x240');//圖片廣告推薦大小 function getsetting() {//返回設置項目 $settings = array( 'text' => array( 'title' => 'text_title',//設置項目名稱 (可填寫語言項目) 'type' => 'mradio',//項目類型 'value' => array(),//項目選項 'default' => 0,//項目默認值 ) ); return $settings; } function setsetting(&$advnew, &$parameters) {//保存設置項目 } function evalcode() {//廣告顯示時的運行代碼 return array( //檢測廣告是否投放時的代碼 'check' => ' if(condition) { $checked = false; }', //廣告顯示時的代碼 (隨機調用投放的廣告) 'create' => '$adcode = $codes[$adids[array_rand($adids)]];', ); }}?>道具類
腳本位置:source/class/magic/magic_name.php
語言包位置:source/language/magic/lang_name.php
【Discuz! X3.0 新增】
腳本位置:source/plugin/插件目錄/magic/magic_name.php
圖標:source/plugin/插件目錄/magic/magic_name.small.gif、source/plugin/插件目錄/magic/magic_name.gif
<?phpclass magic_name { var $version = '1.0';//腳本版本號 var $name = 'name';//道具名稱 (可填寫語言包項目) var $description = 'desc';//道具說明 (可填寫語言包項目) var $price = '10';//道具默認價格 var $weight = '10';//道具默認重量 var $copyright = 'Comsenz Inc.';//版權 (可填寫語言包項目) function getsetting() {//返回設置項目 $settings = array( 'text' => array( 'title' => 'text_title',//設置項目名稱 (可填寫語言項目) 'type' => 'mradio',//項目類型 'value' => array(),//項目選項 'default' => 0,//項目默認值 ) ); return $settings; } function setsetting(&$advnew, &$parameters) {//保存設置項目 } function usesubmit($magic, $parameters) {//道具使用 } function show($magic) {//道具顯示 }}?>任務類
腳本位置:source/class/task/task_name.php
語言包位置:source/language/task/lang_name.php
【Discuz! X3.0 新增】
腳本位置:source/plugin/插件目錄/task/task_name.php
圖標:source/plugin/插件目錄/task/task_name.gif
<?phpclass task_name { var $version = '1.0';//腳本版本號 var $name = 'name';//任務名稱 (可填寫語言包項目) var $description = 'desc';//任務說明 (可填寫語言包項目) var $copyright = 'Comsenz Inc.';//版權 (可填寫語言包項目) var $icon = '';//默認圖標 var $period = '';//默認任務間隔周期 var $periodtype = 0;//默認任務間隔周期單位 var $conditions = array(//任務附加條件 'text' => array( 'title' => 'text_title',//設置項目名稱 (可填寫語言項目) 'type' => 'mradio',//項目類型 'value' => array(),//項目選項 'default' => 0,//項目默認值 'sort' => 'complete',//條件類型 (apply:申請任務條件 complete:完成任務條件) ), ); function preprocess($task) {//申請任務成功后的附加處理 } function csc($task = array()) {//判斷任務是否完成 (返回 TRUE:成功 FALSE:失敗 0:任務進行中進度未知或尚未開始 大于0的正數:任務進行中返回任務進度) } function sufprocess($task) {//完成任務后的附加處理 } function view($task, $taskvars) {//任務顯示 } function install() {//任務安裝的附加處理 } function uninstall() {//任務卸載的附加處理 } function upgrade() {//任務升級的附加處理 }}?>驗證問答類
腳本位置:source/class/secqaa/secqaa_name.php
語言包位置:source/language/secqaa/lang_name.php
【Discuz! X3.0 新增】
腳本位置:source/plugin/插件目錄/secqaa/secqaa_name.php
<?phpclass secqaa_name { var $version = '1.0';//腳本版本號 var $name = 'name';//驗證問答名稱 (可填寫語言包項目) var $description = 'desc';//驗證問答說明 (可填寫語言包項目) var $copyright = 'Comsenz Inc.';//版權 (可填寫語言包項目) function make(&$question) {//返回安全問答的答案和問題 ($question 為問題,函數返回值為答案) }}?>驗證碼類(Discuz! X2.5 新增)
腳本位置:source/class/seccode/seccode_name.php
語言包位置:source/language/seccode/lang_name.php
【Discuz! X3.0 新增】
腳本位置:source/plugin/插件目錄/seccode/seccode_name.php
<?phpclass seccode_name { var $version = '1.0';//腳本版本號 var $name = 'name';//驗證碼類型名稱 (可填寫語言包項目) var $copyright = 'Comsenz Inc.';//版權 (可填寫語言包項目) var $setting = array();//后臺設置后的變量 function check($value, $idhash) {//檢查輸入的驗證碼,返回 true 表示通過 } function make() {//輸出驗證碼,echo 輸出內容將顯示在頁面中 }}?>
計劃任務模塊開發
•?本功能為 Discuz! X3.0 新增內容
•?計劃任務模塊用于拓展一個計劃任務項目,本模塊會在插件安裝時自動添加到系統計劃任務中,并在插件卸載時自動從中刪除
腳本位置:source/plugin/插件目錄/cron/cron_name.php
<?php//cronname:mycron 計劃任務名稱,可寫腳本語言包中的項目//week:1 設置星期幾執行本任務,留空為不限制//day:1 設置哪一日執行本任務,留空為不限制//hour:1 設置哪一小時執行本任務,留空為不限制//minute:0,30 設置哪些分鐘執行本任務,至多可以設置 12 個分鐘值,多個值之間用半角逗號 "," 隔開,留空為不限制if(!defined('IN_DISCUZ')) { exit('Access Denied');}//您的計劃任務腳本內容?>
緩存更新模塊開發
•?本功能為 Discuz! X3.0 新增內容
•?緩存更新模塊用于在系統更新緩存時拓展一個緩存更新項目
腳本位置:source/plugin/插件目錄/cache/cache_name.php
<?phpif(!defined('IN_DISCUZ')) { exit('Access Denied');}function build_cache_plugin_name() { //您的緩存更新腳本內容}?>
插件安裝、卸載、升級腳本的設計
目錄 [隱藏]
•?
1 安裝、卸載
•?2 升級
•?3 檢測
•?4 授權協議、插件介紹
•?5 Discuz! 版本兼容性設置
•?6 其他論壇數據導入
•?7 小提示
安裝、卸載
插件作者可以設計 2 個腳本文件用于插件的安裝和卸載,文件名任意。腳本中可用 runquery() 函數執行 SQL 語句,表名可以直接寫“cdb_”。插件作者只需在導出的 XML 文件結尾加上安裝、卸載腳本的文件名即可
<item id="installfile"><![CDATA[install.php]]></item> <item id="uninstallfile"><![CDATA[uninstall.php]]></item> </item> </root>
安裝、卸載程序中可隨意設計頁面的跳轉,只要在插件安裝、卸載結束時候輸出添加以下代碼即可。
$finish = TRUE;升級
插件作者可以設計一個腳本文件用于插件的升級,文件名任意。腳本中可用 runquery() 函數執行 SQL 語句,表名可以直接寫“cdb_”。插件作者只需在導出的 XML 文件結尾加上升級腳本的文件名即可
<item id="upgradefile"><![CDATA[upgrade.php]]></item> </item> </root>
升級程序中可通過 $fromversion 和 $toversion 變量判斷升級的具體版本號,并隨意設計頁面的跳轉,只要在插件升級結束時候輸出添加以下代碼即可。
$finish = TRUE;
插件的當前版本號位于 XML 文件的以下分支中,可自行更改。
<item id="plugin"> ...... <item id="version"><![CDATA[當前版本]]></item> ...... </item>檢測
插件作者可以設計一個腳本文件用于插件在安裝、卸載、升級操作前的檢測,文件名任意。插件作者只需在導出的 XML 文件結尾加上檢測腳本的文件名即可
<item id="checkfile"><![CDATA[check.php]]></item> </item> </root>授權協議、插件介紹
插件在安裝的時候您可以自定義授權信息文本,文本支持 Discuz! 代碼,站長同意后才能安裝插件。如果插件存在后臺管理界面或者變量配置,那么插件介紹文本會顯示在插件后臺頁面中。插件作者只需在導出的 XML 文件結尾加上以下內容即可
<item id="license"><![CDATA[授權協議文本]]></item> <item id="intro"><![CDATA[插件介紹文本]]></item> </item> </root>Discuz! 版本兼容性設置
請仔細檢查您的插件是否可以在相應的 Discuz! 版本中運行。然后在 XML 文件的以下分支中自行更改。
如您的插件兼容多個版本,請用逗號(,)分隔,如“X2,X2.5”(此寫法從 Discuz! X2 R20120329 后開始支持)
<item id="Data"> <item id="plugin"> ...... </item> ...... <item id="version"><![CDATA[兼容性設置]]></item> ...... </item>其他論壇數據導入
插件安裝時可以直接導入一個或多個論壇數據,這些論壇數據包括表情(smilies)、風格(styles)的數據。在導出的 XML 文件結尾加上需要導入數據的類型和數據文件名即可,多個文件名用逗號(",")分隔。
<item id="importfile"> <item id="smilies"><![CDATA[discuz_smilies_test.xml]]></item> <item id="styles"><![CDATA[discuz_styles_test.xml]]></item> </item> </item> </root>小提示
如果導出的 XML 文件名以 SC_GBK、SC_UTF8、TC_BIG5、TC_UTF8 結尾,顯示的時候將直接顯示為“簡體”、“繁體”、“UTF8”等字樣。
插件模板和語言包的設計
插件語言包創建語言包
•?給插件創建語言包首先需要創建一個 data/plugindata/identifier.lang.php 文件,文件內容中包含 4 個數組,如下:
<?php$scriptlang['identifier'] = array( 'english' => 'chinese', ...);$templatelang['identifier'] = array( 'english' => 'chinese', ...);$installlang['identifier'] = array( 'english' => 'chinese', ...);$systemlang['identifier'] = array( 'file' => array( 'english' => 'chinese', ... ), ...);?>
$scriptlang 為程序腳本文件的語言包。
$templatelang 為模版文件的語言包。
$installlang 為安裝、升級、卸載腳本用的語言包。
$systemlang 為系統語言包(Discuz! X3 新增)。
如果插件不涉及某些類型的語言文字,變量可忽略。
•?
然后在插件基本設置中開啟語言包選項后即可。
調用語言包
模版中調用模板文件語言包,通過 {lang identifier:english} 方式調用。
程序腳本中調用腳本文件語言包,通過 lang('plugin/identifier', 'english') 方式調用。
安裝腳本中調用安裝腳本文件語言包,通過 $installlang 變量直接獲取。如 $installlang['english']。
系統語言包用于替換系統語言包中的某些語言條目。
語言包導出
創建好的語言包在插件導出后會自動導出到 XML 文件中,供插件作者轉碼后發放多編碼版本的插件。如上例中導出的 XML 中會包含以下內容:
<item id="language"> <item id="scriptlang"> <item id="english"><![CDATA[chinese]]></item> </item> <item id="templatelang"> <item id="english"><![CDATA[chinese]]></item> </item> <item id="installlang"> <item id="english"><![CDATA[chinese]]></item> </item> <item id="systemlang"> <item id="file"> <item id="english"><![CDATA[chinese]]></item> </item> </item></item>
data/plugindata/identifier.lang.php 文件不必在插件發布的時候導出,此文件僅供插件設計者模式時使用。
插件模板
插件的模板統一放置到 source/plugin/identifier/template 目錄下,程序腳本通過以下語句調用插件模板文件,如下例,調用 source/plugin/identifier/template/test.htm
include template('identifier:test');
模版中調用插件模版通過以下方法:
{template identifier:test}
插件注冊及插件新版本提示
以下內容僅限 Discuz! X2.0
為了保護插件的合法權益,你可以把設計好的插件到官方的應用中心( http://addon.discuz.com )進行注冊,注冊后你將擁有此插件的唯一所有權。
插件 LOGO 設置
設置插件的 LOGO,提升插件的價值。請自行設計一個 40x40 大小的 PNG 圖片,上傳到擴展中心,此 LOGO 會在 Discuz! 的插件管理中心顯示。
插件新版本提示
插件新版本提示可以讓站長在隨時檢測到你插件是否存在新版本。請插件作者把自己發布插件的相關文件生成 MD5 校驗碼,然后到擴展中心進行插件版本校驗文件的登記。
插件校驗碼生成函數
function createValidator($pluginid, $md5files) { define('IN_DISCUZ', true); require_once 'source/class/class_xml.php'; require_once 'source/discuz_version.php'; $plugindir = 'source/plugin/'.$pluginid.'/'; $md5 = ''; foreach($md5files as $file) { $md5 .= md5_file($file); } echo md5(md5($md5).$pluginid); $xml = array( 'Title' => 'Discuz! Plugin Validator', 'Version' => DISCUZ_VERSION, 'Data' => $md5files, ); if($fp = @fopen($plugindir.'validator.xml', 'wb')) { fwrite($fp, array2xml($xml)); fclose($fp); }}
此函數執行后會在插件目錄生成 validator.xml 文件,請同插件其他文件一并打包發布。頁面輸出的 MD5 校驗碼填寫到擴展中心“插件版本校驗文件登記”中。
使用范例
$md5files = array( 'source/plugin/myrepeats/switch.inc.php', 'source/plugin/myrepeats/admincp.inc.php', 'source/plugin/myrepeats/discuz_plugin_myrepeats.xml', 'source/plugin/myrepeats/memcp.inc.php',);createValidator('myrepeats', $md5files);
編寫插件的原則與注意事項
請在您動手編寫插件之前,還需要仔細的閱讀以下原則,遵循這些原則,將有效的避免可能發生的問題:
•?所有與插件的程序,包括其全部的前后臺程序,請全部放入 source/plugin/ 目錄中,同時在插件的安裝說明中指出,插件的文件需要復制到哪些目錄。為了避免與其他插件沖突,請盡量建立 source/plugin/ 下的子目錄,并將插件程序放置于子目錄下,這樣您編寫的插件將獲得更好的兼容性。
•?如果您的插件包含“導航欄”模塊,該模塊將統一用 plugin.php?identifier=xxx&module=yyy 的方式調用,請在相應鏈接、表單中使用此方式。其中 xxx 為插件的惟一標識符,yyy 為模塊名稱。前臺插件外殼程序 plugin.php 已經加載了通用初始化模塊 /source/class/class_core.php,不需再次引用。
•?如果您的插件包含“管理中心”模塊,該模塊將統一用 admin.php?action=plugins&identifier=xxx&pmod=yyy 的方式調用,請在相應鏈接、表單中使用此方式。其中 xxx 和 yyy 的定義與“導航欄”模塊中的相同。系統還允許用 admin.php?action=plugins&edit=$edit&pmod=$mod 的方式來生成鏈接和表單地址,$edit 和 $mod 變量已經被插件后臺管理接口賦值,因此將這兩個變量值帶入 URL 中也是被支持的。由于后臺模塊是被 admin.php 調用,因此已加載了通用初始化模塊 /source/class/class_core.php 并進行了后臺管理人員權限驗證,因此模塊程序中可直接寫功能代碼,不需再進行驗證。
•?請勿繞過插件的前后臺外殼(plugin.php 和 admin.php)而以直接調用某程序的方式編寫插件,因為這樣既導致了用戶使用不便,代碼冗余和不規范,同時又產生了因驗證程序考慮不周到而帶來的安全隱患。您可以在任何地方,包括鏈接、表單等處方便的使用上述 URL 地址對插件模塊進行調用。
•?所有與插件有關的程序,包括全部的前臺程序,因全部使用外殼調用,請務必在第一行加入
if(!defined('IN_DISCUZ')) { exit('Access Denied');}
后臺程序第一行加入
if(!defined('IN_DISCUZ') || !defined('IN_ADMINCP')) { exit('Access Denied');}
•?以免其被 URL 直接請求調用,產生安全問題。
•?一般情況下,您發布插件請使用插件導出的功能,以方便使用者一次性導入插件的配置數據,極特殊的情況下,也可以分步驟告知使用者如何進行插件配置管理和安裝此插件。
•?如果功能獨立,請盡量使用單獨程序的方式編寫插件(即外掛型插件),而盡量少的對論壇本身代碼進行修改,這將為使用者今后的升級帶來很大方便。
•?您可以修改 Discuz! 本身的數據結構,但更推薦在不很影響效率的前提下將插件數據用另外的數據表存儲,因為不能排除您增加的字段或索引和今后版本 Discuz! 核心數據字段重名的可能。在任何情況下,請不要刪除 Discuz! 標準版本數據結構中已有的字段或索引。
•?請在插件說明書中對插件做以詳盡的描述,例如增加了哪些字段、哪些表,修改了或新增了哪些程序,版本兼容性,后續支持的提供方式(例如不提供支持,或以什么樣的方式提供)。如果方便,請盡可能提供插件的卸載方法,例如去除哪些字段、刪除哪些新增的程序、將哪些被插件修改的程序恢復原狀等等,使用者會感激您為此付出的辛勤勞動,甚至愿意支付相應的費用支持您未來的發展。
•?如果插件使用另外的數據表存儲,請在插件管理中準確的設置插件所使用的數據表名稱(不包含前綴),這樣用戶在備份數據的時候,能夠把插件數據一同備份。
•?Discuz! 內置了 8 種自定義積分,存儲于 common_member 表中的 extcredits1 至 extcredits8 字段中,類型為有符號整數
2、語言包編碼轉換工具 convertz 【百度一下】(專門用來處理多種編碼的插件安裝 )
3、數據庫管理工具 navicat 【百度一下】(方便數據庫的查看與操作)
4、網站的基本數據,這些數據包括:系統常量、全局變量、系統調用 ,首先從系統常量說起
4.1、系統常量
DISCUZ_ROOT //網站根目錄
TIMESTAMP //程序執行的時間戳
CHARSET //程序的語言編碼類型
IS_ROBOT //是否是機器訪問
FORMHASH //HASH值
其余的可直接打印出來查看,如:
??<?php
??require_once './source/class/class_core.php';
??$discuz = & discuz_core::instance();
??$discuz->init();
??print_r(get_defined_constants());
???>
復制代碼
4.2、全局變量
直接打印$_G即可得知,如:
??<?php
??require_once './source/class/class_core.php';
??$discuz = & discuz_core::instance();
???$discuz->init();
???print_r($_G);
????>
復制代碼
4.3、數據庫配置參數
直接打印$_G['config']['db']即可,如:
???<?php
???require_once './source/class/class_core.php';
???$discuz = & discuz_core::instance();
???$discuz->init();
???print_r($_G['config']['db']);
????>
復制代碼
4.4、數據庫操作
DB::table() //增加了pre的數據庫表名
DB::delete() //刪除表中數據
DB::insert() //向表中插入數據
DB::update() //更新表中數據
DB::fetch() //配合DB::query來實現數據資源數據的獲取
DB::query() //執行一條數據庫語句
DB::fetch_first() //獲取結果集的第一條記錄
更多操作請查看文檔: http://dev.discuz.org/wiki/index ... E%E5%BA%93%E7%B1%BB
5、熟悉 ./source/function/function_admincp.php 管理后臺文件里的函數,知道具體函數是實現什么功能效果
6、了解和掌握基礎通用的類、函數 http://dev.discuz.org/wiki/#.E5. ... 1.E5.87.BD.E6.95.B0
二、安全性處理
1、文件的安全性
所有與插件有關的程序,包括全部的前后臺程序,因全部使用外殼調用,請務必在第一行加入
if(!defined('IN_DISCUZ')) {
exit('Access Denied');
}
以免其被 URL 直接請求調用,產生安全問題。
2、對數值處理
2.1、 intval(); //處理非負整數 ,如:$uid=intval($uid);
注意,使用intval后,一定要想一想,自己這個變量是不是應該非負的?如果是的話,得加個判斷語句,或者用abs,max等函數處理下
2.2、 trim(); //去除左右空格, 如:$username=trim($username);
2.3、 對于文字內容,記得使用htmlspecialchars(dhtmlspecialchars)
2.4、 寫入數據庫時的注意事項
要進數據庫的變量一定得addslashes(DZ內為daddslashes,如用DZ無須再次過濾,DZ已將所有$_POST和$_GET過濾),當然,如果你進的是數字(比如uid,并且已經intval過),或者是其他一些肯定不會出錯的,那么你可以不做這一步。
2.5、 在寫sql語句時,變量一定得記得用’框起來。如果變量是字符串,不這么做會出錯。如果是數字不這么做不會提示出錯,但是有可能有注入的危險。
2.6、 數組在運用前記得寫$xxx = array(); 原因很簡單,防止用戶提交惡意的值。
3、語句查詢優化
在寫SQL語句是盡量符合SQL規則,語句查詢要相應的優化,有先有后;數據表要相應的創建索引,加快查詢速度,這里不多說。
三、實例講解之插件的前兆
1、最先清楚需要開發什么功能的插件,插件機制是否能夠開發,最后能否達到預期效果,否則一切都免談了
2、需要使用什么菜單、什么參數,配置哪些選項、數據結構如何設計、前后臺實現哪些功能等等
3、需要哪些函數,discuz內部是否有這功能的函數,盡量用內部的函數來達到預期效果
4、最好不要改動discuz原有的布局,寧愿Coty一段代碼出來也不要在原有的函數上添加功能,防止以后的升級問題
5、盡最大能力去開發智能的插件,多用變量代替常量,增強程序的移植性,可維護性