SplObjectStorage::detach

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

SplObjectStorage::detach从存储中移除一个 对象

描述

public SplObjectStorage::detach(对象 $object): void

从存储中移除 对象

参数

object

要移除的 对象

返回值

没有返回值。

范例

范例 #1 SplObjectStorage::detach() 示例

<?php
$o
= new stdClass;
$s = new SplObjectStorage();
$s->attach($o);
var_dump(count($s));
$s->detach($o);
var_dump(count($s));
?>

上面的例子将输出类似于

int(1)
int(0)

参见

添加注释

用户贡献的注释 4 个注释

13
r dot wilczek at web-appz dot de
14 年前
从存储中分离当前条目会阻止 SplObjectStorage::next() 操作。

作为 PHPUnit 测试的示例

<?php
public function testDetachingCurrentPreventsNext()
{
$storage = new SplObjectStorage;
$storage->attach(new stdClass);
$storage->attach(new stdClass);
$storage->rewind();
$iterated = 0;
$expected = $storage->count();
while (
$storage->valid()) {
$iterated++;
$storage->detach($storage->current());
$storage->next();
}
$this->assertEquals($expected, $iterated);
}
?>

此测试将失败,因为迭代将永远无法到达第二个 stdClass。
SplObjectStorage::next() 显然依赖于当前元素有效。

如果要分离迭代期间的对象,您应该取消引用对象,然后调用 next(),并在 next() 后分离引用。

<?php
public function testDetachingReferenceAfterNext()
{
$storage = new SplObjectStorage;
$storage->attach(new stdClass);
$storage->attach(new stdClass);
$storage->rewind();
$iterated = 0;
$expected = $storage->count();
while (
$storage->valid()) {
$iterated++;
$object = $storage->current();
$storage->next();
$storage->detach($object);
}
$this->assertEquals($expected, $iterated);
}
?>

此测试将通过。
3
alan dot bem at gmail dot com
10 年前
SplObjectSotage::detach() 有一个错误 - 它会重绕内部数组指针。
记住这一点 - 当循环遍历存储时 - 因为它没有解决方法。

https://bugs.php.net/bug.php?id=65629&edit=2
2
nawa
1 年前
在循环内部分离对象时出现问题情况,因为 SplObjectStorage 需要在 detach() 之前调用 next()

使用 foreach 的示例
<?php
/**
* spl 对象存储在循环时的错误
* @see https://bugs.php.net/bug.php?id=65629
*/
$firstStorage = new SplObjectStorage();
$secondStorage = new SplObjectStorage();
// 临时存储
$temporaryStorage = new SplObjectStorage();
// 范围 0 - 9
$range = range(0, 9);

foreach (
$range as $id) {
$object = new stdClass();
$object->id = $id;
$firstStorage->attach($object);
$secondStorage->attach($object);
}

// 在循环中直接分离
foreach ($firstStorage as $storage) {
// 在普通数组中,它将在循环中分离所有元素
// 但对象存储仍然保留 1 个对象
if ($storage->id < 5) {
$firstStorage->detach($storage);
}
}

// 将存储收集到临时 SplObjectStorage 中
foreach ($secondStorage as $storage) {
// 收集到临时存储中
if ($storage->id < 5) {
$temporaryStorage->attach($storage);
}
}
// 通过临时存储移除所有
$secondStorage->removeAll($temporaryStorage);

var_dump(count($firstStorage)); // int(6)
var_dump(count($secondStorage)); // int(5)
?>

使用 while 的示例
<?php
$firstStorage
= new SplObjectStorage();
$secondStorage = new SplObjectStorage();
// 临时存储
$temporaryStorage = new SplObjectStorage();
// 范围 0 - 9
$range = range(0, 9);

foreach (
$range as $id) {
$object = new stdClass();
$object->id = $id;
$firstStorage->attach($object);
$secondStorage->attach($object);
}

$firstStorage->rewind();
while (
$firstStorage->valid() && ($current = $firstStorage->current())) {
if (
$current->id < 5) {
$firstStorage->detach($current);
}
// 在分离后不要调用 next
$firstStorage->next();
}

$secondStorage->rewind();
while (
$secondStorage->valid() && ($current = $secondStorage->current())) {
// 在分离之前调用 next 行为
$secondStorage->next();
if (
$current->id < 5) {
$secondStorage->detach($current);
}
}

var_dump(count($firstStorage)); // int(6)
var_dump(count($secondStorage)); // int(5)
?>
2
Hayley Watson
6 年前
如果您尝试分离不在集合中的对象,SplObjectStorage 不会有任何抱怨;它是一个空操作。

<?php

$o
= new StdClass;
$t = new StdClass;
$s = new SplObjectStorage();
$s->attach($o);
var_dump(count($s));
$s->detach($t); // 没有附加此对象。
var_dump(count($s));

?>
To Top