2014-12-21 36 views
0

的getter和setter調用的數量這可能是一個愚蠢的問題,但我無法弄清楚google是什麼。我正在學習面向對象,並得到一般概念,但試圖實現它,我收到一些問題。減少來自類

我正在使用簡單的html dom製作網絡抓取工具。我想創建一個連接到一個頁面的類,並且包含我可以在該頁面上調用的幾個不同的函數,具體取決於我想要執行的操作。然後我可以從另一個文件調用這個類的方法。

這是我寫的類:

<?php 

include_once '/simple_html_dom.php'; 

class CountyScraping 
{ 
protected $demoMode = 0; //set 1 for demo 
protected $cinemas = NULL; 
protected $url = NULL; 
protected $html = NULL; 
protected $counties = array(); 

function __construct($url) 
{ 
    $this->setUrl($url); 
} 

public function setUrl($url) 
{ 
    $this->url = $url; 
} 

public function getUrl() 
{ 
    return $this->url; 
} 

public function setHtml() 
{ 
    $this->html = file_get_html($this->url); 
} 

public function getHtml() 
{ 
    return $this->html; 
} 

public function setCounties() 
{ 
    foreach($this->html->find('#UserLocation option') as $element) 
    { 
     if (($element->value != NULL) && ($element->plaintext)) 
     { 
      $county = array(); 
      $county['id'] = $element->value; 
      $county['county_name'] = $element->plaintext; 
      $this->counties[] = $county; 
     } 
    } 
} 

public function getCounties() 
{ 
    return $this->counties; 
} 

?> 

正如你可以從類見上面,我希望從我的網頁獲得縣的列表,它的所有工作作爲應該的。我想要調用的主要方法是獲得一系列縣。使用上面的代碼來獲得各縣的名單我必須做這樣的事情目前:

$scrape = new CountyScraping("http://example.com"); 

$scrape->setHtml(); 
$scrape->setCounties(); 
$counties = $scrape->getCounties(); 

這工作得很好,我可以繼續使用這個,但是我覺得我做了很多電話給getter和來自課堂外的製片人。我想我應該打一個電話,getCounties,並且在課堂上處理所有事情。

我是否正確地承擔了這個?我的getCounties()方法應該調用我的setHtml和setCounties方法嗎?或者我應該保持我的getter和setter儘可能最小並且有另一個函數呢?

任何有關我的代碼任何部分的建議都會受到歡迎。

+1

在首位:從分析它的工作拆分取頁的工作。他們是獨立的。第二:你不需要在內部使用setter。第三:從API的角度來看,'setHtml'和'setCountries'方法看起來很奇怪。 – zerkms

+0

你應該在'getCounties()'方法中使用getter和setter。通常最好將課堂以外的吸氣和吸氣設備的使用降到最低。相反,使用它的方法來操縱對象。 – Mark

+0

在Yii框架中,setter和getter函數是通過繼承提供的。看看Yii,也許會適應所使用的策略。在這裏找到更多的信息:http://www.yiiframework.com/doc-2.0/guide-concept-properties.html – WeSee

回答

2

PHP神奇的方法也會幫助你多一點。 下面是PHP手冊的鏈接__set() http://php.net/manual/en/language.oop5.overloading.php#object.set

這裏也是一個很好的articale,這將有助於你更多的信息,魔術方法 http://culttt.com/2014/04/16/php-magic-methods/

這裏是魔術方法的基本示例

<?php 
class PropertyTest 
{ 
    /** Location for overloaded data. */ 
    private $data = array(); 

    /** Overloading not used on declared properties. */ 
    public $declared = 1; 

    /** Overloading only used on this when accessed outside the class. */ 
    private $hidden = 2; 

    public function __set($name, $value) 
    { 
     echo "Setting '$name' to '$value'\n"; 
     $this->data[$name] = $value; 
    } 

    public function __get($name) 
    { 
     echo "Getting '$name'\n"; 
     if (array_key_exists($name, $this->data)) { 
      return $this->data[$name]; 
     } 

     $trace = debug_backtrace(); 
     trigger_error(
      'Undefined property via __get(): ' . $name . 
      ' in ' . $trace[0]['file'] . 
      ' on line ' . $trace[0]['line'], 
      E_USER_NOTICE); 
     return null; 
    } 

