avatar_epmak

Класс-парсер для MMO TOP и QTOP

Автор epmak, 2014 Янв. 19, 20:35

« назад - далее »

0 Пользователи и 2 гостей просматривают эту тему.

Ключевые слова [SEO] mmotopqtop

epmak

Сел переписывать модуль голосования, написал почти на коленке, но многим этот класс будет полезен, чтобы не изобретать велосипедов. Кушает и https, но нужен включенный curl


/**
* Class TopParse
* класс по работе с топами голосований MMOTOP и Q-TOP
* для работы требуется версия php не ниже 5.х
* подключенная библиотека CURL (в случае, если используется https)
*/

class TopParse {
class TopParse {
//http(s) адрес до списка проголосовавших
private $adr;
//разделитель для отделения столбцов
private $limiter;
//сгенерированный массив
private $out;
//внутренний указатель безопасное соединение или нет
private $isHttps = false;
/*
*  Массив опций
*  [statisic] принимает значения
*        false - выбираем всех подряд и все подряд записи
*        true - записи носят накопительный характер, то есть, все голоса сложаться, ип, дата, номер будут последними
*  [onlyone] кого выбираем
*        false - выбираем всех
*        <ник> - выбираем конкретного персонажа/аккаунт
*/
private $options = array("statisic"=>"false","onlyone"=>"false");
private $cnt =0;

public function  __construct($adress,$delimiter,$options="")
{
self::CheckHttps($adress);
$this->adr = $adress;
$this->limiter = $delimiter;
if($options!="")
$this->options = $options;
}

/**
* функция - оболочка для парса данных
* @param string      $adress
* @param string      $delimiter
* @param array|string $options
* @return array
*/
public function parce($adress="",$delimiter="",$options="")
{
//region переменные
if (empty($adress))
$ad = $this->adr;
else
{
$ad = $adress;
$this->adr = $adress;
}

if(empty($delimiter))
$del = $this->limiter;
else
{
$del = $delimiter;
$this->limiter = $delimiter;
}

if($options!="")
$this->options = $options;
//endregion

self::getData();
return $this->out;
}

/**
* основная функция по разбору полученных данных
*/
private function getData()
{
if ($this->isHttps == false)
{
$tempA = file($this->adr);
}
else
{
$tempA = self::getSslPage($this->adr);
}

if (!empty($tempA))
{
$this->out = array();
$iter1 = new ArrayIterator($tempA); //на случай, если массив будет большой
$tempB = array();
$b=-1;

foreach ($iter1 as $id=>$v)
{
if (empty($v))
continue;
$ar = explode($this->limiter,$v);
if($this->cnt==0)
{
$this->cnt = count($ar);
if ($this->cnt>5)
{
$nick = 4;
$voice = 5;
}
else
{
$nick = 3;
$voice = 4;
}
}
if (trim($ar[$nick])=="")
continue;

if ($this->options["statisic"]=="false")
{
if ($this->options["onlyone"]=="false")
$this->out[$id] = $ar;
else
{
if(trim($ar[$nick]) == $this->options["onlyone"])
{
$this->out[$id] = $ar;
}
}
}
else
{
if ($this->options["onlyone"]=="false")
{

if(!isset($tempB[trim($ar[$nick])]))
{
$tempB[trim($ar[$nick])] = $id; //запоминаем на данный ник данные
$b = $id;
}
else
{
$b = $tempB[$ar[$nick]];
// echo $v[$nick]."<br>";
}

//в случае ммо ип есть, на q топе нету
$this->out[$b][0] = $ar[0];
$this->out[$b][1] = $ar[1];
$this->out[$b][2] = $ar[2];

if (!isset($this->out[$b][$nick]))
$this->out[$b][$nick] = $ar[$nick];

if (isset( $this->out[$b][$voice]))
$this->out[$b][$voice] += $ar[$voice];
else
$this->out[$b][$voice] = $ar[$voice];
}
else
{

if(trim($ar[$nick]) == $this->options["onlyone"])
{
if($b<0)
{
$b = $id;
}
//в случае ммо ип есть, на q топе нету
$this->out[$b][0] = $ar[0];
$this->out[$b][1] = $ar[1];
$this->out[$b][2] = $ar[2];

if (!isset($this->out[$b][$nick]))
$this->out[$b][$nick] = $ar[$nick];

if (isset( $this->out[$b][$voice]))
$this->out[$b][$voice] += $ar[$voice];
else
$this->out[$b][$voice] = $ar[$voice];
}
}

}
}
}
}

/**
* curl приходит на выручку  случае https
* @param string $url
* @return array
*/
protected function getSslPage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);
$result = explode("n",$result);
return $result;
}

