Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Как лучше сделать вызов различных функций


Автор: lemniscate 27.3.2012, 10:17
Добрый день! Есть такой код 
Код

function htmltable(){

        if($this->show_head){$l .= $this->htmltblhead();}
        while($row = $this->db->fetch_array()){
           $i=0;
           $l .= '<tr>';
           if($this->numrows){$l .= '<td>'.$i.'</td>';}
           while($i < $this->db->num_fields){
                 $l .= '<td>'.$row[$this->db->fields[$i]].'</td>';
                 $i++;
           }
           $l .= '</tr>';
        }
        return $l;
    }


по сути данная функция позволяет создавать html таблицу на основе полученного запроса из mysql. Все работает, все ок. 
Но вот вопрос:
1. На мой взгляд данный код слишком громоздкий (вложенные циклы и т.д.), есть ли вариант его упростить?  
2. По теме топика - как сделать лучше и проще чтобы к выводимому значению применялись различные функции, ну например в таблице есть поле date для него нужно применить функцию date('d-m-Y', strtotime(название поля)), а также другие функции. 

Подумал сделать так, в функцию передать массив полей и действий к ним что нить вроде этого "название поля"=>" название функции", соответственно в коде если данное поле есть в массиве то применяется соответствующая функция. Но такой вариант мне кажется существенно затормозит всю работу. 

Заранее спасибо 

Автор: Fortop 27.3.2012, 13:14
Цитата(lemniscate @  27.3.2012,  10:17 Найти цитируемый пост)
Подумал сделать так, в функцию передать массив полей и действий к ним что нить вроде этого "название поля"=>" название функции", соответственно в коде если данное поле есть в массиве то применяется соответствующая функция. Но такой вариант мне кажется существенно затормозит всю работу. 

Если у вас не таблица на миллионы ячеек, то это не имеет значения. Т.е. можете пользоваться таким вариантом.

Что касается циклов, то если они вам сильно не нравятся, то внутренний цикл можно заменить таким
Код

$htmlRow = '<td>' . implode('</td><td>', $row) . '</td>';

Автор: lemniscate 27.3.2012, 19:00
ок, спасибо! пойду пока в этом направлении. 

а вот еще вопрос, как можно оптимизировать вот этот код? 

Код

function htmltblhead(){
        $h = '<tr>';
        if($this->numrows){$h = '<td> № </td>';}
        $i=0;        
        while($i < $this->db->num_fields){
            if($this->translate_head){
                $t = $this->translate_head[$this->db->fields[$i]];
            }
            else{
                $t = $this->db->fields[$i];
            }
            if($this->order_by){
                $t = $this->orderby($this->db->fields[$i], $t); 
            }
            $h .= '<td>'.$t.'</td>';
            $i++;
        }
        $h .= '</tr>';
        return $h;
    }


Данная функция работает. Она выводит заголовок таблицы html, в качестве заголовков выводятся название полей, также можно делать перевод на русский через массив.  Но вот что мне не нравится это то как реализовал функцию сортировки  $this->orderby, которая добавляет тег A с различными аттрибутами 

вот код: 
Код

function orderby($a, $b){
        $c = "<a ".$this->order_by[1]." ".$this->order_by[0]."&orderby=".$a.">".$b."</a>";
        return $c;
    }


а вот в коде 
Код

$tbl->order_by = array('value=reestr.php?', 'href="#" class=menu');


получилось как то криво. задача в том чтобы сделать универсально, чтобы путь брался или из  href или через jquery и ajax. не могу сообразить как сделать проще, помогите. 

Автор: Sentox 27.3.2012, 22:57
Я думаю стоит немного причесать код вот так, но всё таки с архитектруой что то не то:
Это версия рефакторинга 1.0.0
Код

public function getHeadTable()
    {
        $head = '<tr>';

        if($this->numrows)
        {
            $head .= '<td> № </td>';
        }

        // Определение значение ячейки для html таблицы и рендеринг html кода
        // Две абстракции: определение значений и рендеринг html кода стоит рефакторить и читаемость кода затруднена загромождением цикла
        for($i = 0; $i < $this->db->count_fields; $i++)
        {
            $cellValue = $this->db->fields[$i];
            // Если ни одно из условий не совпадает значение для ячейки по умолчанию остаётся значением из поля таблицы БД
            if(is_array($this->translate_head) && count($this->translate_head) > 1)
            {
                $cellValue = $this->translate_head[$this->db->fields[$i]];
            }
            elseif(is_array($this->order_by))
            {
                // При рефакторинге видно что метод $this->orderby($this->db->fields[$i], $t); избыточен в параметрах
                // то есть два параметра при определённых условиях являются одним и тем же значением
                $cellValue = $this->orderOfValueCell($cellValue, $cellValue);
            }

            $head .= '<td>' . $cellValue . '</td>';
        }

        $head .= '</tr>';

        return $head;
    }


Версия рефакторинга 1.1.0
Код

public function getHeadTable()
    {
        $head = '<tr>';

        if($this->numrows)
        {
            $head .= '<td> № </td>';
        }

        /* Рендеринг html кода таблицы. 
         В этом варианте более удобочитаемый код и разделён по разным абстракциям что само по себе удобно поддерживать и тестировать.
         Не стоит применять напрямую доступ к параметрам строк и самим строкам, так как если у Вас будут набираться строки не из БД
         , а из дугого места или при инициализации самого объекта массивом другого происхождения.
         Например так будет гибче: $this->count_fields и $this->fields будут инициализироваться в другом месте и определённом методе
         тогда эти методы и код будет независим от источника получения данных */
        for($i = 0; $i < $this->count_fields; $i++)
        {
            $cellValue = $this->detectValueForCell($i);
            $head .= '<td>' . $cellValue . '</td>';
        }

        $head .= '</tr>';

        return $head;
    }

    private function detectValueForCell($numField)
    {
        $cellValue = $this->fields[$numField];
        // Если ни одно из условий не совпадает значение для ячейки по умолчанию остаётся значением из поля таблицы БД
        if(is_array($this->translate_head) && count($this->translate_head) > 1)
        {
            $cellValue = $this->translate_head[$cellValue];
        }
        elseif($this->order_by !== false)
        {
            $cellValue = $this->getLinkForOrder($cellValue, $this->order_by);
        }

        return $cellValue;
    }

    private function getLinkForOrder($cellValue, $htmlOptions = false)
    {
        $link = "<a href=\"reestr.php?order=" . $cellValue . "\" class=\"order_by\" value="{$cellValue}">Order by of " . $cellValue  . "</a>";
        return $link;
    }


Автор: lemniscate 28.3.2012, 05:38
Вот это дельный совет! спасибо большое. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)