PHP pthreads,类没有在Thread实例中加载,也没有设置参数

时间:2014-02-26 21:12:42

标签: php facebook multithreading pthreads

我正在利用pthreads来同时发布Facebook API。

我创建了一个范围并且以结构化方式运行良好,但是使用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?或者设置已经实例化的类的参数,就像在实例化并作为参数传递的线程之外的情况一样。

感谢。

1 个答案:

答案 0 :(得分:1)

以下是一些示例代码,可帮助您了解正在发生的事情......

<?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);
?>

在Thread中实例化对象不是问题,问题是您正在尝试操纵多个上下文中不是线程安全的对象。 Facebook对象显然不是线程安全的,你可以从上面的例子中看到,只是从pthreads下降使得该类的任何对象都可以安全地在多个上下文中使用,这些对象会表现出预期的行为。

github上有很多例子,你应该全部阅读。

进一步阅读:https://gist.github.com/krakjoe/6437782