作者:Armel Fauveau
原文地址:http://www.phpbuilder.net/columns/armel20010427.php3
PHP能够打开远程或者本地服务器的sockets!这里是一个使用socket的简单的例子:连接到Usenet的新闻服务器,与服务器沟通,并从一个精确的新闻分组中下载一些文章。
使用PHP打开Socket
使用fsockopen()来打开一个Socket。这个函数在PHP3和PHP4中都存在。函数的原型如下:
intfsockopen
(string hostname,
int port [,
int errno [,
string errstr [,
double timeout]]])
?>
对于网络主机,它将建立一个TCP的Socket的连接到主机名的端口上。主机名可以是域名或者IP地址。对于UDP连接,你需要明确指出其协议:udp://hostname。对于unix主机,主机名将在socket的路径中使用,在这个例子中端口必须设置成0。可选项timeout可以用来设置连接超时的秒数。
关于fsockopen()的更多信息可以访问http://www.php.net/manual/function.fsockopen.php
网络新闻传输协议(NNTP)
访问一个usenet新闻服务器需要用到一个特别的协议,称作NNTP,即网络新闻传输协议标准。这个协议的详细资料在RFC977中,你可以在http://www.w3.org/Protocols/rfc977/rfc977.html中查看到。这个文档详细的描述了如何使用不同的命令来连接并且和NNTP服务器对话。
连接服务器
连接到NNTP服务器需要知道服务器的主机名(或者IP地址)和它将要监听的端口。另外建议你加上一个超时的时间,这样连接失败的时候就不会“冻结”程序。
$cfgServer = "your.news.host";
$cfgPort = 119;
$cfgTimeOut = 10;
// open asocket
if(!$cfgTimeOut)
// without timeout
$usenet_handle = fsockopen($cfgServer, $cfgPort);
else
// with timeout
$usenet_handle = fsockopen($cfgServer, $cfgPort, &$errno, &$errstr, $cfgTimeOut);
if(!$usenet_handle) {
echo"Connexionfailed\n";
exit();
}
else {
echo"Connected\n";
$tmp = fgets($usenet_handle, 1024);
}
?>
与服务器交互
现在我们已经连接上服务器了,而且能够通过先前打开的socket连接与服务器进行交互。让我们对服务器说“我们要从某一新闻分组中获取到最新的10篇文章”。RFC977定义了如何选择正确的新闻分组的命令,如下:
GROUPggg
必需的参数ggg是你将要选择的新闻分组的名字,比如net.news。使用list命令你可以获取到一组有效的新闻列表。成功选择响应会返回组中首尾两篇新闻的新闻号以及对存档新闻号估计。
比如
chrome:~$ telnetmy.news.host 119
Trying aa.bb.cc.dd...
Connected tomy.news.host.
Escape character is'^]'.
200 my.news.hostInterNetNews NNRP server INN 2.2.2 13-Dec-1999 ready (posting ok).
GROUP alt.test
211 232 222996 223235alt.test
quit
205 .
在接受到命令“GROUP alt.test”,新闻服务器返回了“211232 222996 223235 alt.test”。其中211是RFC标识码(简单的解释说命令已经成功的执行—查看RFC你可以获取更加详细的资料),返回信息说明其中有232篇文章,其中最旧的新闻的索引号是222996,而最新的新闻索引号是223235。现在让我们计算下:222996+232并不等于232235。这丢失的文章或者从这服务器移除出去了,或者被他的作者取消了(是的,这是可能的,也是很容易实现的),或者是删除了。
小心起见,在选择新闻分组之前,服务器可能需要认证,当然这是由服务器是否公开或者私有来决定的。一般是允许任何人获取新闻,但发表新闻需要通过认证。
//$cfgUser = "xxxxxx";
//$cfgPasswd = "yyyyyy";
$cfgNewsGroup = "alt.php";
// identification required on private server
if($cfgUser) {
fputs($usenet_handle, "AUTHINFO USER".$cfgUser."\n");
$tmp = fgets($usenet_handle, 1024);
fputs($usenet_handle, "AUTHINFO PASS ".$cfgPasswd."\n");
$tmp = fgets($usenet_handle, 1024);
// check error
if($tmp != "281Ok\r\n") {
echo "502Authentication error\n";
exit();
}
}
// select newsgroup
fputs($usenet_handle, "GROUP ".$cfgNewsGroup."\n");
$tmp = fgets($usenet_handle, 1024);
if($tmp == "480 Authentication required for command\r\n") {
echo "$tmp\n";
exit();
}
$info = split(" ", $tmp);
$first = $info[2];
$last = $info[3];
print "First : $first\n";
print "Last : $last\n";
?>
获取一些文章
现在我们已经有最新文章的A索引号,那就能很容易的获取最新的十篇文章。RFC977指出使用ARTICLE命令可以和文章的索引号或者消息的ID一起使用。为了小心起见,在这里,文章的索引号和消息ID是不同的,因为每个新闻服务器定义不同,所以在不同的新闻服务器上相同文章的索引号都会不一样的,但是消息ID好是唯一的(包含在文章的头部中)
$cfgLimit = 10;
// upload last articles
$boucle=$last-$cfgLimit;
while ($boucle set_time_limit(0);
fputs($usenet_handle, "ARTICLE$boucle\n");
$article="";
$tmp = fgets($usenet_handle, 4096);
if(substr($tmp,0,3) != "220") {
echo "+----------------------+\n";
echo "Error onarticle $boucle\n";
echo "+----------------------+\n";
}
else {
while($tmp!=".\r\n") {
$tmp = fgets($usenet_handle, 4096);
$article = $article.$tmp;
}
echo "+----------------------+\n";
echo "Article$boucle\n";
echo "+----------------------+\n";
echo "$article\n";
}
$boucle++;
}
?>
我们仅仅从这个服务器的这个分组上获取了十条最新的新闻。你也可以使用HEAD命令来至获取文章的头部信息,或者使用BODY命令来获取新闻的正文。
关闭连接
使用fclose()函数你就可以结束与NNTP服务器之间的会话,当然你可以些一个新的文件,如下:
// close connexion
fclose($usenet_handle);
?>
更多关于fclose()的信息,请看:http://www.php.net/manual/function.fclose.php
结论
本文中,我们只说明了在确定的情况下如何打开、使用和关闭一个socket连接:连接上一个NNTP服务器然后从新闻分组中取回一些文章。使用POST命令在NNTP服务器上发表一篇文章并不复杂多少。
因此,下一步就是编写一个新闻客户端(并去掉一些Netscape),它需要能很容易的保存文章,并使用一些搜索引擎(比如htgid, http://www.htdig.org/)来索引这些文章,而且要有一个WEB应用程序能进行新闻分组下的关键字搜索。这里有一个例子,你可以访问http://www.phpindex.com/ng/去下载。

PHPSession失效的原因包括配置錯誤、Cookie問題和Session過期。 1.配置錯誤:檢查並設置正確的session.save_path。 2.Cookie問題:確保Cookie設置正確。 3.Session過期:調整session.gc_maxlifetime值以延長會話時間。

在PHP中調試會話問題的方法包括:1.檢查會話是否正確啟動;2.驗證會話ID的傳遞;3.檢查會話數據的存儲和讀取;4.查看服務器配置。通過輸出會話ID和數據、查看會話文件內容等方法,可以有效診斷和解決會話相關的問題。

多次調用session_start()會導致警告信息和可能的數據覆蓋。 1)PHP會發出警告,提示session已啟動。 2)可能導致session數據意外覆蓋。 3)使用session_status()檢查session狀態,避免重複調用。

