2009-12-25 184 views
1

你好,我只是學習更多關於在PHP中使用類。我知道下面的代碼是廢話,但我需要幫助。這是做這個PHP類的正確方法嗎?

如果我正朝着正確的方向前進,有人能讓我知道嗎?

我的目標是將這個類包含到用戶配置文件頁面中,當創建一個新的配置文件對象時,我想讓它從mysql中檢索所有配置文件數據,然後我希望能夠顯示任何只要使用這樣的事情

$profile = New Profile; 
echo $profile->user_name; 

這裏是我到目前爲止的代碼在頁面上項目,請告訴我,什麼是錯的,到目前爲止,或者如果我在正確的方向我要去?

而不是使用echo $ profile-> user_name;對於超過50個配置文件的mysql fileds,有時我需要對數據做些事情,例如,連接日期和出生日期有其他代碼必須運行來轉換它們,如果記錄是空的,那麼我想顯示一個替代值,所以有了這個知識,我應該使用方法嗎?像50多種不同的方法?

<?PHP 
//Profile.class.php file 

class Profile 
{ 
    //set some profile variables 
    public $userid; 
    public $pic_url; 
    public $location_lat; 
    public $location_long; 
    public $user_name; 
    public $f_name; 
    public $l_name; 
    public $country; 
    public $usa_state; 
    public $other_state; 
    public $zip_code; 
    public $city; 
    public $gender; 
    public $birth_date; 
    public $date_create; 
    public $date_last_visit; 
    public $user_role; 
    public $photo_url; 
    public $user_status; 
    public $friend_count; 
    public $comment_count; 
    public $forum_post_count; 
    public $referral_count; 
    public $referral_count_total; 
    public $setting_public_profile; 
    public $setting_online; 
    public $profile_purpose; 
    public $profile_height; 
    public $profile_body_type; 
    public $profile_ethnicity; 
    public $profile_occupation; 
    public $profile_marital_status; 
    public $profile_sex_orientation; 
    public $profile_home_town; 
    public $profile_religion; 
    public $profile_smoker; 
    public $profile_drinker; 
    public $profile_kids; 
    public $profile_education; 
    public $profile_income; 
    public $profile_headline; 
    public $profile_about_me; 
    public $profile_like_to_meet; 
    public $profile_interest; 
    public $profile_music; 
    public $profile_television; 
    public $profile_books; 
    public $profile_heroes; 
    public $profile_here_for; 
    public $profile_counter; 

    function __construct($session) 
    { 
    // coming soon 
    } 

