- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我到处搜索这个,我遇到了很多问题,但我不认为这是实际代码的问题。基本上这段代码在两个单独的线程中启动套接字服务器(登录和游戏),我基本上是从非线程版本转换这段代码,但我一直无法让它为线程工作。
include "socket.php";
include "dep.php";
class Server extends Thread {
public $server;
public $config;
public function __construct($type){
//$this->config = (string)$type;
$this->run2($type);
$this->run();
}
public function run(){
while(true){
$this->server->loop();
}
}
public function run2($config){
$this->server = new sokserv($config);
$this->server->init();
//while(true){
// $this->server->loop();
//}
}
}
$login = new Server('Config/config.xml');
$game = new Server("Config/config2.xml");
The error received is
Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in C:\Users\=\Desktop\Test\Start.php:19
Stack trace:
#0 C:\Users\=\Desktop\Test\Start.php(19): Server->run2()
#1 C:\Users\=\Desktop\Test\Start.php(10): Server->run2('Config/config.x...')
#2 C:\Users\=\Desktop\Test\Start.php(26): Server->__construct('Config/config.x...')
#3 {main}
thrown in C:\Users\=\Desktop\Test\Start.php on line 19
但是,恢复到旧代码可以正常工作。sokserv的第一部分(我删除了一些公共(public)变量,因为它们包含个人信息)
class sokserv
{
public $ip;
public $port;
public $users = array();
public $config;
public $mysql;
private $socket;
public function __construct($config = "Config/config.xml")
{
$this->readConfig($config);
}
public function readConfig($file)
{
if (!file_exists($file))
die("Could not find config");
$this->config = simplexml_load_file($file);
}
如果你想要,这是 xml:
<server>
<port>6112</port>
<ip>0</ip>
<mysql>
<host>127.0.0.1</host>
<username>root</username>
<dbname></dbname>
<password></password>
<table></table>
</mysql>
</server>
最佳答案
在 TSRM 的帮助下,Zend 内存管理器专门用于禁止上下文共享数据;没有上下文可以在另一个线程中分配或释放任何东西。这被称为无共享架构,它完全按照 jar 上说的做。 pthread 的工作是以安全、理智的方式突破这个障碍。
显然,与 PHP 捆绑在一起的扩展都不知道 pthreads,我们也不希望它们知道,因为它们只会变得非常复杂。当涉及到其他扩展提供的对象时,pthreads 假设最安全的做法是序列化对象以进行存储。一些对象禁止这种情况发生,SimpleXML后代就是这样一组对象。
从 pthread 派生的字符串、 float 、整数和对象不会被序列化。来自 pthreads 的对象劫持序列化 API,存储对象的物理地址,通过直接访问表示用户空间中对象的线程安全结构来避免序列化。
正确的解决方案是将您希望共享的数据包装在 pthreads 派生的对象中:
<?php
class Config extends Stackable {
/**
* Constructs thread safe, sharable configuration from complex XML
* @param mixed $xml SimpleXMLElement or location of XML file
* @param array &$objects reference store
*/
public function __construct($xml, &$objects) {
if ($xml instanceof SimpleXMLElement) {
foreach ($xml as $key => $value)
$this[$key] = (string) $value;
} else {
foreach (simplexml_load_string(
$xml) as $key => $value) {
if ($value->children()) {
$this[$key] = new Config($value, $objects);
} else $this[$key] = (string) $value;
}
}
/* maintain object references */
$objects[] = $this;
}
public function run() {}
}
class Test extends Thread {
protected $config;
/**
* Constructs thread using pre-constructed thread safe, shared configuration object
* @param Config $config
*/
public function __construct(Config $config) {
$this->config = $config;
}
public function run() {
/* iterate over configuration */
printf("%d settings:\n", count($this->config));
foreach ($this->config as $key => $data) {
if (count($data) > 1) {
printf(
"\t%s, %d settings:\n", $key, count($data));
foreach ($data as $name => $value) {
printf("\t\t%s = %s\n", $name, $value);
}
} else printf("\t%s = %s\n", $key, $data);
}
printf("\n");
printf(
"Host: %s:%d\n",
$this->config->ip,
$this->config->port);
printf(
"MySQL: %s@%s?database=%s&password=%s&table=%s\n",
$this->config->mysql->username,
$this->config->mysql->host,
$this->config->mysql->dbname,
$this->config->mysql->password,
$this->config->mysql->table);
}
}
/* Example XML */
$xml = <<<XML
<server>
<port>6112</port>
<ip>some.ip</ip>
<mysql>
<host>127.0.0.1</host>
<username>root</username>
<dbname>somedb</dbname>
<password>somepass</password>
<table>sometable</table>
</mysql>
</server>
XML;
/* Object reference storage */
$objects = [];
$config = new Config($xml, $objects);
$thread = new Test($config);
$thread->start();
$thread->join();
?>
将输出如下:
3 settings:
port = 6112
ip = some.ip
mysql, 5 settings:
host = 127.0.0.1
username = root
dbname = somedb
password = somepass
table = sometable
Host: some.ip:6112
MySQL: root@127.0.0.1?database=somedb&password=somepass&table=sometable
提供的示例使用您在问题中提供的 [格式] XML,它采用该 XML 并创建它的线程安全表示,永远不会被序列化。
Config 构造函数中的逻辑完全取决于您使用的 XML 格式。
您可以将该 Config 对象传递给任意数量的线程,所有线程都可以读/写属性,并执行它的方法。
您打算共享的所有数据都应该以这种方式管理,您想要从中得到的不是您应该解决异常并尝试存储串行数据,而是您应该为您的数据创建合适的容器,这些容器实际上正确地支持多线程。
关于PHP 线程 SimpleXMLElement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21174603/
SimpleXMLElement 的“addChild”方法似乎应该是正确的选择,但它显然只接受表示新 child 的标记名的字符串。 有用于引用树节点并设置它们的对象式表示法,例如$simpleXM
我有以下 XML: 0 200230455 Promotion 10001599 KFL-20% off N
我正在编写一个 PHP 脚本来生成一些 xml 文档,但我在使用 SimpleXML 和引号时遇到了一些问题。 如果我有这样的代码: $xml = new SimpleXMLElement('');
我有以下 XML: 0 200230455 Promotion 10001599 KFL-20% off N
我正在编写一个 PHP 脚本来生成一些 xml 文档,但我在使用 SimpleXML 和引号时遇到了一些问题。 如果我有这样的代码: $xml = new SimpleXMLElement('');
我做了一个这样的函数: function getFeed($feed_url) { $content = file_get_contents($feed_url); $x = new
每个人都知道我们应该始终使用 DOM 技术而不是正则表达式来从 HTML 中提取内容,但我觉得我永远不能相信 SimpleXML 扩展或类似的扩展。 我现在正在编写一个 OpenID 实现,我尝试使用
我正在尝试在我的 php7 laravel 项目中使用 digital ocean 空间。代码非常简单,只需加载一个文件并将其复制到目录即可。一切都在我的本地机器上工作,但在我的 digital oc
我到处搜索这个,我遇到了很多问题,但我不认为这是实际代码的问题。基本上这段代码在两个单独的线程中启动套接字服务器(登录和游戏),我基本上是从非线程版本转换这段代码,但我一直无法让它为线程工作。 inc
我找到了 ( here) 一个关于删除 SimpleXMLElement 对象节点的方法的答案。 问题是我无法真正理解这是怎么发生的。 我的意思是,$image var 是一个 ref,对吧?那么,$
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
我正在尝试在 Wordpress 中创建一个 Widget,但在创建 SimpleXMLElement 对象时遇到了问题。 代码如下: namespace GenieKnows_Search; cl
我正在尝试访问以下元素中的数字,但无法从中获取值。 echo $object->0; //returns Parse error: syntax error, unexpected T_LNUMBER
我在加载外部 XML 文件时遇到问题。 当我在浏览器中打开它时,一切看起来都很好。我尝试下载 XML 文件并将其上传到我自己的服务器上。当我尝试从我的服务器加载 XML 文件时,一切正常。 有人可以帮
我是第一次使用 SimpleXMLElement,需要在我的 XML 中生成一行,如下所示: 我之前没有对命名空间使用过 addAttribute 并且无法在这里使用正确的语法 - 我已经开始了:
我正在解析一个 Webserivce 响应并且我有一个奇怪的行为, 这是what returns me the WS的一个小例子 输出是用 var_dump($results); 完成的 但如果我这样
我正在查询YouTrack的网络服务以获取问题列表。响应是如下所示的XML: Bug
我正在使用 xpath 解析网页中的文本,但它将它作为对象返回,我如何将其作为字符串返回。 libxml_use_internal_errors(TRUE); $dom = new DOMDocume
如何访问作为数组的 SimpleXMLElement 子项? SimpleXMLElement(9) { name => "John" (11) phone => array(2) [ 0
我有这个: [1]=> object(SimpleXMLElement)#6 (1) { ["@attributes"]=> array(14) { ["name"]=>
我是一名优秀的程序员,十分优秀!