PHP.mk документација

SplObjectStorage

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

class.splobjectstorage.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека class.splobjectstorage.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
SplObjectStorage

Референца за `class.splobjectstorage.php` со подобрена типографија и навигација.

class.splobjectstorage.php

Класата SplObjectStorage

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

Вовед

Класата SplObjectStorage обезбедува мапа од објекти до податоци или, со игнорирање на податоците, сет од објекти. Оваа двојна намена може да биде корисна во многу случаи кога е потребно уникатно идентификување на објекти.

Примери

Пример #1 SplObjectStorage како сет

<?php
// As an object set
$s = new SplObjectStorage();

$o1 = new stdClass;
$o2 = new stdClass;
$o3 = new stdClass;

$s->attach($o1);
$s->attach($o2);

var_dump($s->contains($o1));
var_dump($s->contains($o2));
var_dump($s->contains($o3));

$s->detach($o2);

var_dump($s->contains($o1));
var_dump($s->contains($o2));
var_dump($s->contains($o3));
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

bool(true)
bool(true)
bool(false)
bool(true)
bool(false)
bool(false)

Пример #2 SplObjectStorage како мапа

<?php
// As a map from objects to data
$s = new SplObjectStorage();

$o1 = new stdClass;
$o2 = new stdClass;
$o3 = new stdClass;

$s[$o1] = "data for object 1";
$s[$o2] = array(1,2,3);

if (isset(
$s[$o2])) {
var_dump($s[$o2]);
}
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}

Дневник на промени

Верзија = NULL
8.4.0 Имплементирај SeekableIterator, претходно само Итератор беше имплементирана.

Содржина

Белешки од корисници 11 белешки

Адам Монсен
12 години пред
Note some inconsistent/surprising behavior in SplObjectStorage to preserve backwards compatibility. You can't properly use foreach with key/value syntax.

<?php
$spl = new SplObjectStorage ();
$keyForA = new StdClass();
$keyForB = new StdClass();
$spl[$keyForA] = 'value a';
$spl[$keyForB] = 'value b';
foreach ($spl as $key => $value)
{
    // $key is NOT an object, $value is!
    // Must use standard array access to get strings.
    echo $spl[$value] . "\n"; // prints "value a", then "value b"
}
// it may be clearer to use this form of foreach:
foreach ($spl as $key)
{
    // $key is an object.
    // Use standard array access to get values.
    echo $spl[$key] . "\n"; // prints "value a", then "value b"
}
?>

See https://bugs.php.net/bug.php?id=49967
рафал на pawlukiewicz точка com
пред 7 години
SplObjectStorage class can be nicely used in Observer pattern, for example:

<?php
class Subject implements \SplSubject
{
    private $observers;
    
    public function __construct()
    {
        $this->observers = new \SplObjectStorage;
    }

    public function attach(\SplObserver $observer)
    {
        $this->observers->attach($observer);
    }

    public function detach(\SplObserver $observer)
    {
        $this->observers->detach($observer);
    }

    public function notify()
    {
        foreach ($this->observers as $observer) {
            $observer->update($this);
        }
    }
}
?>
frame86 на live dot com
пред 9 години
Keep in mind that foreach() will copy your array before iterating, SplObjectStorage does not. If you have a sub call within an iteration that also calls foreach() on the object storage again, the iterator position collides!

To be safe use:
<?php
foreach(clone $myStorage as $obj) {

}
?>
м точка древек на smf точка de
пред 11 години
Please note that SplObjectStorage has a Bug introduced with 5.4.0, breaking object lookup in cloned instances of derived classes that overwrite getHash().

This is a confirmed Bug: https://bugs.php.net/bug.php?id=67582

Example:
<?php
class MyObjectStorage extends SplObjectStorage {
    // Overwrite getHash() with just some (working) test-method
    public function getHash($object) { return get_class($object); }
}

class TestObject {}

$list = new MyObjectStorage(); // No issues if using "new SplObjectStorage()"
$list->attach(new TestObject());

foreach($list as $x) var_dump($list->offsetExists($x)); // TRUE

$list2 = clone $list;
foreach($list2 as $x) var_dump($list2->offsetExists($x)); // FALSE
?>
grzeniufication
пред 8 години
<?php
/**
  * For simple use cases (where you want to keep objects in a map)
  * I would suggest to stick to an plain old array. Just use the object
  * hash as array key.
  */
$entity1 = new stdClass();
$entity2 = new stdClass();
$entities = [];
$entities[spl_object_hash($entity1)] = $entity1;
$entities[spl_object_hash($entity2)] = $entity2;

// object hashes are hard to distinguish so you could run a hash function
// on them for better readability.
$entities[md5(spl_object_hash($entity1))] = $entity1;
$entities[md5(spl_object_hash($entity2))] = $entity2;

print_r($entities);
крис точка ламоте на it-kitchen точка be
пред 10 години
For anyone having issues with SplObjectStorages containing corrupt member variables after garbage collection (FatalErrorException after serializing): we used following fix to great effect
<?php

class FixedSplObjectStorage extends SplObjectStorage
{

