在 php 中的 类 之间共享一组对象

Sharing an array of objects across classes in php

我有一个场景,其中一组对象(玩家)必须由其他 classes 的对象读取和修改。这些对象将在同一个数组上工作,也就是说,对数组的任何更改都会被所有对象看到。任何东西都可能修改数组,包括线程和 IO 事件函数。

具体细节如下:

class Player {
    public $connection;
    public $x,$y,$velocity;

    public function __construct(ConnectionInterface $conn, $initx, $inity) 
    { /* ... */ }

    public function updateVelocity($newVelocity) { /* ... */ }
}

$players_arr = array();

class ConnectionClass extends Thread implements MessageComponentInterface {
    private $players;

    // A new player connected
    public function onOpen(ConnectionInterface $conn) { 
    // ...
        array_push($this->players, new Player($conn, x, y);
    }

    public function run() {
        while(true) {
            // ...
            foreach ($this->players as $player) 
                $player->connection->send(data);
            sleep(1);
        }
    }

}

class World extends Thread {
    private $players;

    public function run() {
        while(true) {
            // ...
            foreach ($this->players as $player) 
                $player->updateVelocity($vel);
            usleep(30000);
        }
    }

}

WorldConnectionClass 中的 $players 应该始终相同!!

ConnectionInterfaceMessageComponentInterface 是 "Ratchet" 我正在使用的 Web-Socket 库的一部分。此外,如果有任何区别,每个 class 都在其自己的 .php 文件中。

我应该如何构建代码?

我应该在 Player class 本身中将共享数组设为静态吗?如果是这样,如何从其他 classes 访问它?

我尝试过的事情:

注意:我知道多线程访问数组需要特殊措施和同步(请详细说明),但主要问题是如何跨线程共享数组classes(不一定是线程)

如果 WorldConnectionClass 扩展 Thread class 的目的是共享相同的 $players 这将不起作用。

据我所知,ArrayObject 的新实例应该可以完成这项工作,您只需将它的实例传递给 WorldConnectionClass实例:

$players = new ArrayObject();
$connection = new ConnectionClass($players); //add it to the other arguments if any
$world = new World($players); //add it to the other arguments if any

//or you can with setter

$players = new ArrayObject();
$connection = new ConnectionClass();
$connection->setPlayers($players);
$world = new World($players);
$world-> setPlayers($players);

您应该更改 WorldConnectionClass 的控制器以使用新参数启动 private $players 属性,或者实施 setter。

public function __construct($players)
{
     $this->players = $players;
}

//or

public function setPlayers($players)
{
     $this->players = $players;
}

您还应该更改 onOpen 的实现:

public function onOpen(ConnectionInterface $conn) { 
// ...
    $this->players->append(new Player($conn, x, y));
}