摘要:命令行時返回值為,標(biāo)準(zhǔn)輸入輸出均指向終端可用進(jìn)程號查看。會在腳本執(zhí)行完畢后關(guān)閉三個流,無需用戶手動關(guān)閉。與遠(yuǎn)程網(wǎng)址交互是一個請求和響應(yīng)的過程,其中細(xì)節(jié)可參考本人之前的文章回顧之請求和回顧之響應(yīng),也可參考協(xié)議的權(quán)威文檔。
轉(zhuǎn)載請注明文章出處: https://tlanyan.me/php-review...PHP回顧系列目錄
PHP基礎(chǔ)
web請求
cookie
web響應(yīng)
session
數(shù)據(jù)庫操作
加解密
Composer
創(chuàng)建自己的Composer包
發(fā)送郵件
無論哪種編程語言,IO操作都值得好好學(xué)習(xí)和理解。由于PHP簡單的特性,不少人對此毫無概念也能寫出可用的代碼。本文總結(jié)PHP開發(fā)中幾個常見的IO場景并介紹對應(yīng)的操作,希望能幫助PHP開發(fā)人員加深對IO的理解。后續(xù)文章中將介紹隱藏在簡單之下的本質(zhì):流。
本文介紹的場景包括:讀寫文件、命令行輸入輸出、與遠(yuǎn)程網(wǎng)址交互。廢話少說,直接開始吧!
讀寫文件文件的讀寫是最常規(guī)的IO操作。打開文件、讀寫內(nèi)容、關(guān)閉文件,一氣呵成,沒什么尿點。一個典型的讀取文件內(nèi)容例子:
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)進(jìn)程互斥鎖;
fread/fgets/fscanf等獲取文件內(nèi)容的函數(shù);
fwrite/fputs/fputcsv/ftruncate等寫入內(nèi)容函數(shù);
feof/ftell/fseek/rewind等操作文件指針位置的函數(shù);
fclose: 關(guān)閉文件,釋放資源。
注意本節(jié)中的文件指是 本地文件,對于遠(yuǎn)程文件,上述函數(shù)是否起作用取決于協(xié)議是否提供支持。例如fread/fwrite可以操作http://協(xié)議的資源,但stat/filesize等函數(shù)不能正常工作??蓞⒖脊倬W(wǎng)的“協(xié)議和包裝器” 查看非本地普通文件時可用的函數(shù)信息。
命令行輸入和輸出PHP主要用于web開發(fā),命令行應(yīng)用也比較常見,比如定時任務(wù)的腳本。命令行模式下,有不少與web開發(fā)不同的地方,比如可以使用多進(jìn)程/線程(web中的curl_multiple不算),沒有運行時間限制等。
命令行時php_sapi_name返回值為cli,標(biāo)準(zhǔn)輸入輸出均指向終端(可用ll /proc/進(jìn)程號/fd查看)。PHP定義了三個句柄常量:
STDIN: 標(biāo)準(zhǔn)輸入,只讀,等同于用fopen打開"php://stdin";
STDOUT: 標(biāo)準(zhǔn)輸出,只寫,等同于用fopen打開"php://stdout";
STDERR: 標(biāo)準(zhǔn)錯誤輸出,只寫,等同于fopen打開"php://stderr"。
注意標(biāo)準(zhǔn)輸入對應(yīng)"php://stdin"而非"php://input",雖然這兩者行為在命令行模式下幾乎一致(區(qū)別可參考本人之前的文章php://output和php://stdout的區(qū)別)。
操作三個讀寫通道,對應(yīng)的函數(shù)是fread/fgetc/fscanf/fwrite/fputc/fputs等。PHP會在腳本執(zhí)行完畢后關(guān)閉三個流,無需用戶手動關(guān)閉。下面用代碼簡要展示用法:
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"鏈接到標(biāo)準(zhǔn)輸出,所以echo/print/var_dump等輸出函數(shù)可正常使用。要交互式的從命令行獲取輸入,則需要用到fread/fgets等文件讀取函數(shù)。
常量PHP_EOL是預(yù)定義的跨平臺換行符,EOL是end of line的縮寫,不是end of life~
與遠(yuǎn)程網(wǎng)址交互從網(wǎng)頁獲取內(nèi)容,cURL拓展絕對值得大提特提。如果你熟悉curl命令,對其功能的強大應(yīng)該有所了解,那么應(yīng)該對使用PHP中的CURL系列函數(shù)會得心應(yīng)手。
與遠(yuǎn)程網(wǎng)址交互是一個請求和響應(yīng)的過程,其中細(xì)節(jié)可參考本人之前的文章:PHP回顧之web請求和PHP回顧之web響應(yīng),也可參考HTTP協(xié)議的權(quán)威文檔。使用CURL與遠(yuǎn)程web服務(wù)器的交互流程如下:
初始化CURL句柄
設(shè)置請求信息:請求URL、頭部信息、cookie、正文等;
發(fā)送請求
獲取執(zhí)行結(jié)果
關(guān)閉CURL句柄,釋放資源
CURL簡單好用,缺點是請求的設(shè)置參數(shù)繁雜難記。
實踐中推薦以類Java的HttpClient庫形式與遠(yuǎn)程服務(wù)器交互。HttpClient類庫將請求、響應(yīng)、傳輸?shù)雀拍畛槌鰜恚耆嫦驅(qū)ο?,更語義化,使用其能更好促進(jìn)對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)與遠(yuǎn)程服務(wù)器的交互,這部分內(nèi)容放在后續(xù)的流中闡述。
file_get_contents上文廢話了半天,還沒說到PHP中獲取內(nèi)容的神器:file_get_contents函數(shù)。該函數(shù)是PHP讀取內(nèi)容當(dāng)之無愧的神器,不管是常規(guī)文件、php://、http://、還是標(biāo)準(zhǔn)輸入等,file_get_contents一句話搞定。相較于Java等語言中的client/connection/stream等一堆代碼,file_get_contents體現(xiàn)了PHP簡單實用的設(shè)計哲學(xué)。
想必PHP開發(fā)常用該函數(shù),就用幾個簡單的示例結(jié)束本文(注意代碼中POST請求網(wǎng)頁已經(jīng)涉及到了流的內(nèi)容)。
// 讀取普通文件 file_get_contents("/etc/passwd"); // 獲取web請求的原始正文,可獲取json/xml等數(shù)據(jù)格式的原始內(nèi)容,也可獲得上傳文件的內(nèi)容,注意該返回可能唯二進(jìn)制 // 以json/xml數(shù)據(jù)格式交互時,推薦使用此方法而非通過$GLOBALS["HTTP_RAW_POST_DATA"]獲取,$HTTP_RAW_POST_DATA在PHP 7.2中已被移除 file_get_contents("php://input"); // 獲取網(wǎng)址內(nèi)容,可取代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模式下從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù),此時換行符也被當(dāng)做輸入的一部分,要以ctrl+d作為結(jié)束輸入的標(biāo)志 file_get_contents(STDIN); // 寫入文件內(nèi)容 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...
感謝閱讀,感謝指正!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/30726.html
摘要:本文先回顧生成器,然后過渡到協(xié)程編程。其作用主要體現(xiàn)在三個方面數(shù)據(jù)生成生產(chǎn)者,通過返回數(shù)據(jù)數(shù)據(jù)消費消費者,消費傳來的數(shù)據(jù)實現(xiàn)協(xié)程。解決回調(diào)地獄的方式主要有兩種和協(xié)程。重點應(yīng)當(dāng)關(guān)注控制權(quán)轉(zhuǎn)讓的時機,以及協(xié)程的運作方式。 轉(zhuǎn)載請注明文章出處: https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎(chǔ) web請求 cookie web響應(yīng) sess...
摘要:通過,腳本層無需過多考慮執(zhí)行的具體環(huán)境,而本身則可以讓針對自己的特點給出特有實現(xiàn)。模式下,也只執(zhí)行一次。這幾個概念的關(guān)系如下網(wǎng)關(guān)協(xié)議,與語言無關(guān),所以與關(guān)系也不大??偨Y(jié)本文簡要回顧了程序的架構(gòu)和執(zhí)行流程,并對幾個容易混淆概念做了介紹。 轉(zhuǎn)載請注明文章出處:https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎(chǔ) web請求 cookie we...
摘要:如果你想體驗原味編程,用開頭的比較適合否則建議使用流函數(shù)。有關(guān)流的知識,請參考本人之前的博文回顧之流。接下來我們用流函數(shù)實現(xiàn)一個簡單的客戶端和服務(wù)端。流函數(shù)中的和兩個函數(shù)是我們想要的。本文目的是簡要介紹中的編程,行文到此已經(jīng)達(dá)到目的。 轉(zhuǎn)載請注明文章出處: https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎(chǔ) web請求 cookie w...
摘要:多進(jìn)程中與多進(jìn)程相關(guān)的兩個重要拓展是和。函數(shù)執(zhí)行期間,主進(jìn)程除了等待無法處理其他任務(wù),所以一般不認(rèn)為這是多進(jìn)程編程?;厥兆舆M(jìn)程有兩種方式,一種是主進(jìn)程調(diào)用函數(shù)等待子進(jìn)程結(jié)束另外一種是處理信號。 轉(zhuǎn)載請注明文章出處: https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎(chǔ) web請求 cookie web響應(yīng) session 數(shù)據(jù)庫操作 加解...
閱讀 1738·2021-11-15 11:37
閱讀 3484·2021-09-28 09:44
閱讀 1739·2021-09-07 10:15
閱讀 2858·2021-09-03 10:39
閱讀 2754·2019-08-29 13:20
閱讀 1359·2019-08-29 12:51
閱讀 2270·2019-08-26 13:44
閱讀 2186·2019-08-23 18:02