如何使用php实现表过滤器

问题描述 投票:0回答:1

我正在为有关如何实现筛选器选项的数据苦苦挣扎的概述表工作。

表看起来像:

Process Type | Issue Total | Issue closed | Issue open
Piping       |    20       |     15       |    5
Cable pulling|

这已经是属于过程类型(例如管道系统)的单个“项目”的摘要。

“项目”与系统有关。

所以现在我想实现一个筛选器选项来筛选与系统配管有关的问题之和

Filter: <select>
<option>1</option>
<option>2</option>
</select>
<button> Filter results</button>

Process Type | Issue Total | Issue closed | Issue open
Piping       |    20       |     15       |    5
Cable pulling|

我在哪里遇到问题?此表是内容部分中包含的一个.php文件中6个不同表之一。我真的不知道如何在此表上执行过滤器。

预先感谢您的任何想法/建议

php html-table
1个回答
0
投票

我不确定,如果您的数据模型正确无误。但是这是一个小示例,说明如何使用PHP过滤数据结构。在PHP部分之后,我将解释如何设置HTML表单,以便仅在HTML表中输出所需的项目。

PHP部分

我假设您从数据库表或API中读取数据。因此,让我们假设我们的模型看起来像这样。该模型只是一个示例,展示了PHP中对象对象化方法的外观。

<?php
declare(strict_types=1);
namespace Marcel\Model;

class Item
{
    protected $id;
    protected $systemID;
    protected $anotherProperty;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function setId(int $id): self
    {
        $this->id = $id;
        return $this;
    }

    public function getSystemId(): ?int
    {
        return $this->systemId;
    }

    public function setSystemId(int $systemId): self
    {
        $this->systemId = $systemId;
        return $this;
    }

    public function getAnotherProperty(): ?string
    {
        return $this->anotherProperty;
    }

    public function setAnotherProperty(string $anotherProperty): self
    {
        $this->anotherProperty = $anotherProperty;
        return $this;
    }
}

您可以看到我们的项目模型只有三个属性。重要属性将是系统ID。稍后,我们将通过此属性过滤项目集合。在执行此操作之前,我们使用一个集合来存储所有项目对象。为什么要收藏?集合为我们提供了一种类型安全性,并且在过滤集合时使操作更加容易。

<?php
declare(strict_types=1);
namespace Marcel\Model;

use InvalidArgumentException;
use SplObjectStorage;

class ItemCollection extends SplObjectStorage
{
    public function attach($object, $data = null): self
    {
        if (!$object instanceof Item) {
            throw new InvalidArgumentException(sprintf(
                'The given object must be of the type Item. Given: "%s"',
                get_class($object)
            ));
        }

        parent::attach($object, $data);
        return $this;
    }
}

这是我们的物品收藏。该集合扩展了PHP内置类SplObjectStorage,并用于存储对象。在这种情况下,集合仅接受类型为Item的对象。我们的集合实现了Iterator接口,使集合可迭代。非常适合过滤。

我们接下来需要的是过滤器。 PHP带来了一个内置的FilterIterator类,使过滤数据结构像饼一样容易。

<?php
declare(strict_types=1);
namespace Marcel\Filter;

class ItemFilterIterator extends FilterIterator
{
    protected $systemId;

    public function __construct(Iterator $iterator, int $systemId = 0)
    {
        parent::__construct($iterator);
        $this->systemId = $systemId;
    }

    public function accept(): bool
    {
        // if system id is 0 return all items
        if ($this->systemId === 0) {
            return true;
        }

        $item = $this->getInnerIterator()->current();
        return $item->getSystemId() === $this->systemId;
    }
}

这是我们的FilterIterator实现。该扩展需要系统ID作为构造器中的第二个参数。系统ID将是我们的过滤器参数。当某项的系统ID属性等于系统ID过滤器参数时,accept方法将返回true。如果不是,则accept方法返回false。

让我们看看,这三个课程可以为您做些什么。这是一个可行的例子。首先,我将创建一些示例项目。

<?php
declare(strict_types=1);
namspace Marcel;

use Marcel\Filter\ItemFilterIterator;
use Marcel\Model\Item;
use Marcel\Model\ItemCollection;

$item1 = (new Item())
    ->setId(1)
    ->setSystemId(1)
    ->setAnotherProperty('item 1');

$item2 = (new Item())
    ->setId(2)
    ->setSystemId(1)
    ->setAnotherProperty('item 2');

$item3 = (new Item())
    ->setId(3)
    ->setSystemId(2)
    ->setAnotherProperty('item 3');

$collection = (new ItemCollection())
    ->attach($item1)
    ->attach($item2)
    ->attach($item3);

// here comes the magic
$filter = new ItemFilterIterator($collection, 2);
foreach ($filter as $item) {
    var_dump($item);
}

在此示例中,我们有三个项目,它们属于sysmtem id属性设置的两个不同的系统。通常,这些项目应来自您的数据库或数据集来自的任何地方。这些项目设置为集合,我们使用过滤器迭代器类对其进行过滤。在此示例中,我们只希望项目属于系统2。在此设置下,foreach循环仅输出项目3,因为系统ID等于2。]

HTML部分

您的HTML模板看起来不错。我会为您扩展一下。

<form id="my-filter-form" method="post" action="index.php">
    <label for="filter">Filter</label>
    <select name="filter" id="filter">
        <option value="">all</option>
        <option value="1">1</option>
        <option value="2">2</option>
    </select>
    <button type="submit">Filter results</button>
</form>

如您所见,我们使用普通形式,它将选择的过滤器选项发送到名为index.php的php文件。每当有人点击“过滤结果”按钮时,都会发送表格并刷新页面。

这是一个示例index.php文件。

<?php
declare(strict_types=1);
namespace Marcel;

use Marcel\Filter\ItemFilterIterator;
use Marcel\Model\Item;
use Marcel\Model\ItemCollection;

// first get your items from somewhere and fill the item collection
$collection = new ItemCollection();
$collection->attach(...); // attach all the items

// check, if there 's a filter - if not use 0 to display all items
$systemID = (isset($_POST['filter'])) ? intval($_POST['filter']) : 0;

// init the filter iterator
$filter = new ItemFilterIterator($collection, $systemID);
$items = new ItemCollection();

// attach all filtered items to a new collection
foreach ($filter as $item) {
    $items->attach($item);
}
?>

<form id="my-filter-form" method="post" action="index.php">
    <label for="filter">Filter:</label>
    <select id="filter" name="filter">
        <option>all</option>
        <option value="1">system 1</option>
        <option value="2">system 2</option>
    </select>
    <button type="submit">Filter me!</button>
</form>

<table>
    <thead>
        <tr>
            <th>ID</th>
            <th>System</th>
            <th>Name</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($items as $item) : ?>
        <tr>
            <td><?= $item->getId() ?></td>
            <td><?= $item->getSystemId() ?></td>
            <td><?= $item->getAnotherProperty() ?></td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>

请注意,每次您发送表单时页面都会重新加载。如果要避免重新加载,则必须使用ajax(异步javascript请求)。

希望这个小的过滤示例会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.