Это, вероятно, глупый вопрос, но я не могу понять, что гуглить. Я изучаю ООП и получаю общую концепцию, но пытаюсь реализовать ее, и у меня возникают некоторые вопросы.
Я делаю веб-скребок, используя простой HTML-дом. Я хочу создать класс, который подключается к странице и содержит несколько различных функций, которые я могу вызывать на этой странице в зависимости от того, что я хочу сделать. Затем я могу вызвать методы этого класса из другого файла.
Это класс, который я написал:
<?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? Или я должен сохранять свои методы получения и установки минимальными и иметь вместо них другую функцию?
Любой совет о любой части моего кода будет приветствоваться.
Магические методы PHP помогут вам немного больше.
Вот ссылка на руководство по PHP для __set()
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
Я хотел бы предложить вам всегда использовать SOA (сервис-ориентированную архитектуру), когда вы хотите разрабатывать с ООП. С SOA ваш сервис приходит из класса CountyScraper
должен быть уникальным. Вот почему мы используем одиночка. Служба не должна удерживать состояние от действия. Вот почему вы не должны устанавливать 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');