1

Тема: Клас опитувань

Всім привіт (мене звать Віталюка=))
Викладаю на обговорення клас опитувань. Він поки бета... проте працює.

<?php
 /*
  * Клас опитувань
  * Автор: BoGdAn/ARMYbodya <armybodya@gmail.com>
  * URL: https://weua.info/bogdan
  * Дата: 29 вересня 2014р
  * Оновлення: 4 грудня 2014р
  */
  
class parseString { 

    function array_to_string($arr, $max = 0) { 
        if($max == 1) 
            $str = implode(',', $arr);
        else {
            $count = count($arr);
            foreach($arr as $v) {
                $str .= implode(',' ,$v);
                if(++$i != $count)
                    $str .= '|';
            }
        }
        return $this->string($str);
    }

    function string_to_array($str, $max = 0) {
        $str = $this->string($str);
        if($max == 1) { 
            if(empty($str)) return array();
                $arr = explode(',', $str);
        }
        else {
            $arr = array();
            $v = empty($str) ? array() : explode('|', $str);
            if(!$max) 
                $max = count($v);
            for($i = 0; $i <= ($max-1); ++$i)
                $arr[] = empty($v[$i]) ? array() : explode(',', $v[$i]);
        }
        return $arr;
    }
    
    function  to_flat_array($arr){  
        $out = array();  
        if(!is_array($arr)) 
            return $arr; 
        foreach($arr as $v) { 
            $req = $this->to_flat_array($v);
            if(is_array($req)) 
                $out = array_merge($out, $req);  
            else  
                $out[] = $req;  
        } 
        return $out; 
    } 
    
    function string($str) {
        $arr = array(',,' => ',', ' ' => '', "\n" => '', "\r" => '');
        return strtr($str, $arr);
    }
    
}
  
class Vote extends parseString {

    public $col_vote; 
    public $arr;
    public $string;

    function __construct($str, $col_vote = 1) {
        $this->col_vote = $col_vote;
        $str = $this->string($str);
    $this->arr = $this->string_to_array($str, $this->col_vote);
    }

    function add($id, $cheng = 1) {
        if($this->col_vote == 1) {
            if(in_array($id, $this->arr)) { 
                $arr_flip = array_flip($this->arr);
                unset($arr_flip[$id]);
                $this->arr = array_flip($arr_flip);
            }
            else 
                $this->arr[] = $id;
        return $this->array_to_string($this->arr, 1);
        }
        $arr_p = array();
        foreach($this->arr as $mas) 
            if(in_array($id, $mas)) {
                $noadd = 1;
                $mas_flip = array_flip($mas);
                unset($mas_flip[$id]);
                $mas = array_flip($mas_flip);
                $arr_p[] = $mas; 
            }
            else  
                $arr_p[] = $mas;
        if(!isset($noadd))
            if(!is_array($arr_p[$cheng]))
                $arr_p[$cheng] = array($id);
            else
                $arr_p[$cheng][] = $id;
        return $this->array_to_string($arr_p);
    }

    function view() { 
        if($this->col_vote == 1) 
            return count($this->arr);
        $r_arr = array();
        foreach($this->arr as $mas)
            $r_arr[] = count($mas);
        return $r_arr;
    }

    function in_vote($id) { 
        if($this->col_vote == 1) 
            if(in_array($id, $this->arr))
                return 1;
            else 
                return 0;
        $r_arr = array();
        foreach($this->arr as $mas)
            if(in_array($id, $mas))
                $r_arr[] = 1;
            else 
                $r_arr[] = 0;
        return $r_arr;
    }

    function uslist($cheng = 'all') {
        if($cheng == 'all') 
            return $this->to_flat_array($this->arr);
        if($this->col_vote == 1)
            return $this->arr;
        else 
            return $this->arr[$cheng];
    }

    function __destruct() {
        foreach($this as $key => $value) 
            unset($this->$key); 
    } 

}

Приклад і сам клас в прикріпленому файлі.

Post's attachments

vote_by_BoGdAn.zip 2.92 kb, 315 downloads since 2014-12-04 

2

Re: Клас опитувань

Дам декілька порад
В першу чергу форматуйте  сій код ;) Досить важко читати :)
В другу чергу є ж github =) туди виклали, тут написали ;)
більше нічого сказати не можу :)

