PHP pthreads,类不会被加载到线程实例中,也不会设置参数
问题描述:
我正在利用pthreads来做同步发布的Facebook API。PHP pthreads,类不会被加载到线程实例中,也不会设置参数
我创建了一个范围,并以结构化的方式运行良好,但使用pthreads似乎无法设置API的参数。
而当调用API的实例时什么都不做。
有人可以帮我解决这个问题,最实际的解决方案是什么。
我有2个文件。一个文件被cron调用来不时运行该进程,并开始处理线程。
<?php require_once("../../../Connections/sys_config.php"); // external functions
require_once("../../inc/lib/facebook.php"); //include sdk
require_once('cron.class.php'); // thread class
set_time_limit(0);
// API DATA
$appId = 'XXXXXXXX'; //Facebook App ID
$appSecret = 'XXXXXXXX'; // Facebook App Secret
//Call Facebook API
// I instantiate the call to api facebook here because I can not do within the thread
try {
$facebook = new Facebook(array(
'appId' => $appId,
'secret' => $appSecret,
'fileUpload' => true,
'cookie' => true,
));
} catch (Exception $e) {
var_dump($e->getMessage());
}
// Fetch the schedule according to the time set by the User
$fb_loadCronPostSYS = fb_loadCronPostSYS($time);
// with results continues
if($fb_loadCronPostSYS['totalReg'] > 0) {
// Create a array
$stack = array();
//Iniciate Multiple Thread
foreach ($fb_loadCronPostSYS['dados'] as $i) {
$stack[] = new apiSEND($i, $facebook);
}
// Start The Threads
foreach ($stack as $t) {
$t->start();
}
} else {
// does nothing
} ?>
在这里我运行线程。实际上,因为我不能在线程内设置access_token,所以我没有向API发送数据。
<?php
define("SQL_HOST", "localhost");
define("SQL_USER", "xxxx");
define("SQL_PASS", "xxxx");
define("SQL_DB", "xxxx");
// I am using sql class to make calls to mysql
class sql {
public static $connection;
public static function __callstatic($method, $args){
if (self::$connection) {
return call_user_func_array(array(self::$connection, $method), $args);
} else {
self::$connection = new mysqli(SQL_HOST, SQL_USER, SQL_PASS, SQL_DB);
if (self::$connection)
return call_user_func_array(array(self::$connection, $method), $args);
}
}
}
class apiSEND extends Thread {
public $data, $appId, $appSecret;
public function __construct($arg, $facebook) {
$this->cad_datetime = date('Y-m-d H:i:s');
// $arg is array with the User data and publication that will be taken by the Facebook API
$this->fb_loadCronPostSYS = $arg;
$this->user_id = $this->fb_loadCronPostSYS['fb_id'];
}
public function run() {
if ($this->user_id) {
printf("%s is Thread #%lu\n", __CLASS__, $this->getThreadId());
// efetua a conexao com o access_token do BD, se precisar renova o access_token
$accessToken = $this->fb_loadCronPostSYS['dados']['fb_access_token'];
$this->facebook->setAccessToken($accessToken);
// pega os dados da api
try {
$fbuser = $this->facebook->getUser();
$user_profile = $this->facebook->api('/me'); //user profile
$user_permissions = $this->facebook->api("/me/permissions"); //list of user permissions
} catch (FacebookApiException $e) {
error_log($e);
$fbuser = null;
}
echo 'fbuser:' . $fbuser;
print_r($user_profile);
print_r($user_permissions);
// faz as publicacoes
if($fbuser) {
// envia para API
$post_msg = post_msg('message that will be posted', 'page that will be posted');
sleep($tempo);
}
}
}
} // fecha run
?>
请任何帮助。
如何实例化线程内的clases?或者像在实例化并作为参数传递的线程之外的情况那样设置已经实例化的类的参数。
谢谢。
答
下面是一些示例代码,应该帮助您了解正在发生的事情...
<?php
class Bookface {
protected $uid;
public function __construct($uid) {
$this->uid = $uid;
}
public function fetch() {
return file_get_contents(
"http://www.google.com/?q={$this->uid}");
}
public function getUID() { return $this->uid; }
public function setUID($uid) { $this->uid = $uid; }
}
/* the same class again, safely ... */
class Safeface extends Stackable {
protected $uid;
public function __construct($uid) {
$this->uid = $uid;
}
public function fetch() {
return file_get_contents(
"http://www.google.com/?q={$this->uid}");
}
public function getUID() { return $this->uid; }
public function setUID($uid) { $this->uid = $uid; }
public function run(){}
}
class Bookwork extends Thread {
protected $bookface;
protected $safeface;
public function __construct(Bookface $bookface, Safeface $safeface) {
$this->bookface = $bookface;
$this->safeface = $safeface;
}
public function run() {
var_dump(
$this->bookface,
$this->safeface);
/*
* This will not work, the object is not thread safe
*/
$this->bookface->setUID(100);
/*
* This will work, the object is thread safe
*/
$this->safeface->setUID(200);
var_dump(
$this->bookface, /* this will be unchanged */
$this->safeface); /* this will reflect changes */
}
}
$faces = [new Bookface(1), new Safeface(2)];
$thread = new Bookwork($faces[0], $faces[1]);
$thread->start();
$thread->join();
/*
* Changes made to safeface will be visible here
*/
var_dump($faces);
?>
线程中实例化对象是没有问题的,问题是,你正试图操纵对象在多个上下文中不是线程安全的。 Facebook对象显然不会是线程安全的,从上面的例子可以看出,仅从pthreads降序使得该类的任何对象都可以安全地在多个上下文中使用,然后这些对象展现出预期的行为。
github上有很多例子,你应该阅读它们。
嗨乔,感谢您的回复。 但我遇到了Zend模块的问题,这可以在论坛cPanel中给一个检查帖子。支持人员cPanel正在帮助我,但也没有发现问题,并说我应该寻求Zend的支持。你怎么看? http://forums.cpanel.net/f442/how-install-php-pthreads-zts-387252.html 我在论坛上的用户名和这里一样。 (sourceforge的) – SourceForge