    /** As of PHP 5.1.0 */ 
    public function __isset($name) 
    { 
     echo "Is '$name' set?\n"; 
     return isset($this->data[$name]); 
    } 

    /** As of PHP 5.1.0 */ 
    public function __unset($name) 
    { 
     echo "Unsetting '$name'\n"; 
     unset($this->data[$name]); 
    } 

    /** Not a magic method, just here for example. */ 
    public function getHidden() 
    { 
     return $this->hidden; 
    } 
} 


echo "<pre>\n"; 

$obj = new PropertyTest; 

$obj->a = 1; 
echo $obj->a . "\n\n"; 

var_dump(isset($obj->a)); 
unset($obj->a); 
var_dump(isset($obj->a)); 
echo "\n"; 

echo $obj->declared . "\n\n"; 

echo "Let's experiment with the private property named 'hidden':\n"; 
echo "Privates are visible inside the class, so __get() not used...\n"; 
echo $obj->getHidden() . "\n"; 
echo "Privates not visible outside of class, so __get() is used...\n"; 
echo $obj->hidden . "\n"; 
?> 

輸出是在這裏:

Setting 'a' to '1' 
Getting 'a' 
1 

Is 'a' set? 
bool(true) 
Unsetting 'a' 
Is 'a' set? 
bool(false) 

1 

Let's experiment with the private property named 'hidden': 
Privates are visible inside the class, so __get() not used... 
2 
Privates not visible outside of class, so __get() is used... 
Getting 'hidden' 


Notice: Undefined property via __get(): hidden in <file> on line 70 in <file> on line 29 

此示例源自http://php.net/manual/en/language.oop5.overloading.php#object.set

+0

因爲我喜歡屬性來閱讀'東西'我使用'魔術''__get'與檢查它在確保只能讀取有效的「屬性類型的東西」。所以,來自我的+1。 'set'不是很清楚,因爲可能需要參數並且可能需要執行其他邏輯。 –

+0

我不明白爲什麼在這種情況下使用魔術方法。神奇的方法有時可能是有用的,但我會建議謹慎使用它們。請記住,您應該在類之間使用低耦合(接口),以便擁有可伸縮,可維護和可測試的應用程序。魔法呼叫阻止正確執行此操作。 – Gnucki

0

我建議您在希望使用OOP進行開發時始終使用SOA(面向服務的體系結構)。使用SOA,來自類CountyScraper的服務應該是唯一的。這就是我們使用singleton的原因。服務不應該保持一種狀態。這就是爲什麼你不應該將url或html設置爲屬性。

<?php 

include_once '/simple_html_dom.php'; 

class CountyScraper 
{ 
    /** 
    * Returns the *Singleton* instance of this class. 
    * 
    * @staticvar Singleton $instance The *Singleton* instances of this class. 
    * 
    * @return Singleton The *Singleton* instance. 
    */ 
    public static function getInstance() 
    { 
     static $instance = null; 
     if (null === $instance) { 
      $instance = new static(); 
     } 

     return $instance; 
    } 

    /** 
    * Protected constructor to prevent creating a new instance of the 
    * *Singleton* via the `new` operator from outside of this class. 
    */ 
    protected function __construct() 
    { 
    } 

    /** 
    * Private clone method to prevent cloning of the instance of the 
    * *Singleton* instance. 
    * 
    * @return void 
    */ 
    private function __clone() 
    { 
    } 

    /** 
    * Private unserialize method to prevent unserializing of the *Singleton* 
    * instance. 
    * 
    * @return void 
    */ 
    private function __wakeup() 
    { 
    } 

    public function findCounties($url) 
    { 
     $counties = array(); 
     $html = file_get_html($url); 

     foreach ($html->find('#UserLocation option') as $element) 
     { 
      if (($element->value != NULL) && ($element->plaintext)) 
      { 
       $county = array(); 
       $county['id'] = $element->value; 
       $county['county_name'] = $element->plaintext; 
       $counties[] = $county; 
      } 
     } 
    } 
} 

然後,您可以使用它像:

$countyScraper = CountyScraper::getInstance(); 

$countyScraper->findCounties('http://example.com');