3

Re: Клас опитувань

funivan написав:

Дам декілька порад
В першу чергу форматуйте  свій код ;) Досить важко читати :)
В другу чергу є ж github =) туди виклали, тут написали ;)
більше нічого сказати не можу :)

Ви не перші хто радить форматувати код ;) нажаль я непослушний хлопчик :)

Вчора вночі коли більшість людей україни вже спало, я чомусь згадав про клас який закинув. З моїм інтернетиком, відкриваючи гітхабик я б заснув( Більше так не буду *SORRY*

Так все погано? :'(

4

Re: Клас опитувань

Так все погано? :'(

На перших порах у всіх все погано. Якщо дивитись на чужий код і брати найкраще - тоді все буде норма)

5

Re: Клас опитувань

funivan написав:

Так все погано? :'(

На перших порах у всіх все погано. Якщо дивитись на чужий код і брати найкраще - тоді все буде норма)

Що саме не сподобалось?

6 Востаннє редагувалося TwiStar (09.12.2014 23:41:02)

Re: Клас опитувань

У цьому коді є досить багато речей, які викликають здивування.

По порядку.

1. У Вас є три різні види опитувань. Навіщо намагатися реалізувати їх через один клас? Ще більше if-ів у кожен метод? Це зробить Ваш код ще більш заплутаним та вразливим для помилок. Я би радив зробити один абстрактний клас Vote, в якому залишити лише той код, який є спільним для всіх видів опитування, та внаслідувати від нього три класси, кожен з яких буде відповідати своєму виду опитування, в яких реалізувати відмінності.

2. Клас parseString. Цей класс не має жодного відношення до опитування, тому якось дивно, що від нього наслідується класс Vote. Якщо хочете відокремити його функціонал - зробіть композицію, щось на зразок

    function __construct()
    {
          $this->helper = new StringHelper();
    }

Або просто задекларуйте ці функції як методи у Vote.
Наслідування - дуже негнучка річ, тому ним краще користуватися обережно, не використовуючи для поєднання несумісних обьектів.

3. Взагалі, цей класс існує лише тому, що Ви вирішили створити свій формат даних, але зовсім незрозуміло, навіщо. Ваш формат даних дуже стандартний, не потрібно вигадувати квадратне колесо. Є метод serialize, який перетворює масиви на строки, та зворотній для нього метод. Чому не скористатися ними?

4. З одного боку добре, що процес отримання та збереження даних відокремлений від самого класу опитувань, але оскільки опитування дуже тісно зав'язані на цих даних, я б радив зробити окремий клас для отримання та запису даних, та передавати його на конструктор класу Vote для подальшого використання. Таким чином буде легко замінити файл на, наприклад, базу даних.

5. Якщо Ви намагаєтесь писати код таким чином, щоб ним могли користуватися інші - робіть так, щоб ним було зручно користуватись. Про стиль коду вже казали, але це ще не все - наприклад, назви змінних $arr, $col_vote, $str - без жодних коментарів дуже важко розібратися у цьому коді. Намагайтесь називати свої змінні та методи більш зрозумілим чином, пишіть коментарі - це дуже допоможе і Вам також.

6. Взагалі, більше читайте про ООП, намагайтеся зрозуміти, навіщо, взагалі. ним користуються, і чого з його допомогою намагаються досягти. Дуже важлива аббревіатура - SOLID. Якщо розібратися з нею, програмування переходить на якісно новий рівень.

Подякували: quez, army.bodya2

7

Re: Клас опитувань

Дякую за зауваження.

1) Насправді їх два види лайк і опитування. Розділю.

2) Це тому що я всеж думав розділити клас Vote на Like і Vote.

3) Я знайомий з функціями serialize і json_encode за допомогою яких можна зберігати масив із даними в одну лінію. Мені не сподобалося відчутне навантаження на сервер. Типу мікро оптимізація. Тим паче легко замінити вміст методів кодування і декодування на serialize і unserialize.

4) Не зрозумів. Клас віддає (через метод Vote::add() ) та отримує дані (Через конструктор), а куди ви їх зберігаєте/звідки отримуєте мене не хвилює. Приклад на файлах але це не означає що не можна використовувати базу даних.

5) мені ні))) Проте я оформлю код опісля допрацювань.