2017-05-30 144 views
11

我在WordPress中有一個依賴外部數據庫的自定義頁面模板,並且使用wpdb類來實現此目的。使用WordPress中的wpdb類訪問外部數據庫

這是我的代碼:

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> 
    <header class="entry-header"> 
     <?php the_title('<h1 class="entry-title">', '</h1>'); ?> 
    </header><!-- .entry-header --> 

<?php 

class StudentsDatabase 
{ 
    private $db; 
    public function __construct() { 
     try { 
      $this->db = new wpdb(DB_USER, DB_PASSWORD, 'students_db', DB_HOST); 
      $this->db->show_errors(); 
     } catch (Exception $e) { 
      echo $e->getMessage(); 
     } 
    } 
    public function getStudentById($student_id) 
    { 
     return $this->db->get_results("SELECT * FROM `students` WHERE id=$student_id"); 
    } 
    public function getSchoolByAreaCode($area_code) 
    { 
     return $this->db->get_results("SELECT * FROM `schools` WHERE area_code=$area_code;--"); 
    } 

} 
$Students_DB = new StudentsDatabase(); 
$student_one = $Students_DB->getStudentById(1); 
$school_one = $Students_DB->getSchoolByAreaCode(1); 

?> 
<div class="entry-content"> 
    <?php 

    //do something with $student_one and $school_one ... 

    the_content(); 

    ?> 
</div><!-- .entry-content --> 

嗯,我想知道,這是做正確的方式。實際上,安全方面或任何「其他」都是明智的。

從頁面模板本身進行外部數據庫調用感覺有點簡單。我是否應該在某些外部文件上註冊這些功能,然後在模板中使用它們?

+0

我可以輸入這個值爲area_code或student_id嗎? 「'null或1 = 1; drop table users; --'」確保輸入信息在[bobby tables](https://xkcd.com/327/)到達您的頁面之前已'消毒'。 – coderatchet

+0

@thenaglecode他們都很好的消毒,我只是張貼了一部分代碼(:但是感謝您的關注,雖然! –

回答

10

我認爲最「乾淨」的方法是實現一個插件,它將成爲您主題的API。當然,這取決於它是否僅僅是爲了你自己的目的的主題,因爲Wordpress(迄今爲止)缺乏依賴管理器。

總結 - 在主題中使用這個API。

+0

沒有真正得到你的總結部分。總之,這種方法將用於數百個不同的網站 - 他們每個人都有不同的主題和特定的自定義,所以一個插件在這種情況下不是一個解決方案,它需要大量的時間和工作來覆蓋所有這些情況。 –

+0

這不是最多的優雅的答案,但它是100正確的。如果問題是如何訪問外部數據庫,答案是通過API。OP的代碼示例是亂碼,所以這是一個很好的答案! –

+0

@GonrasKarols - _有一個不同的主題和特定的自定義 - 這就是爲什麼它應該成爲一個插件;插件以抽象的方式共享一個共同的邏輯 - 當你修正一個錯誤時,你只需升級一個插件,而不是替換每個代碼實例 – eRIZ

6

class聲明等放入主題的functions.php文件中。或者,甚至更好,require_once他們在那裏,並將它們放在主題的assetsincludes文件夾中。

-/theme/ 
    -/includes/classes/class-studentsDatabase.php 
    -functions.php 

在functions.php的

define('TEMPLATE_PATH', get_template_directory()); 
require_once(TEMPLATE_PATH . '/includes/classes/class-studentsDatabase.php'); 

您可以實例化class(ES)爲主題作爲一個整體,或根據需要模板頁面(S)爲你現在在做的。


就安全性而言,我會避免將數據庫連接放在要發送到野外的主題中。

我不確定我是否按照你所做的那樣做,但是如前所述,我會在主題環境之外處理這一點。

再次,不知道你的用例,主題可以利用外部api,並且api可能是一個wordpress wp-json api管理中心站點的數據庫連接。

這將允許主題GET/POST到處理驗證和任何CRUD的端點,並減輕很多潛在的安全問題。外部網站上的主題就是解析返回的json,除此之外不會有任何數據庫訪問。

+3

這是初學者WP開發者常見的誤解。如果你添加功能,它應該放在一個插件中,而不是一個主題。如果你正在修改網站的「外觀」,它應該放在主題的functions.php中。這種類型的事絕對不應該放在一個主題。 –

+0

@JimMaguire如果您構建與特定主題相關的功能,爲什麼不把它放在主題functions.php中? wordpress中的主題不僅僅是一個定義網站外觀的「主題」。 (至少這是它在過去2 - 3年內的變化) – Avishay28

+0

很難想出一個例子,其中你的建議是有道理的。是的..當然,主題銷售商將功能放在主題中,他們想鎖定你並向你推銷某些東西。我會問你爲什麼把它放在一個主題?它限制了你的選擇並且一無所獲。 –

0

還有更激進的方式與Wordpress中的多個數據庫一起工作。作爲WPDB從以下Codex page

的WPDB $對象可以跟任意數量的表,但只有一次在一個數據庫;默認情況下是WordPress數據庫。在極少數情況下,您需要連接到另一個數據庫,您需要使用您自己的數據庫連接信息從wpdb類實例化自己的對象。對於具有多個數據庫的極其複雜的設置,請考慮使用hyperdb。

Hyperdb是一個插件,它可以幫助多個數據庫並替代您對代碼組織的過度關注。