Распределить содержимое равномерно таблиц с помощью php


Роде алгоритм в php, чтобы заполнить 4 таблицы в html-форме.

Однако, я нахожу, мой код немного грязный, и я хотел бы проверить, существует ли более чистым способом создать этот код.

То, что он делает: Он принимает массив с именами и добавочных номеров, и распределяет их равномерно на 4 таблицы, независимо от того, сколько чисел и расширения, если число не делится на 4, он берет остальные, и распределяет.

Детали: массив-это только тест, результат приходит CRUD, кто владеет BD.

использование свойств HTML inline, это всего лишь тест, в системе будет управляться с классами CSS, ответственность.

То, что я прошу сосредоточить внимание исключительно на алгоритм распределитель результатов.

Ниже мой массив:

<?php
$grupos = array(
    'adm' => array(
        0 => array(
            'nome' => 'nome0',
            'ramal' => 'ramal0'
        ),
        1 => array(
            'nome' => 'nome1',
            'ramal' => 'ramal1'
        ),
        2 => array(
            'nome' => 'nome2',
            'ramal' => 'ramal2'
        ),
        3 => array(
            'nome' => 'nome3',
            'ramal' => 'ramal3'
        ),
        4 => array(
            'nome' => 'nome4',
            'ramal' => 'ramal4'
        ),
        5 => array(
            'nome' => 'nome5',
            'ramal' => 'ramal5'
        ),
        6 => array(
            'nome' => 'nome6',
            'ramal' => 'ramal6'
        ),
        7 => array(
            'nome' => 'nome7',
            'ramal' => 'ramal7'
        ),
        8 => array(
            'nome' => 'nome8',
            'ramal' => 'ramal8'
        ),
        9 => array(
            'nome' => 'nome9',
            'ramal' => 'ramal9'
        )
    )
);

Код

define("DIVISOR", 4); //Número de tabelas
$array_size = count($grupos['adm']); //quantidade de ramais
$qtd_por_tabela = (int) ($array_size / DIVISOR); //quantidade em cada tabela
$resto = ($array_size % DIVISOR); //resto a ser dividido nas tabelas
$y = 0; //contador array

for ($i = 1; $i <= DIVISOR; $i++) {
    echo "<div class=\"tables\"><table>";
    $sobra = $resto > 0 ? 1 : 0;
    for ($x = 1; ($x <= ($qtd_por_tabela + $sobra)); $x++) {
        $tag = "<tr><td>";
        $tag.=$grupos['adm'][$y]['nome'];
        $tag.="</td><td>";
        $tag.= $grupos['adm'][$y]['ramal'];
        $tag.="</td></tr>";
        echo $tag;
        $y++;
    }
    $resto = $resto > 0 ? ($resto - 1) : 0;
    echo "</table></div>";
    echo "\r\n";
}
?>

немного CSS, чтобы играть в таблицы рядом друг с другом...

<style>
    table,
    table td{
    border: 1px solid #000;
    }
    .tables{
        float: left;
        margin: 10px;
    }
</style>

код печатает следующее результат:

<div class="tables">
    <table>
        <tr>
            <td>nome0</td>
            <td>ramal0</td>
        </tr>
        <tr>
            <td>nome1</td>
            <td>ramal1</td>
        </tr>
        <tr>
            <td>nome2</td>
            <td>ramal2</td>
        </tr>
    </table>
</div>
<div class="tables">
    <table>
        <tr>
            <td>nome3</td>
            <td>ramal3</td>
        </tr>
        <tr>
            <td>nome4</td>
            <td>ramal4</td>
        </tr>
        <tr>
            <td>nome5</td>
            <td>ramal5</td>
        </tr>
    </table>
</div>
<div class="tables">
    <table>
        <tr>
            <td>nome6</td>
            <td>ramal6</td>
        </tr>
        <tr>
            <td>nome7</td>
            <td>ramal7</td>
        </tr>
    </table>
</div>
<div class="tables">
    <table>
        <tr>
            <td>nome8</td>
            <td>ramal8</td>
        </tr>
        <tr>
            <td>nome9</td>
            <td>ramal9</td>
        </tr>
    </table>
</div>

Примечание: Он не indenta так мило, но я сделал вручную, чтобы облегчить чтение. Идея достижения этого результата, но с помощью алгоритма более "чистым".

