PHP Pthreads-使用mysqli [英] PHP Pthreads - using mysqli

查看:85
本文介绍了PHP Pthreads-使用mysqli的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Web应用程序中首次使用pthread.我有pthread用于简单的测试用例,但是在使pthread内的mysql查询正常工作时遇到了麻烦.这是我的php文件:

class SqlThread extends Thread
{
    private $dbc;
    public $log;
    public $return;

    public function __construct(){
        $this->dbc = mysqli_connect("localhost", "root", "rootpassword", "my_database");

        $this->log = "<br>(".__LINE__.") construct finished.";
    }

    //gets called when thread is started
    public function run(){
        $val = $this->testSqlCall();

        $this->log .= "<br>(".__LINE__.") testSqlCall() has finished";

        $this->return = $val;
    }

    /**
     * testing sql queries
     */
    function testSqlCall(){

        $sql = "SELECT *
                FROM client_detail";

        $this->log .= "<br>(".__LINE__.") testSqlCall() - sql: ".$sql;

        $r= @mysqli_query($this->dbc,$sql);
        $num = mysqli_affected_rows($this->dbc);

        $this->log .= "<br>(".__LINE__.") testSqlCall() - total number of returned rows: ".$num;

        return $num;

    }
}

/**
 * threaded test
 */
$thread = new SqlThread();
$thread->start();
$thread->join();

echo "<br><br><br>thread return value:";
var_dump($thread->return);
echo $thread->log;

/**
 * same test, but not threaded
 */

$dbc = mysqli_connect("localhost", "root", "rootpassword", "my_database");
$sql = "SELECT *
        FROM client_detail";
$r = @mysqli_query($dbc,$sql);
$num = mysqli_affected_rows($dbc);
echo "<br><br> --- non-threaded return value: $num";

这是它的返回内容:

thread return value:

null


(12) construct finished.
(32) testSqlCall() - sql: SELECT * FROM client_detail
(37) testSqlCall() - total number of returned rows:
(19) testSqlCall() has finished

--- non-threaded return value: 39276

如您所见,SqlThread中的mysqli查询什么都不返回,而SqlThread类之外的完全相同的查询返回了我期望的结果.

有什么想法吗?有没有人在php线程中获得sql查询以起作用?

解决方案

问题是mysqli对象不适合在多个线程中使用,您想为启动的每个线程创建一个MySQLi实例,因此每个线程都有唯一的连接.

<?php
define("SQLHOST", "localhost");
define("SQLUSER", "root");
define("SQLPASS", "");
define("SQLDB",   "test");
define("SQLPORT", 3306);
define("SQLSOCK", "/var/lib/mysql/mysql.sock");

class Mine extends Thread {
    public function run() {
        try {
            $my = new mysqli(SQLHOST, SQLUSER, SQLPASS, SQLDB, SQLPORT, SQLSOCK);
            if ($my) {
                $result = $my->query("SHOW DATABASES;");

                if (is_object($result)) {
                    while (($row = $result->fetch_assoc())) {
                        var_dump($row);
                    }
                }
            }
        } catch(Exception $ex) {
            var_dump($ex);
        }
    }
}

$mine = new Mine();
$mine->start();
?>

收益

array(1) {
  ["Database"]=>
  string(18) "information_schema"
}
array(1) {
  ["Database"]=>
  string(5) "mysql"
}
array(1) {
  ["Database"]=>
  string(18) "performance_schema"
}
array(1) {
  ["Database"]=>
  string(4) "test"
}

请注意,MySQLi对象永远不会存储在Threads对象范围内,因为您应该仅将要共享的对象存储在对象范围内,并且由于不能共享MySQLi连接,因此最好在其中进行操作方法范围.

github上有很多示例,包括一个SQLWorker示例,您应该全部阅读它们.

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

I'm trying to utilize pthreads for the first time in my web application. I have pthreads working for simple test cases, but am having trouble getting mysql queries within pthreads to work. Here's my php file:

class SqlThread extends Thread
{
    private $dbc;
    public $log;
    public $return;

    public function __construct(){
        $this->dbc = mysqli_connect("localhost", "root", "rootpassword", "my_database");

        $this->log = "<br>(".__LINE__.") construct finished.";
    }

    //gets called when thread is started
    public function run(){
        $val = $this->testSqlCall();

        $this->log .= "<br>(".__LINE__.") testSqlCall() has finished";

        $this->return = $val;
    }

    /**
     * testing sql queries
     */
    function testSqlCall(){

        $sql = "SELECT *
                FROM client_detail";

        $this->log .= "<br>(".__LINE__.") testSqlCall() - sql: ".$sql;

        $r= @mysqli_query($this->dbc,$sql);
        $num = mysqli_affected_rows($this->dbc);

        $this->log .= "<br>(".__LINE__.") testSqlCall() - total number of returned rows: ".$num;

        return $num;

    }
}

/**
 * threaded test
 */
$thread = new SqlThread();
$thread->start();
$thread->join();

echo "<br><br><br>thread return value:";
var_dump($thread->return);
echo $thread->log;

/**
 * same test, but not threaded
 */

$dbc = mysqli_connect("localhost", "root", "rootpassword", "my_database");
$sql = "SELECT *
        FROM client_detail";
$r = @mysqli_query($dbc,$sql);
$num = mysqli_affected_rows($dbc);
echo "<br><br> --- non-threaded return value: $num";

and here's what it returns:

thread return value:

null


(12) construct finished.
(32) testSqlCall() - sql: SELECT * FROM client_detail
(37) testSqlCall() - total number of returned rows:
(19) testSqlCall() has finished

--- non-threaded return value: 39276

As you can see, the mysqli query within the SqlThread returns nothing, while the exact same query outside the SqlThread class returns what I would expect.

Any Ideas? Has anyone gotten sql queries within php threads to work?

解决方案

The problem is that the mysqli object is unsuitable for use in multiple threads, you want to create an instance of MySQLi for each thread you start, so each thread has a unique connection.

<?php
define("SQLHOST", "localhost");
define("SQLUSER", "root");
define("SQLPASS", "");
define("SQLDB",   "test");
define("SQLPORT", 3306);
define("SQLSOCK", "/var/lib/mysql/mysql.sock");

class Mine extends Thread {
    public function run() {
        try {
            $my = new mysqli(SQLHOST, SQLUSER, SQLPASS, SQLDB, SQLPORT, SQLSOCK);
            if ($my) {
                $result = $my->query("SHOW DATABASES;");

                if (is_object($result)) {
                    while (($row = $result->fetch_assoc())) {
                        var_dump($row);
                    }
                }
            }
        } catch(Exception $ex) {
            var_dump($ex);
        }
    }
}

$mine = new Mine();
$mine->start();
?>

Yields

array(1) {
  ["Database"]=>
  string(18) "information_schema"
}
array(1) {
  ["Database"]=>
  string(5) "mysql"
}
array(1) {
  ["Database"]=>
  string(18) "performance_schema"
}
array(1) {
  ["Database"]=>
  string(4) "test"
}

Note that, the MySQLi object is never stored in the Threads object scope, because you should only store in the object scope that which you intend to share, and since you cannot share a MySQLi connection, it is best to manipulate it in the method scope.

There are many examples on github, including an SQLWorker example, you should read them all.

Further reading: https://gist.github.com/krakjoe/6437782

这篇关于PHP Pthreads-使用mysqli的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