代码改变世界

20 使用网络函数和协议函数

2016-08-26 19:28  yojiaku  阅读(404)  评论(0编辑  收藏  举报
20 使用网络函数和协议函数
主要内容:介绍PHP所提供的面向网络的函数,这些函数能够使脚本与Internet进行交互。
先看了一个例子:程序清单20-1 lookup.php —— 从NASDAQ获得$symbol列表所给出股票的报价脚本
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Stock Quote From NASDAQ</title>
</head>
<body>
<?php
// choose stock to look at
$symbol = 'AMZN';
echo '<h1>Stock quote for'.$symbol.'</h1>';

$url = 'http://finance.yahoo.com/d/quotes.csv'.
    '?s=' . $symbol . '&e=.csv&f=slldltlclohgv';
if(!($contents = file_get_contents($url)))
{
    die('Failure to open '.$url);
}

// extract relevant data
list($symbol, $quote, $date, $time) = explode(',', $contents);  // 把$contents字符串按‘,’分割成数组,然后依次把数组中元素按顺序赋给前面list里的变量。
$date = trim($date, '"');
$time = trim($time, '"');

echo "<p>".$symbol." was last sold at: ".$quote."</p>";
echo "<p>Quote current as of ".$date." at ".$time."</p>";

// acknowledge source
echo "<p>This information retrieved from <br /><a href='".$url."'>".$url."</a>.</p>";
?>
</body>
</html>

  

很快,我就遇到了第一个错误:
Failure to open http://finance.yahoo.com/d/quotes.csv?s=AMZN&e=.csv$f=sl1d1t1c1ohgv
我查了一下这个网址,发现根本打不开,所以应该是网址写错了的缘故,换成下面的就好了:
$url = 'http://finance.yahoo.com/d/quotes.csv'.
'?s=' . $symbol . '&e=.csv&f=slldltlclohgv';
然后我刷新界面,发现运行结果如下:
"AMZN" was last sold at: "4:00pm - 757.25"
Quote current as of 4:00pm - 757.25 at N/A
This information retrieved from
http://finance.yahoo.com/d/quotes.csv?s=AMZN&e=.csv&f=slldltlclohgv.
然后我点开后面的网址,下载了一个Excel文件:
AMZN 4:00pm - <b>757.25</b> 4:00pm - <b>757.25</b> N/A 4:00pm - <b>757.25</b> N/A 4:00pm - <b>757.25</b> -5.1932 4:00pm - <b>757.25</b> 763 763.41 755.36 1744107
不是很明白它写的是什么,但是获取的消息跟预想的差不多。
书上解释的是:
这个程序使用file_get_contents()从URL获取信息,获取到页面文本后,通过list()函数找到我们所要的网页部分
(这个例子是去雅虎财经网获取亚马逊的股票报价)
(这是一个人对这个例子的解释:In order to write the example code you have, some ardent programmer went to Yahoo's Finance site and observed what happened there when he/she wanted to read the stock quote for Amazon.com.
One of the first things *you* should do is visit bankrate.com and find where the LIBOR is displayed. Take a look at the source code around that area, as that's what you'll be receiving back from a call to file_get_contents().)

这个例子的输出结果为:

这是连接时间超过限制30s了,可以在配置中修改

正常情况下,运行结果为:

"AMZN" was last sold at: "4:00pm - 757.25"
Quote current as of 4:00pm - 757.25 at N/A
This information retrieved from
http://finance.yahoo.com/d/quotes.csv?s=AMZN&e=.csv&f=slldltlclohgv.
还有一种php写法:
<html>
<head>
    <title>Stock Quote from NASDAQ</title>
</head>
<body>
<?php
// choose stock to look at
$symbol='AMZN';
echo "<h1>Stock Quote for $symbol</h1>";

$theurl="http://www.amex.com/equities/listCmp/EqLCDetQuote.jsp?Product_Symbol=$symbol";

if (!($contents = file_get_contents($theurl)))
{
    echo 'Could not open URL';
    exit;
}

// find the part of the page we want and output it
$pattern = '(\\$[0-9 ]+\\.[0-9]+)';

if (eregi($pattern, $contents, $quote))
{
    echo "<p>$symbol was last sold at: ";
    echo $quote[1];
    echo '</p>';
}
else
{
    echo '<p>No quote available</p>';
};


// acknowledge source
echo '<p>'
    .'This information retrieved from <br />'
    ."<a href=\"$theurl\">$theurl</a><br />"
    .'on '.(date('l jS F Y g:i a T')).'</p>';
?>
</body>
</html>

  运行结果为:

在PHP中,文件函数还可以完成许多操作,这里给出的例子至少通过http载入一个Web页面,还可以通过https、ftp或其他协议以几乎相同的方式与其他服务进行交互。
进入下一个例子:使用网络查找函数。
PHP提供一组查找函数,这些函数可以用来检查主机名称、ip地址、邮件交换等信息。
例如:如果要创建一个目录站点,例如Yahoo!,当用户提交一个新的URL时,我们可能会自动那个检查URL所指向的主机和此站点的联系信息是否有效。这样,当一个访问者浏览一个网站并发现此网站不存在或电子邮件无效时,可以节省进一步的操作。
程序清单 20-2 directory_submit.html —— 提交表单的HTMl
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Submit site</title>
</head>
<body>
<h1>Submit site</h1>
<form method="post" action="directory_submit.php">
    URL: <input type="text" name="url" size="30" value="http://"> <br />
    Email contact: <input type="text" name="email" size="23"> <br />
    <input type="submit" name="Submit site">
</form>
</body>
</html>

  运行结果:

点击提交后显示php页面结果为:

如果用localhost作为URL:

点击提交后:

 

程序清单 20-3 directory_submit.php —— 用于检查URL和电子邮件地址的脚本
<html>
<head>
    <title>Site submission results</title>
</head>
<body>
<h1>Site submission results</h1>
<?php

// Extract form fields

$url = $_REQUEST['url'];
$email = $_REQUEST['email'];

// Check the URL

$url = parse_url($url);
$host = $url['host'];
if(!($ip = gethostbyname($host)))
{
    echo 'Host for URL does not have valid IP';
    exit;
}

echo "Host is at IP $ip <br>";

// Check the email address

$email = explode('@', $email);
$emailhost = $email[1];

// note that the getmxrr() function is *not implemented* in
// Windows versions of PHP
if (!getmxrr($emailhost, $mxhostsarr))
{
    echo 'Email address is not at valid host';
    exit;
}

echo 'Email is delivered via: ';
foreach ($mxhostsarr as $mx)
    echo "$mx ";

// If reached here, all ok

echo '<br>All submitted details are ok.<br>';
echo 'Thank you for submitting your site.<br>'
    .'It will be visited by one of our staff members soon.'

// In real case, add to db of waiting sites...
?>
</body>
</html>

  

在其php文件中有一些需要注意的地方:
· 获取URL并将其作为函数parse_url()的参数。
parse_url()函数是URL解析函数,顾名思义,它可以解析URL,并返回其组成部分:array parse_url ( string url );
返回一个关联数组,包括现有URL的各种组成部分。如果缺少了其中一个,则不会为这个组成部分创建数组项。组成部分有:(以http://nobody:secret@example.com:80/script.php?variable = value#anchor 为例)
· scheme : http
· user : noboby
· pass : secret
· host : example.com
· port : 80
· path : /script.php
· query : variable = value (在?之后)
· fragment : anchor (在#之后)
· 函数dns_get_mx()检查是否有邮件可以到达的确切地方:dns_get_mx()函数与getmxrr()函数相同,该函数返回一个邮件地址的一组邮件交换(Mail Exchange, MX)记录
bool getmxrr ( string $hostname , array &$mxhosts [, array &$weight ] )
(hostname
The Internet host name.

mxhosts
A list of the MX records found is placed into the array mxhosts.

weight
If the weight array is given, it will be filled with the weight information gathered.)
注意:MX记录存储在DNS中,而且查找方式类似于主机名的查找方式。MX列出的机器不一定是邮件最终到达的机器。相反,它是一台知道邮件发送路由的机器(可能不止一台,因此这个函数返回的是一个数组而不是一个主机名字符串)。
例如:m17784080315@126.com返回Email is delivered via: 126mx01.mxmail.netease.com 126mx03.mxmail.netease.com 126mx02.mxmail.netease.com 126mx00.mxmail.netease.com