在PHP中配置會話生命週期可以通過設置session.gc_maxlifetime和session.cookie_lifetime來實現。 1)session.gc_maxlifetime控制服務器端會話數據的存活時間,2)session.cookie_lifetime控制客戶端cookie的生命週期,設置為0時cookie在瀏覽器關閉時過期。

使用數據庫存儲會話的主要優勢包括持久性、可擴展性和安全性。 1.持久性:即使服務器重啟,會話數據也能保持不變。 2.可擴展性:適用於分佈式系統,確保會話數據在多服務器間同步。 3.安全性:數據庫提供加密存儲,保護敏感信息。

在PHP中實現自定義會話處理可以通過實現SessionHandlerInterface接口來完成。具體步驟包括:1)創建實現SessionHandlerInterface的類,如CustomSessionHandler;2)重寫接口中的方法(如open,close,read,write,destroy,gc)來定義會話數據的生命週期和存儲方式;3)在PHP腳本中註冊自定義會話處理器並啟動會話。這樣可以將數據存儲在MySQL、Redis等介質中,提升性能、安全性和可擴展性。

SessionID是網絡應用程序中用來跟踪用戶會話狀態的機制。 1.它是一個隨機生成的字符串,用於在用戶與服務器之間的多次交互中保持用戶的身份信息。 2.服務器生成並通過cookie或URL參數發送給客戶端,幫助在用戶的多次請求中識別和關聯這些請求。 3.生成通常使用隨機算法保證唯一性和不可預測性。 4.在實際開發中,可以使用內存數據庫如Redis來存儲session數據,提升性能和安全性。

在無狀態環境如API中管理會話可以通過使用JWT或cookies來實現。 1.JWT適合無狀態和可擴展性,但大數據時體積大。 2.Cookies更傳統且易實現,但需謹慎配置以確保安全性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境