/**
* функция проверки адреса на ащищенное соединение
* @param string $url  адрес
*/
private function CheckHttps($url)
{
if (substr(strtolower($url),0,5) == "https")
$this->isHttps = true;
else
$this->isHttps = false;
}
}

пример использования:
$n = new TopParse("ссылка на топ","разделитель",array("statisic"=>"true или false","onlyone"=>"false или ник"));

print "<pre>";
print_r($n->parce()); //выведет на экран полученный массив
print "</pre>";


касаемо последнего параметра, пишу отдельно, так как не все читают пояснения к классу
Массив опций
[statisic] принимает значения
false - выбираем всех подряд и все подряд записи
true - записи носят накопительный характер, то есть, все голоса сложаться, ип, дата, номер будут последними
[onlyone] кого выбираем
false - выбираем всех
<ник> - выбираем конкретного персонажа/аккаунт

разделители
qtop: "||"
mmotop: "    "(возможно будет искажен форумом, чтобы точно установить, пройдите по ссылке на тхт в браузере, включите просмотр кода и скопируйте пустоту между 1 и 2 столбцами)

Profesor08

#1
Критика: Ну смысл последних параметров неочень ясен. Это задача для потомков.

Вариант написанный на коленке - просто и сердито:
$file = file("https://q-top.ru/profiles/117/20.01.2014.txt");
$separator = "||";
$data = array();
foreach ($file as $key => $value)
{
$data[] = explode($separator, $value);
}

print "<pre>";
print_r($data); //выведет на экран полученный массив
print "</pre>";

epmak

#2
А вся прелесть в том, что его можно видоизменить так , что он считать сам будет и записывать сам будет. Плюс класс сам проверяет, какое соединение: безопасное или нет, соответственно, использует разные методы (в принципе, можно и 1 но много чего придется включить, если еще и есть нужная библиотека у хостинга), так же я не зря ввел третий параметр-опции. Можно дернуть только статистикой накопительной и сравнить с тем, что ест. делается, буквально 1 запросом в базу, вместо той ереси, что была написана у меня раньше =
Класс я не навязываю, тут кому как удобнее, тот так и пишет, выложил его, так как использую некоторые функции из просторов интернета, считайте, что просто поступаю по совести.

+ вам предоставлен скелет, по сути. сравни по краткости:
Вызов класса и то, что написал сам. Нужно проверить сразу оба топа: тебе придется писать сочинение с чеком соединения и выборкой нужных полей, в моем случае - в метод pars вписать параметры нового топа. Эм кстати, спасибо, что обратил внимание, я ошибку логическую нашел.

*исправил первый класс (избавился от логической ошибки)

Profesor08

Простым щелчком пальцев, я получаю массив данных, с этим массивом можно делать что угодно дальше, выбирать какие угодно данные, сортировать, объединять и тд. Прочие заморочки в случае mmotop и q-top ненужны. Это можно поместить в функцию или класс и простым вызовом парсить данные с файлов.

epmak

ты сказал в сущности то же, что и я. Просто ты приверженец функционального подхода. Это не хорошо и не плохо, это дело вкуса.
Для себя я уяснил, что некоторые вещи проще и лучше писать в виде класса сразу, чем потом выковыривать из своего же кода функцию и заменять её на класс в связи с тем, что функций стало столько, что их надо как-то организовывать. Преимущество ооп перед обычным процедурным в первую очередь в том, что когда кода становится много, то гораздо легче работать с классом, нежели использовать набор функций.



Я писал все это для своего движка, ты же можешь его и не использовать, я не принуждаю ни к чему. Если желаешь подискутировать на эту тему - милости прошу в скайп.