减少来自类的getter和setter调用量

时间:2014-12-21 21:58:16

标签: php oop getter-setter

这可能是一个愚蠢的问题,但我无法弄清楚谷歌的内容。我正在学习OOP并获得一般概念,但试图实施它并且我得到了一些问题。

我正在使用简单的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();

这很好用,我可以继续这个,但是我觉得我在课堂外打电话给吸气员和制定者很多。我想我应该打一个电话,getCounties并在课堂上处理所有事情。

我假设这是正确的吗?我的getCounties()方法应该调用我的setHtml和setCounties方法吗?或者我应该尽可能地保持我的吸气剂和制定者的最小化并改为使用另一种功能?

欢迎任何关于我的代码任何部分的建议。

2 个答案:

答案 0 :(得分:2)

PHP魔术方法也会对你有所帮助。 这是__set()的php手册的链接 http://php.net/manual/en/language.oop5.overloading.php#object.set

这里也是一个很好的语言,可以帮助您获得有关魔术方法的更多信息 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

答案 1 :(得分: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');