    public function serialize()
    {
        $goodPortion = 'N;;m:a:0:{}';
        $startKey = 'N;;m:a:';

        $serialized = parent::serialize();

        $startPos = strpos($serialized, $startKey);

        if ($startPos !== false) {
            $serialized = substr_replace($serialized, $goodPortion, $startPos, -1);

        }

        return $serialized;

    }
}

?>
inwebo на gmail точка fr
пред 14 години
I needed to merge SplObjectStorages.
<?php
// As an object set
$SplObjectStorage_1 = new SplObjectStorage();

$object1 = new StdClass;
$object1->attr = 'obj 1';
$object2 = new StdClass;
$object2->attr = 'obj 2';
$object3 = new StdClass;
$object3->attr = 'obj 3';

$SplObjectStorage_1->attach($object1);
$SplObjectStorage_1->attach($object2);
$SplObjectStorage_1->attach($object3);

// Another one object set
$SplObjectStorage_2 = new SplObjectStorage();

$object4 = new StdClass;
$object4->attr = 'obj 4';
$object5 = new StdClass;
$object5->attr = 'obj 5';
$object6 = new StdClass;
$object6->attr = 'obj 6';

$SplObjectStorage_2->attach($object4);
$SplObjectStorage_2->attach($object5);
$SplObjectStorage_2->attach($object6);

/**
 * Merge SplObjectStorage
 *
 * @param how many SplObjectStorage params as you want
 * @return SplObjectStorage
 */
function mergeSplObjectStorage() {
    
    $buffer   = new SplObjectStorage();

    if( func_num_args() > 0  ) {
        $args = func_get_args();
        foreach ($args as $objectStorage) {
            foreach($objectStorage as $object) {
                if(is_object( $object ) ) {
                    $buffer->attach($object);
                }
            }
        }
    }
    else{
        return FALSE;
    }
    return $buffer;
}

$merge = mergeSplObjectStorage($SplObjectStorage_1, $SplObjectStorage_2);

?>
<?php
echo $merge->count();
?>
Will output :
6

<?php
$merge->rewind();
while($merge->valid()) {
    $object = $merge->current();
    var_dump($object);
    $merge->next();
}
?>
Will ouput :
object(stdClass)#2 (1) {
  ["attr"]=>
  string(5) "obj 1"
}
object(stdClass)#3 (1) {
  ["attr"]=>
  string(5) "obj 2"
}
object(stdClass)#4 (1) {
  ["attr"]=>
  string(5) "obj 3"
}
object(stdClass)#6 (1) {
  ["attr"]=>
  string(5) "obj 4"
}
object(stdClass)#7 (1) {
  ["attr"]=>
  string(5) "obj 5"
}
object(stdClass)#8 (1) {
  ["attr"]=>
  string(5) "obj 6"
}

My two cents.
Мариус
пред 11 години
Do not use SplObjectStorage::detach when forach'ing over items in the storage as this skips the second (and only second) element.

Example:

<?php

class A {
    public $i;
    public function __construct($i) {
        $this->i = $i;
    }
}

$container = new \SplObjectStorage();

$container->attach(new A(1));
$container->attach(new A(2));
$container->attach(new A(3));
$container->attach(new A(4));
$container->attach(new A(5));

foreach ($container as $item) {
    echo $item->i . "\n";
    $container->detach($item);
}
echo "== Left in storage ==\n";
foreach ($container as $item) {
    echo $item->i . "\n";
}
/* Outputs:
1
3
4
5
== Left in storage ==
2
*/
?>
oheil at ecc-gmbh dot de
пред 4 години
If you assign an array() to an object in SplObjectStorage and then try to modify its individual elements, you'll probably find it doesn't work.
Instead, you can use ArrayObject(), which will emulate array behaviour.

<?php

$storage = new SplObjectStorage();

$obj1 = new StdClass();
$obj2 = new StdClass();

$storage[$obj1] = array();
$storage[$obj2] = new ArrayObject();

$storage[$obj1]['person'] = 'Jana'; // Won't work  (PHP Notice:  Indirect modification of overloaded element of SplObjectStorage has no effect)
$storage[$obj2]['person'] = 'Jana'; // Works

var_dump($storage[$obj1]['person']); // NULL  (PHP Notice:  Undefined index: person)
var_dump($storage[$obj2]['person']); // string(4) "Jana"

?>
[email protected]
пред 8 години
if you're looking for a ResourceStorage, check https://gist.github.com/divinity76/b8041e073b74bdeab562a075fc94217f

(i needed it for socket programming with socket_select())
Јан Валтер
пред 14 години
I rewrote some scripts and changed object storage with arrays to SplObjectStorage. At some point I needed support of array_rand() but I did not find a function to return a random attached object of an SplObjectStorage object.

So here is my solution for random access to SplObjectStorage:

<?php
$o1 = new StdClass;
$o2 = new StdClass;
$s = new SplObjectStorage;
$s->attach($o1);
$s->attach($o2);

$random = rand(0,$s->count()-1);
$s->rewind();
for($i=0;$i<$random;$i++) {
  $s->next();
}
var_dump($s->current());
?>
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.