php變量及參數傳遞

術語
zval容器,符號表,is_ref,refcount,cow,引用分離php

<?php
# 值傳遞
$a =1;    // 一個zval容器
$b=$a;    // 兩個zval容器,因爲cow優化,仍然是一個zval容器
?>

<?php
# cow
$a = 1;
$b =$a;    // cow優化,一個容器
$b=2;    // 寫操做,分離成兩個zval容器了
?>

<?php
# 閉包use值傳遞
$var = 'Hello World';
$func=function ()use($var) {    // 閉包use,值傳遞(copy)
    var_dump($var);        // Hello World
    $var = "new value";    // 閉包內的值修改,不影響閉包外部的變量
};
$func();
var_dump($var);    // 不變,仍然是Hello World
?>

<?php
# 閉包use經過引用改變外部變量
$var = 'Hello World';
$func=function ()use(&$var) {    // 閉包use,試試傳引用
    var_dump($var);    // Hello World
    $var = new stdClass();
};
$func();
var_dump($var);    // 引用發生了做用,輸出object(stdClass)#2 (0) {}

?>

<?php
# 函數傳遞默認是值傳遞,對於對象則使用引用傳遞
$a = new stdClass();
function test($a) {
    $a->b=1;
    var_dump($a);
}
test($a);
var_dump($a);    // $a被改變了,輸出:object(stdClass)#1 (1) {["b"]=>int(1) }
?>

<?php
# swoole下的參數傳遞
class Pool {
    private $_pool;
    public function __construct()
    {
        $this->_pool = new SplQueue();
        $this->_init();
    }
    private function _init(){
        for($i=0;$i<100;$i++) {
            $this->put($i);
        }
    }
    public function get() {
        return $this->_pool->dequeue();
    }
    public function put($item){
        $this->_pool->enqueue($item);
    }
    public function length(){
        return $this->_pool->count();
    }
}
$pool = new Pool();

class Server {
    private $_server;
    private $_pool;
    public function __construct(Pool $_pool)
    {
        $this->_pool = $_pool;
        $this->_server = new Swoole\Http\Server("0.0.0.0", 9500);
        $this->_server->set(
            [
                'worker_num' => 2,
//                'daemonize' => true,    // daemon
                'log_level' => SWOOLE_LOG_INFO,
            ]
        );
        $this->_server->on("request", [$this, "onRequest"]);

        $this->_server->start();
    }
    public function onRequest(\Swoole\Http\Request $request, \Swoole\Http\Response $response)
    {
        echo $this->_pool->get().PHP_EOL;
    }

}

$server = new Server($pool);

# 壓測   ab -c 4 -n 4  http://127.0.0.1:9500/
# 輸出:
#0
#1
#0
#1
# 分析:2個worker,4個併發,共4個請求,因爲進程隔離,$pool對象發生了複製,而不是指望中輸出0/1/2/3

?>

Refer:
http://php.net/manual/en/func...swoole

相關文章
相關標籤/搜索