摘要:命令行時返回值為,標準輸入輸出均指向終端可用進程號查看。會在腳本執(zhí)行完畢后關閉三個流,無需用戶手動關閉。與遠程網(wǎng)址交互是一個請求和響應的過程,其中細節(jié)可參考本人之前的文章回顧之請求和回顧之響應,也可參考協(xié)議的權威文檔。
轉載請注明文章出處: https://tlanyan.me/php-review...PHP回顧系列目錄
PHP基礎
web請求
cookie
web響應
session
數(shù)據(jù)庫操作
加解密
Composer
創(chuàng)建自己的Composer包
發(fā)送郵件
無論哪種編程語言,IO操作都值得好好學習和理解。由于PHP簡單的特性,不少人對此毫無概念也能寫出可用的代碼。本文總結PHP開發(fā)中幾個常見的IO場景并介紹對應的操作,希望能幫助PHP開發(fā)人員加深對IO的理解。后續(xù)文章中將介紹隱藏在簡單之下的本質:流。
本文介紹的場景包括:讀寫文件、命令行輸入輸出、與遠程網(wǎng)址交互。廢話少說,直接開始吧!
讀寫文件文件的讀寫是最常規(guī)的IO操作。打開文件、讀寫內容、關閉文件,一氣呵成,沒什么尿點。一個典型的讀取文件內容例子:
function getFileContent(string $filename) : ?string { if (!is_file($filename)) { return null; } $fd = fopen($filename, "rb"); $content = fread($fd, filesize($filename); fclose($fd); return $content; }
讀寫文件So easy! 要想對文件操作玩得更高端點,至少需要熟練使用這些API:
file_exists/is_file/filesize/fileperms等獲取文件信息的輔助函數(shù);
fopen:打開文件,獲取文件句柄,第二個參數(shù)(arwcbx)的含義要弄清楚;
flock:獲取文件鎖,可用其實現(xiàn)進程互斥鎖;
fread/fgets/fscanf等獲取文件內容的函數(shù);
fwrite/fputs/fputcsv/ftruncate等寫入內容函數(shù);
feof/ftell/fseek/rewind等操作文件指針位置的函數(shù);
fclose: 關閉文件,釋放資源。
注意本節(jié)中的文件指是 本地文件,對于遠程文件,上述函數(shù)是否起作用取決于協(xié)議是否提供支持。例如fread/fwrite可以操作http://協(xié)議的資源,但stat/filesize等函數(shù)不能正常工作??蓞⒖脊倬W(wǎng)的“協(xié)議和包裝器” 查看非本地普通文件時可用的函數(shù)信息。
命令行輸入和輸出PHP主要用于web開發(fā),命令行應用也比較常見,比如定時任務的腳本。命令行模式下,有不少與web開發(fā)不同的地方,比如可以使用多進程/線程(web中的curl_multiple不算),沒有運行時間限制等。
命令行時php_sapi_name返回值為cli,標準輸入輸出均指向終端(可用ll /proc/進程號/fd查看)。PHP定義了三個句柄常量:
STDIN: 標準輸入,只讀,等同于用fopen打開"php://stdin";
STDOUT: 標準輸出,只寫,等同于用fopen打開"php://stdout";
STDERR: 標準錯誤輸出,只寫,等同于fopen打開"php://stderr"。
注意標準輸入對應"php://stdin"而非"php://input",雖然這兩者行為在命令行模式下幾乎一致(區(qū)別可參考本人之前的文章php://output和php://stdout的區(qū)別)。
操作三個讀寫通道,對應的函數(shù)是fread/fgetc/fscanf/fwrite/fputc/fputs等。PHP會在腳本執(zhí)行完畢后關閉三個流,無需用戶手動關閉。下面用代碼簡要展示用法:
function prompt(string $message) : string { fwrite(STDOUT, $message); // fgets會把換行符也讀入,可用rtrim過濾掉 return rtrim(fgets(STDIN)); } function println(string $message) : void { fputs(STDOUT, $message . PHP_EOL); } function error(string $message) : void { fputs(STDERR, $message . PHP_EOL); } $value = prompt("input your value:"); if ($value !== "") { println("your input: $value"); } else { error("invalid value!"); }
命令行模式時"php://output"鏈接到標準輸出,所以echo/print/var_dump等輸出函數(shù)可正常使用。要交互式的從命令行獲取輸入,則需要用到fread/fgets等文件讀取函數(shù)。
常量PHP_EOL是預定義的跨平臺換行符,EOL是end of line的縮寫,不是end of life~
與遠程網(wǎng)址交互從網(wǎng)頁獲取內容,cURL拓展絕對值得大提特提。如果你熟悉curl命令,對其功能的強大應該有所了解,那么應該對使用PHP中的CURL系列函數(shù)會得心應手。
與遠程網(wǎng)址交互是一個請求和響應的過程,其中細節(jié)可參考本人之前的文章:PHP回顧之web請求和PHP回顧之web響應,也可參考HTTP協(xié)議的權威文檔。使用CURL與遠程web服務器的交互流程如下:
初始化CURL句柄
設置請求信息:請求URL、頭部信息、cookie、正文等;
發(fā)送請求
獲取執(zhí)行結果
關閉CURL句柄,釋放資源
CURL簡單好用,缺點是請求的設置參數(shù)繁雜難記。
實踐中推薦以類Java的HttpClient庫形式與遠程服務器交互。HttpClient類庫將請求、響應、傳輸?shù)雀拍畛槌鰜?,完全面向對象,更語義化,使用其能更好促進對HTTP協(xié)議的理解,缺點是代碼相對繁瑣。PHP有不少類似的HTTP請求庫,以下使用Yii2中的yii2-httpclient類庫展示使用示例:
use yiihttpclientClient; use yiihttpclientResponse; $url = "https://tlanyan.me"; $data = [ "key1" => "value1", "key2" => "value2", ]; $response = (new Client())->createRequest() ->setMethod("POST") ->setFormat(Client::FORMAT_JSON) ->setUrl($url) ->setData($data) ->send(); if ($response->isOk) { $response->setFormat(Client::FORMAT_JSON); // 獲取解析后的數(shù)據(jù) $data = $response->data; .... }
使用fopen/fsocketopen等函數(shù)也能實現(xiàn)與遠程服務器的交互,這部分內容放在后續(xù)的流中闡述。
file_get_contents上文廢話了半天,還沒說到PHP中獲取內容的神器:file_get_contents函數(shù)。該函數(shù)是PHP讀取內容當之無愧的神器,不管是常規(guī)文件、php://、http://、還是標準輸入等,file_get_contents一句話搞定。相較于Java等語言中的client/connection/stream等一堆代碼,file_get_contents體現(xiàn)了PHP簡單實用的設計哲學。
想必PHP開發(fā)常用該函數(shù),就用幾個簡單的示例結束本文(注意代碼中POST請求網(wǎng)頁已經(jīng)涉及到了流的內容)。
// 讀取普通文件 file_get_contents("/etc/passwd"); // 獲取web請求的原始正文,可獲取json/xml等數(shù)據(jù)格式的原始內容,也可獲得上傳文件的內容,注意該返回可能唯二進制 // 以json/xml數(shù)據(jù)格式交互時,推薦使用此方法而非通過$GLOBALS["HTTP_RAW_POST_DATA"]獲取,$HTTP_RAW_POST_DATA在PHP 7.2中已被移除 file_get_contents("php://input"); // 獲取網(wǎng)址內容,可取代curl file_get_contents("https://tlanyan.me"); // 傳入context對象,可實現(xiàn)post請求 $contextOptions = [ "http" => [ "method" => "POST", "ignore_errors" => true, "content" => "username=tlanyan", "header" => "Content-type: application/x-www-form-urlencoded", "user_agent" => "MySpider/1.0", ], "ssl" => [ "verify_peer" => false, ], ]; $context = stream_context_create($contextOptions); file_get_contents("https://tlanyan.me", false, $context); // cli模式下從標準輸入讀取數(shù)據(jù),此時換行符也被當做輸入的一部分,要以ctrl+d作為結束輸入的標志 file_get_contents(STDIN); // 寫入文件內容 file_put_contents("foo.txt", "Test function call ", FILE_APPEND);參考
http://php.net/manual/en/ref....
http://php.net/manual/en/feat...
http://php.net/manual/en/book...
https://github.com/yiisoft/yi...
感謝閱讀,感謝指正!
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/30726.html
摘要:本文先回顧生成器,然后過渡到協(xié)程編程。其作用主要體現(xiàn)在三個方面數(shù)據(jù)生成生產者,通過返回數(shù)據(jù)數(shù)據(jù)消費消費者,消費傳來的數(shù)據(jù)實現(xiàn)協(xié)程。解決回調地獄的方式主要有兩種和協(xié)程。重點應當關注控制權轉讓的時機,以及協(xié)程的運作方式。 轉載請注明文章出處: https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎 web請求 cookie web響應 sess...
摘要:通過,腳本層無需過多考慮執(zhí)行的具體環(huán)境,而本身則可以讓針對自己的特點給出特有實現(xiàn)。模式下,也只執(zhí)行一次。這幾個概念的關系如下網(wǎng)關協(xié)議,與語言無關,所以與關系也不大。總結本文簡要回顧了程序的架構和執(zhí)行流程,并對幾個容易混淆概念做了介紹。 轉載請注明文章出處:https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎 web請求 cookie we...
摘要:如果你想體驗原味編程,用開頭的比較適合否則建議使用流函數(shù)。有關流的知識,請參考本人之前的博文回顧之流。接下來我們用流函數(shù)實現(xiàn)一個簡單的客戶端和服務端。流函數(shù)中的和兩個函數(shù)是我們想要的。本文目的是簡要介紹中的編程,行文到此已經(jīng)達到目的。 轉載請注明文章出處: https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎 web請求 cookie w...
摘要:多進程中與多進程相關的兩個重要拓展是和。函數(shù)執(zhí)行期間,主進程除了等待無法處理其他任務,所以一般不認為這是多進程編程?;厥兆舆M程有兩種方式,一種是主進程調用函數(shù)等待子進程結束另外一種是處理信號。 轉載請注明文章出處: https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎 web請求 cookie web響應 session 數(shù)據(jù)庫操作 加解...
閱讀 1689·2021-11-15 11:37
閱讀 3422·2021-09-28 09:44
閱讀 1662·2021-09-07 10:15
閱讀 2799·2021-09-03 10:39
閱讀 2697·2019-08-29 13:20
閱讀 1304·2019-08-29 12:51
閱讀 2214·2019-08-26 13:44
閱讀 2131·2019-08-23 18:02