PHP實現真正的非同步MySQL
來源:互聯網
上載者:User
node.js之類的語言可以實現非同步資料庫查詢功能,執行SQL語句之後不必等待資料庫返回結果。繼續去執行其他的代碼,當資料庫返回結果是再對資料進行處理,如渲染頁面,並將HTML頁面發送給用戶端。這樣應用程式完全不需要阻塞等待。這種方式運行效率非常高。
PHP中是否可以實作類別似的非同步非阻塞MySQL查詢呢?使用github搜尋發現一個項目貌似是做此功能的,https://github.com/kaja47/async-mysql,查看代碼是基於React.PHP.的。但並不是真正的非同步SQL。實現的原理是設定一個定時器,每0.02秒輪詢一次。雖然也可以用,但這樣很浪費CPU資源。不是真正的非同步MYSQL。
現在Swoole1.6.2提供了swoole_event_add和swoole_get_mysqli_sock 2個新的函數,使用它完全可以實現真正的PHP非同步MySQL。下面講一下具體的實現。
代碼:
$db = new mysqli;
$db->connect('127.0.0.1', 'root', 'root', 'test');
$db->query("show tables", MYSQLI_ASYNC);
swoole_event_add(swoole_get_mysqli_sock($db), function($db_sock) {
global $db;
$res = $db->reap_async_query();
var_dump($res->fetch_all(MYSQLI_ASSOC));
swoole_event_exit();
});
首先串連mysql,串連成功後執行SQL語句,要在第二個參數指定MYSQLI_ASYNC。表示此查詢為非同步。query函數會立即返回,這時候並沒有得到mysqli_result。
然後調用swoole_get_mysqli_sock函數取到mysql串連的socket,並調用swoole_event_add將它加入到swoole的epoll事件迴圈中。當資料庫返回結果是會回調我們剛才制定的函數。
這時候再調用mysqli_reap_async_query得到result,調用fetch_all函數得到資料。
這個過程是完全非同步非阻塞的,不存在任何浪費CPU的代碼。這個代碼還可以用在伺服器端程式上,具體代碼實現後續會再寫一篇文章詳細介紹。