如何在foreach循环之前/之后触发代码,只有在PHP 7.4+中以有效的方式输入此代码,才可以触发?

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

[这有点类似于问题:How to determine the first and last iteration in a foreach loop?,但是,已有10年历史的问题非常以array为导向,并且没有一个答案与可以循环使用许多不同类型的事实兼容。

在PHP> = 7.4中给出了可以迭代的循环(数组,迭代器,生成器,PDOStatementDatePeriod,对象属性等),我们如何在有效的方式,需要在循环之前/之后发生的代码,但仅在进入循环的情况下

典型的用例是生成HTML列表:

<ul>
  <li>...</li>
  <li>...</li>
  ...
</ul>

<ul></ul>如果有某些元素,则必须打印。[[only。

这些是我到目前为止发现的约束:

    [empty():不能用于empty() / generators
  1. iterators:已弃用。
  2. each()破坏了生成器的优势。
  3. 在循环内和循环后测试的
  4. A
  5. boolean标志不视为效率,因为它会导致该测试在每次迭代中执行,而不是在循环的开始和结束时执行一次循环。
  6. 在上面的示例中,可能使用虽然
  7. 输出缓冲
  8. 或字符串连接来生成输出,但它不适合循环不会产生任何输出的情况。 (感谢each()的其他建议)
下面的代码片段总结了许多不同的类型,我们可以使用它们进行iterator_to_array()的迭代,可以用作提供答案的起点:

iterator_to_array()

这样的脚本应产生以下输出:

@barmar

php loops foreach iterable php-7.4
1个回答
0
投票
至少这是一个有趣的思想实验...

foreach

示例用法:

foreach

输出

<?php // Function that iterates on $iterable function iterateOverIt($iterable) { // How to generate the "<ul>"? foreach ($iterable as $item) { echo "<li>", $item instanceof DateTime ? $item->format("c") : ( isset($item["col"]) ? $item["col"] : $item ), "</li>\n"; } // How to generate the "</ul>"? } // Empty array iterateOverIt([]); iterateOverIt([1, 2, 3]); // Empty generator iterateOverIt((function () : Generator { return; yield; })()); iterateOverIt((function () : Generator { yield 4; yield 5; yield 6; })()); // Class with no public properties iterateOverIt(new stdClass()); iterateOverIt(new class { public $a = 7, $b = 8, $c = 9;}); $db = mysqli_connect("localhost", "test", "test", "test"); // Empty resultset iterateOverIt($db->query("SELECT 0 FROM DUAL WHERE false")); iterateOverIt($db->query("SELECT 10 AS col UNION SELECT 11 UNION SELECT 12")); // DatePeriod generating no dates iterateOverIt(new DatePeriod(new DateTime("2020-01-01 00:00:00"), new DateInterval("P1D"), new DateTime("2020-01-01 00:00:00"), DatePeriod::EXCLUDE_START_DATE)); iterateOverIt(new DatePeriod(new DateTime("2020-01-01 00:00:00"), new DateInterval("P1D"), 3, DatePeriod::EXCLUDE_START_DATE));

如果传递的迭代器不产生任何值,则不会得到任何输出。

请参见<ul> <li>1</li> <li>2</li> <li>3</li> </ul> <ul> <li>4</li> <li>5</li> <li>6</li> </ul> <ul> <li>7</li> <li>8</li> <li>9</li> </ul> <ul> <li>10</li> <li>11</li> <li>12</li> </ul> <ul> <li>2020-01-02T00:00:00+00:00</li> <li>2020-01-03T00:00:00+00:00</li> <li>2020-01-04T00:00:00+00:00</li> </ul>

我绝不赞成将此作为一个好主意,这完全取决于您。我敢肯定,对于一些比较模糊的SPL类,有一些更优雅的方法可以做到这一点。通过扩展而不是合成来完成它可能也更简单。

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