【问题标题】:Sharing an array of objects across classes in php在 php 中跨类共享对象数组
【发布时间】:2016-06-09 09:19:54
【问题描述】:

我有一个场景,其中一组对象(玩家)必须由其他类的对象读取和修改。这些对象将作用于同一个数组,也就是说,对数组的任何更改都会被所有对象看到。任何东西都可能修改数组,包括线程和 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 是我正在使用的 Web-Socket 库“Ratchet”的一部分。此外,如果有任何区别,每个类都在其自己的 .php 文件中。

我应该如何构建代码?

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

我尝试过的事情:

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

【问题讨论】:

    标签: php multithreading design-patterns pass-by-reference ratchet


    【解决方案1】:

    如果WorldConnectionClass 扩展Thread 类的目的是共享相同的$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));
    }
    

    【讨论】:

    • 在 onOpen() 中追加后,计数仍为零(已在问题中提及)
    • 您传递的是同一个 ArrayObject 实例吗?你能把 ArrayObject 实现的代码贴在这里吗?
    • extends Thread 被删除时,追加突然起作用了。
    • “当extends Thread被删除时,突然追加确实有效”这意味着你必须在那里搜索问题
    • 你是对的。感谢您的帮助,这应该让我继续前进。需要阅读“pthread”文档并了解扩展线程如何影响类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    相关资源
    最近更新 更多