線程是我們在做項目中首要考慮的,在php中怎麼實現線程呢,我們這裡就看看PHP線程的實現。許多 PHP 開發人員認為,由於標准的 PHP 缺少線程功能,因此實際 PHP 應用程序不可能執行多任務處理。
例如,如果應用程序需要其他 Web 站點的信息,那麼在遠程檢索完成之前它都必須停止。這是錯誤的!通過本文了解如何使用 stream_select 和 stream_socket_client 實現進程內 PHP 多任務處理。PHP 不支持線程。盡管如此,與前述大多數 PHP 開發人員所相信的想法形成對比的是,PHP 應用程序可以 執行多任務處理。讓我們開始盡可能清晰地描述一下 “多任務” 和 “線程” 對於 PHP 編程的意義。
PHP線程並發的種類
首先拋開幾個和主題無關的例子。PHP 與多任務或並發的關系十分復雜。在較高層次上,PHP 經常涉及多任務:以多任務方式使用 標准的服務器端 PHP 安裝 —— 例如,作為 Apache 模塊。換句話說,若干個客戶機 —— Web 浏覽器 —— 可以同時請求同一個 PHP 解釋的頁面,而 Web 服務器將差不多同時返回所有這些頁面。
一個 Web 頁面不會妨礙其他 Web 頁面的發送,盡管可能會由於諸如服務器內存或網絡帶寬之類的受限資源而使它們相互之間略有妨礙。這樣,實現並發 的系統級需求可能適合使用基於 PHP 的解決方案。就實現而言,PHP 允許它的管理 Web 服務器負責實現並發。
Ajax 名下的客戶端並發近幾年來也已成為開發人員關注的焦點。雖然 Ajax 的含義已經變得十分模糊,但是它的一個方面是浏覽器顯示可以同時執行計算和保留對諸如選擇菜單項之類的用戶操作的響應。這實際上就是某種 多任務。用 PHP 編碼的 Ajax 就是這樣 —— 但是不涉及任何特定的 PHP;用於其他語言的 Ajax 框架均以完全相同的方法操作。
只粗略地涉及 PHP 的第三個並發實例是 PHP/TK。PHP/TK 是 PHP 的擴展,用於為核心 PHP 提供可移植圖形用戶界面(GUI)綁定。PHP/TK 允許用 PHP 編寫代碼構造桌面 GUI 應用程序。其基於事件的特性將模擬一種易於掌握並且比線程更少出錯的並發形式。此外,並發是 “繼承” 自一項輔助技術,而不是 PHP 的基本功能。
第一個示例PHP線程新的 stream_select 函數及它的幾個助手使這成為可能。請考慮以下示例。
清單 1. 同時請求多個 HTTP 頁面
- <?php
- echo "Program starts at ". date('h:i:s') . ".n";
- $timeout=10;
- $result=array();
- $sockets=array();
- $convenient_read_block=8192;
- /* Issue all requests simultaneously; there's no blocking. */
- $delay=15;
- $id=0;
- while ($delay > 0) {
- $s=stream_socket_client("phaseit.net:80", $errno,
- $errstr, $timeout,
- STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
- if ($s) {
- $sockets[$id++]=$s;
- $http_message="GET /demonstration/delay?delay=" .
- $delay . " HTTP/1.0rnHost: phaseit.netrnrn";
- fwrite($s, $http_message);
- } else {
- echo "Stream " . $id . " failed to open correctly.";
- }
- $delay -= 3;
- }
- while (count($sockets)) {
- $read=$sockets;
- stream_select($read, $w=null, $e=null, $timeout);
- if (count($read)) {
- /* stream_select generally shuffles $read, so we need to
- compute from which socket(s) we're reading. */
- foreach ($read as $r) {
- $id=array_search($r, $sockets);
- $data=fread($r, $convenient_read_block);
- /* A socket is readable either because it has
- data to read, OR because it's at EOF. */
- if (strlen($data) == 0) {
- echo "Stream " . $id . " closes at " . date('h:i:s') . ".n";
- fclose($r);
- unset($sockets[$id]);
- } else {
- $result[$id] .= $data;
- }
- }
- } else {
- /* A time-out means that *all* streams have failed
- to receive a response. */
- echo "Time-out!n";
- break;
- }
- }
- ?>
如果運行此清單,您將看到如下所示的輸出。