    //get profile data 
    function getProfile_info(){ 
     $sql = "SELECT user_name,f_name,l_name,country,usa_state,other_state,zip_code,city,gender,birth_date,date_created,date_last_visit, 
     user_role,photo_url,user_status,friend_count,comment_count,forum_post_count,referral_count,referral_count_total, 
     setting_public_profile,setting_online,profile_purpose,profile_height,profile_body_type,profile_ethnicity, 
     profile_occupation,profile_marital_status,profile_sex_orientation,profile_home_town,profile_religion, 
     profile_smoker,profile_drinker,profile_kids,profile_education,profile_income,profile_headline,profile_about_me, 
     profile_like_to_meet,profile_interest,profile_music,profile_television,profile_books,profile_heroes,profile_here_for,profile_counter 
     FROM users WHERE user_id=$profileid AND user_role > 0"; 
     $result_profile = Database::executequery($sql); 

     if ($profile = mysql_fetch_assoc($result_profile)) { 
      //result is found so set some variables 
      $this->user_name = $profile['user_name']; 
      $this->f_name = $profile['f_name']; 
      $this->l_name = $profile['l_name']; 
      $this->country = $profile['country']; 
      $this->usa_state = $profile['usa_state']; 
      $this->other_state = $profile['other_state']; 
      $this->zip_code = $profile['zip_code']; 
      $this->city = $profile['city']; 
      $this->gender = $profile['gender']; 
      $this->birth_date = $profile['birth_date']; 
      $this->date_created = $profile['date_created']; 
      $this->date_last_visit = $profile['date_last_visit']; 
      $this->user_role = $profile['user_role']; 
      $this->photo_url = $profile['photo_url']; 
      $this->user_status = $profile['user_status']; 
      $this->friend_count = $profile['friend_count']; 
      $this->comment_count = $profile['comment_count']; 
      $this->forum_post_count = $profile['forum_post_count']; 
      $this->referral_count = $profile['referral_count']; 
      $this->referral_count_total = $profile['referral_count_total']; 
      $this->setting_public_profile = $profile['setting_public_profile']; 
      $this->setting_online = $profile['setting_online']; 
      $this->profile_purpose = $profile['profile_purpose']; 
      $this->profile_height = $profile['profile_height']; 
      $this->profile_body_type = $profile['profile_body_type']; 
      $this->profile_ethnicity = $profile['profile_ethnicity']; 
      $this->profile_occupation = $profile['profile_occupation']; 
      $this->profile_marital_status = $profile['profile_marital_status']; 
      $this->profile_sex_orientation = $profile['profile_sex_orientation']; 
      $this->profile_home_town = $profile['profile_home_town']; 
      $this->profile_religion = $profile['profile_religion']; 
      $this->profile_smoker = $profile['profile_smoker']; 
      $this->profile_drinker = $profile['profile_drinker']; 
      $this->profile_kids = $profile['profile_kids']; 
      $this->profile_education = $profile['profile_education']; 
      $this->profile_income = $profile['profile_income']; 
      $this->profile_headline = $profile['profile_headline']; 
      $this->profile_about_me = $profile['profile_about_me']; 
      $this->profile_like_to_meet = $profile['profile_like_to_meet']; 
      $this->profile_interest = $profile['profile_interest']; 
      $this->profile_music = $profile['profile_music']; 
      $this->profile_television = $profile['profile_television']; 
      $this->profile_books = $profile['profile_books']; 
      $this->profile_heroes = $profile['profile_heroes']; 
      $this->profile_here_for = $profile['profile_here_for']; 
      $this->profile_counter = $profile['profile_counter']; 
     } 
    //this part is not done either........... 
    return $this->pic_url; 
    } 
} 
+0

Veeti的答案的後半部分特別有用。任何嚴肅的Web開發都將涉及到框架的使用。在Web開發中重新發明輪子是毫無意義的。 你可能想看看CakePHP或類似的框架。 – 2009-12-25 18:48:29

回答

4

您可能想看看PHP的magic methods,它允許您創建少量方法(通常是「get」和「set」方法),然後您可以使用它們來返回/設置大量私有/保護變量很容易。然後,您可以有如下面的代碼(抽象的,但希望你的想法):

class Profile 
{ 
    private $_profile; 

    // $_profile is set somewhere else, as per your original code 

    public function __get($name) 
    { 
    if (array_key_exists($name, $this->_profile)) { 
     return $this->_profile[$name]; 
    } 
    } 

    public function __set($name, $value) 
    { 
    // you would normally do some sanity checking here too 
    // to make sure you're not just setting random variables 

    $this->_profile[$name] = $value; 
    } 
} 

正如其他人建議爲好,也許尋找到類似的ORM或類似的(原則,ActiveRecord的等)可能是值得做的,在上述所有爲你做了:-)

編輯:(!爲了完整)我應該提到你實現以上後,你會如何訪問屬性

$profile = new Profile; 

// setting 
$profile->user_name = "JoeBloggs"; 

// retrieving 
echo $profile->user_name; 

,這些將使用上面定義的魔術方法。

+0

魔法+1,並使用ORM(我個人認爲有點像教條),而不是重新發明輪子 - 請注意魔術方法也將不便於在IDE中自動完成(除非您也使用正確的docblocks ;;從我記得,學說產生的那些,btw) – 2009-12-25 18:26:48

+0

有大約50個不同的項目爲每個配置文件頁面顯示,很多這些項目需要修改之前顯示,例如一些日期轉換如果結果爲空,我想展示一個替代值,我相信我可以將所有這些功能添加到您的示例中,但如果我沒有使用get/set,我應該使用50種不同的方法構建一個類?也許構造方法可以從數據庫中檢索數據,然後其他方法將顯示結果 – JasonDavis 2009-12-25 18:48:26

+0

