術語
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