在 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);
}
}
}
World
和 ConnectionClass
中的 $players 应该始终相同!!
ConnectionInterface
和 MessageComponentInterface
是 "Ratchet" 我正在使用的 Web-Socket 库的一部分。此外,如果有任何区别,每个 class 都在其自己的 .php 文件中。
我应该如何构建代码?
我应该在 Player
class 本身中将共享数组设为静态吗?如果是这样,如何从其他 classes 访问它?
我尝试过的事情:
- 将
$players_arr
的引用传递给 classes 的构造函数并将其分配给 $players
:出现 cannot assign by reference to overloaded object
错误。
http://ubuntuforums.org/showthread.php?t=2082788
- 使用
ArrayObject
:在 onOpen()
中添加 new Player()
不会产生任何效果。 (可能做错了吗?)
Sharing array inside object through classes in php
注意:我知道多线程访问数组需要特殊措施和同步(请详细说明),但主要问题是如何跨线程共享数组classes(不一定是线程)
如果 World
和 ConnectionClass
扩展 Thread
class 的目的是共享相同的 $players 这将不起作用。
据我所知,ArrayObject
的新实例应该可以完成这项工作,您只需将它的实例传递给 World
和 ConnectionClass
实例:
$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);
您应该更改 World
和 ConnectionClass
的控制器以使用新参数启动 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));
}
我有一个场景,其中一组对象(玩家)必须由其他 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);
}
}
}
World
和 ConnectionClass
中的 $players 应该始终相同!!
ConnectionInterface
和 MessageComponentInterface
是 "Ratchet" 我正在使用的 Web-Socket 库的一部分。此外,如果有任何区别,每个 class 都在其自己的 .php 文件中。
我应该如何构建代码?
我应该在 Player
class 本身中将共享数组设为静态吗?如果是这样,如何从其他 classes 访问它?
我尝试过的事情:
- 将
$players_arr
的引用传递给 classes 的构造函数并将其分配给$players
:出现cannot assign by reference to overloaded object
错误。 http://ubuntuforums.org/showthread.php?t=2082788 - 使用
ArrayObject
:在onOpen()
中添加new Player()
不会产生任何效果。 (可能做错了吗?) Sharing array inside object through classes in php
注意:我知道多线程访问数组需要特殊措施和同步(请详细说明),但主要问题是如何跨线程共享数组classes(不一定是线程)
如果 World
和 ConnectionClass
扩展 Thread
class 的目的是共享相同的 $players 这将不起作用。
据我所知,ArrayObject
的新实例应该可以完成这项工作,您只需将它的实例传递给 World
和 ConnectionClass
实例:
$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);
您应该更改 World
和 ConnectionClass
的控制器以使用新参数启动 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));
}