@jason您可以按照我的示例(數組等等)將它構建到單個對象中(我假設您將從數據庫中獲取單個對象行),或者你可以有50個單獨的類成員變量。您可以根據所要求的$ name將您的默認值構建到上面的方法中,或者可以爲每個項目創建get *()方法。 – richsage 2009-12-25 19:28:17

1

不要使用大量的公共變量。最壞的情況下,使其成爲一個變量,如$profile。那麼所有的領域是$profile['body_type']或其他什麼。

+3

使用每個字段的屬性有一個優點:在任何體面的IDE中自動完成(您的解決方案沒有這種優勢 - 至少,除非您定義了正確的doc-blocks) – 2009-12-25 18:20:44

+0

您認爲如何切換到使用方法對於每個項目,所以我可以在每個輸出上運行其他代碼,例如將數字變量上的數字和任何從數據庫返回的變量轉換爲空白,我可以使用cshow替代文本方法? – JasonDavis 2009-12-25 18:24:23

3

你應該研究製作某種類來抽象這一切,以便你的「配置文件」可以擴展它,並且你所寫的所有功能已經到位。

您可能會對現成的解決方案感興趣 - 這些被稱爲對象關係映射器

你應該檢查出PHP ActiveRecord,這應該很容易讓你做這樣的事情,而無需自己編寫ORM代碼。

其他類似的庫包括DoctrineOutlet

0

通常情況下,將創建一個類,以便將對象(您可以發送的消息)的東西抽象爲可以將做到。您創建它的方式更像是一本字典:PHP語法到數據庫字段的一對一映射。沒有太多的附加價值:你插入一個額外的間接層而沒有明確的好處。

相反,該類必須包含所謂的「狀態」,其中包含例如「某個表的id字段,以及某些方法(某些...)到例如「addressString()」,「marriedTo()」,....

如果您擔心性能問題,您可以緩存表中的字段,這是一個完全不同的問題,應該由另一個類實現可以彙總(一個Cache班或任何)。

我在這個設計中看到的主要OO違規行爲是違反了「告訴,不要問」的原則。

+0

您怎麼看待我製作50個不同的方法來處理我需要顯示的項目,例如,如果數據庫中的項目是日期,那麼顯示該日期的方法將運行其他代碼來格式化它顯示的方式然後將其打印到屏幕上,這些方法中的每一個都會檢查值是否爲空,如果是,則類方法會使其顯示替代文本。那是不合適的? – JasonDavis 2009-12-25 18:52:02

+0

我寧願添加一種方法來渲染'showsHtml'代碼,以試圖不公開對象的內容,而是詢問它如何顯示爲例如。一個html表單。這個想法在Holub的一篇文章中被稱爲Visual Proxy模式。這篇文章對一些基本的面向對象概念也有非常簡潔的解釋(參見http://www.javaworld.com/javaworld/jw-09-1999/jw-09-toolbox.html) – xtofl 2009-12-25 21:23:49

1

這看起來像是一個數據類給我,馬丁福勒在他的書Refactoring中稱code smell

數據類就像孩子。作爲一個起點,他們沒有問題,但作爲一個成年人的對象參與,他們需要承擔一些責任。

他指出,如這裏的情況,

在早期階段,這些類可能擁有公共領域。如果是這樣,你應該立即Encapsulate Field之前任何人注意。

如果你把你的許多領域進入一個或幾個幾個關聯數組,然後福勒的建議是

檢查,看它們是否正確封裝和應用Encapsulate Collection如果他們不。在任何不應更改的字段上使用Remove Setting Method

後來,當你有你的Profile類被賦予了行爲和其他類(客戶)使用這些行爲,它可能是有意義的移動其中的一些行爲(以及任何相關數據)的客戶類使用Move Method

如果你不能移動的整體方法,使用Extract Method創建一個可以移動的方法。過了一段時間,您可以開始在吸氣劑和吸氣劑上使用Hide Method

+0

當然,這個建議是公平的通用的。我喜歡關於你的課程的一件事是你傳遞'$ session'而不是依賴一些全局數據。這稱爲依賴注入,它可以在單元測試中給你的類虛擬數據。 – 2009-12-25 19:19:46

相關問題