Кто-нибудь знает, как это сделать?

 3
php
Author: Marcelo Aymone, 2014-08-01

1 answers

Существует Шаблон Проектирования Структурной называется Composite, который позволяет абстрагироваться от HTML и построить иерархическую структуру информации, состоящие, как на дереве.

Композитный у вас есть несколько объектов, каждый из которых представляет отдельную ветку HTML, эти последствия могут или не должны быть в составе других элементов.

, Чтобы в ответ не получить больше, чем уже будет стоять, я не буду отправлять коды здесь, да и все вместе в этом Gist. Также входит реализация простыми autoloader, чтобы запускать Приложения и небольшой визуальной привлекательности с CSS.

Во-первых, структуру директорий, а также файлы используются:

|-index.php
|-Composite\Components
|   |-Composite\Components\AbstractComponent.php
|   |-Composite\Components\Component.php
|   |-Composite\Components\Drawable.php
|   \-Composite\Components\HTML
|     |-Composite\Components\HTML\Cell.php
|     |-Composite\Components\HTML\Row.php
|     \-Composite\Components\HTML\Table.php

"Будем знать теперь наши участники":

  • AbstractComponent.php

Это суперкласс, абстрактный, определяет интерфейс для всех объектов составит для этого какой-то элемент, какой-то узел иерархическая структура, и реализует поведение по умолчанию для них.

Свойство AbstractComponent::children) сохраняет все мы-дети каждый элемент создан, при условии, что соблюдено его условие существования, что позволяет рендеринга в уровнях структуры.

"Это" условие существования" управляется свойством AbstractComponent::leaf, который определяет, является ли данный объект является ветвление (FALSE) или листа (TRUE). Последствия могут быть составные других дочерних элементов, тогда как "ведомости", нет.

В Этом сценарии, в частности, в целях упрощения, я буду считая ячейки таблицы в виде листов, даже в реальном случае они не будут.

Метод AbstractComponent::add() это то, что позволяет эффективно Состав возникнуть в смысле совокупности новые объекты друг друга.

Обратите внимание на то, что в нем производится проверка, что объекты, определенные как "лист" не примите новые объекты, снимая исключение логики.

Наконец, что не менее важно, AbstractComponent::drawChildren() предлагает к объектам, которые представляют собой ветви средство рендеринга всех элементов, содержащихся в них. Как вы можете видеть ниже, объекты "лист" являются единственными, которые не использует.

  • Component и Drawable

Имеем два интерфейса, один для представления компонентов и другой для представления объектов renderizáveis. На самом деле только интерфейс Component может быть использована, но, по желанию, я разделить поведение на два интерфейса, что делает Component типа.

  • Table, Row и Cell

В этом примере есть объекты, представляют лишь трех элементов HTML, но вы можете создать другие по мере необходимости, просто расширить суперкласс AbstractComponent и реализовать метод Drawable::draw(). И конечно, если необходимо охарактеризовать элемент, как "лист", перезаписать свойство защищенного описанного выше.

Либо Table Row просты, только участвуют все мы-дети к просмотру через AbstractComponent::drawChildren(), услугах и теги /
и / , соответственно.

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

Обычно в этом время придет тот, предупреждение на гигантский шатер, неоновые говорил, что, когда путем переопределения конструктора суперкласса, вы должны reinvocá его через parent::__construct(). Однако, это вовсе не обязательно в этом Приложении, потому что однажды flag AbstractComponent::leaf были перезаписаны, AbstractComponent::add() вызовет исключение логика случае вызывается в контексте объекта Cell.

, Если не будем ссылаться конструктор, не считаем, что объект, который перезаписать суперкласса лист и все же мы призывали AbstractComponent::add() (caramba, мы можем ошибаться в 3 раза :), мы получим Fatal Error потому что метод , append() бы быть вызван без объекта. Объект этот, ArrayObject, определяется именно в конструктор суперкласса ora индекс.

Да, не, положим, он там. Зло не делает ^_^

Также Table и Row, Cell::draw() ну, просто, просто вставляет значение полученных конструктор, и ныне хранится в свойстве с видимость private (потому что частный это некрасиво :p) между парой тегов /

Но... И как это относится к проблеме?

Сначала мы изменить свой массив ввода, чтобы что-то немного отличается, только чтобы продемонстрировать, что это работает:

$groups = array(
    'Administração' => array(
        0 => array(
            'nome' => 'nome0',
            'ramal' => 'ramal0'
        ),
        1 => array(
            'nome' => 'nome1',
            'ramal' => 'ramal1'
        ),
        2 => array(
            'nome' => 'nome2',
            'ramal' => 'ramal2'
        ),
        3 => array(
            'nome' => 'nome3',
            'ramal' => 'ramal3'
        )
    ),
    'Financeiro' => array(
        4 => array(
            'nome' => 'nome4',
            'ramal' => 'ramal4'
        ),
        5 => array(
            'nome' => 'nome5',
            'ramal' => 'ramal5'
        ),
        6 => array(
            'nome' => 'nome6',
            'ramal' => 'ramal6'
        ),
        7 => array(
            'nome' => 'nome7',
            'ramal' => 'ramal7'
        ),
        8 => array(
            'nome' => 'nome8',
            'ramal' => 'ramal8'
        ),
        9 => array(
            'nome' => 'nome9',
            'ramal' => 'ramal9'
        )
    )
);

Только сломал он, чтобы рассмотреть отдела. Прежде чем выполнять итерацию, чтобы составить нашу структуру, мы должны задать главный элемент той же, то есть, таблица, где каждая строка и каждая ячейка будет совокупной:

$tableGroup = new Composite\Components\HTML\Table;

Сейчас-да, давайте перебора:

foreach( $groups as $group => $persons ) {

    // Groups

    $groupRow = new Composite\Components\HTML\Row;

    $groupRow -> add( new Composite\Components\HTML\Cell( $group ) );

    $tableGroup -> add( $groupRow );

    // Persons

    foreach( $persons as $person ) {

        $nameCell = new Composite\Components\HTML\Cell( $person['nome'] );
        $dialCell = new Composite\Components\HTML\Cell( $person['ramal'] );

        $personRow = new Composite\Components\HTML\Row;

        $personRow -> add( $nameCell ) -> add( $dialCell );

        $tableGroup -> add( $personRow );
    }
}

Сначала мы создаем строку для Отдела. Мы создаем объект Row и добавляем в него один объект Cell с текстом связи. А затем добавил, что первый состав в таблицу с ранее созданной.

Теперь мы будем перебирать список имен и телефонов. Посмотрите, что на этот раз сделал по-другому. Сначала я создал две ячейки и назначить на них сумм. Только поэтому я создал строку и вошел в Состав.

Ничего не помешает мне, например, сделать так:

$personRow = new Composite\Components\HTML\Row;

$personRow -> add( new Composite\Components\HTML\Cell( $person['nome'] ) )
           -> add( new Composite\Components\HTML\Cell( $person['ramal'] ) );

, Однако, таким образом, вы engessa поток и предотвращает клетки получают дополнительные реквизиты (см.ниже).

Перед тем, как закрыть петли, внутренняя, добавили в Состав строки в таблицу.

Теперь Осталось отрендерить все. Вне цикла вызываем метод Drawable::draw() в контексте Table и AbstractComponent::drawChildren() в нем используется будете рендерить все сразу.

Если вы хотите, чтобы отдельные таблицы, для каждого отдела, просто, что таблица, созданная $tableGroup была сделана в начале цикла и его визуализацию, логотип, в конце концов.

Другой момент, который следует учитывать, является тот факт, линия, зарезервированная для имени Отдела, не простираться во всю ширину таблицы.

Это было как преднамеренно, как случайный. Преднамеренно для упрощения реализации без учета каких-либо атрибутов для элементов, как в случае colspan в ячейке из первых строк.

И случайного, потому что время, которое я написал этот код, не помню как объединить ячейки >.

Но такое повышение находится теперь за свой счет. Вы можете, например, создать второй аргумент в конструкторе Cell, массив атрибутов, которые вы вставить в объявлении TD.

И implode() не работает с массивами associativos, может не показаться, но http_build_query(), фантастические для этого.

Несмотря на все это, стоит отметить, что, сегодня, с инструментами, template, существующих на рынке, этот тип реализации Composite там очень полезно, в конце концов, это гораздо легче открыть и закрыть несколько тегов PHP и писать HTML-код прямо в шаблон, который может в том числе быть фигурные, чем отказаться от этого подход.

 5
Author: Bruno Augusto, 2014-09-05 13:00:45