Professional PHP Programming phần 6 docx

86 292 0
Professional PHP Programming phần 6 docx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

$data .= fread($fp, 1000); } fclose($fp); } return $data; } ?> <FORM> <INPUT TYPE=HIDDEN NAME=action VALUE=query> <INPUT TYPE=TEXT NAME=query VALUE="<?echo $query?>"> <INPUT TYPE=SUBMIT VALUE=" OK "> </FORM> <?php $server = "whois.ripe.net"; if($action == "query") { $data = whois request($server, $query); echo "Sent $query to $server.<p>"; echo "Output: <p><pre>$data</pre><p>"; } ?> Extending the Frontend We can present visitors now a way to query a whois database. But what, if we want to enable visitors to query multiply databases? For example, if we would like to make queries to the RIPE database and the InterNIC database. In the previous example you saw that we had hard-wired the hostname of the whois server. In this step, we want to make this configurable. We use the same whois_request() function again. Our HTML form changes a little bit to reflect our new choice: <FORM> <INPUT TYPE=HIDDEN NAME=action VALUE=query> <SELECT NAME=server> <OPTION value="whois.ripe.net">RIPE</OPTION> <OPTION value="rs.internic.net">InterNIC</OPTION> </SELECT> <INPUT TYPE=TEXT NAME=query VALUE="<?echo $query?>"> <INPUT TYPE=SUBMIT VALUE=" OK "> </FORM> We use the <SELECT> tag to build up a select box which shows several whois servers. We store the hostname as an option value in the HTML part. This helps us to keep the effort minimal to add new servers. Once the user hits the submit button, the hostname of the server of his or her choice will be send to the server. PHP makes the data available as $server variable. Thus we change our code to reflect this: <?php # $server is already set by web server if($action == "query") { $data = whois request($server, $query); echo "Sent $query to $server.<p>"; echo "Output: <p><pre>$data</pre><p>"; } ?> You see, this part became even simpler! In the next step we will enhance the frontend more and build new functionality into it. Is my domain still available? Today, a popular way to utilize whois is to offer potential customers the ability to quickly lookup whether specific domains are still available. We will build such a script now. We reuse our whois_request() function from the previous sections. Recall that this function queries a specific whois server for specific information and returns the raw information from the server. It does not perform any analyzing, so we need some additional logic to produce useful output. Up to now, we built a simple query interface for a whois server. Now we add more logic to it. Our design goal is simple. The user enters a domain name and we find out whether the domain is still available or not. If you have examined the previous examples, you will notice that on some queries you get useful replies with real data and that some fail, returning a message like "No entries found for the selected source(s)." We will use this to make the decision whether a specific domain is available. To increase the value of our script, we enable the user to query for different TLDs (top level domains, like COM, NET, GB). To do that, we have to determine the chosen top-level domain. function domain tld($domain) { $ret = ""; if(ereg("\.([^\.]+)$", $domain, $answer)) $ret = strtolower($answer[1]); return $ret; } The function domain_tld() returns the TLD of the domain name passed to it. It uses a regular expression to determine the last part of the domain, which can be found after the last ".". Note that we do not validate the TLD. You can use the validator class to validate all top-level domains (including all Top 7 and ISO domains). We use the TLD to determine which whois server we have to query for a specific domain. In order to do this quickly, we use an associative array with the TLD as index. For each TLD we save the hostname of the whois server and the answer we expect, if the record does not exist. <?php $whois server = array( "com" => array("whois.internic.net", "No match for"), "de" => array("whois.ripe.net", "No entries found for") ); ?> You can easily support more TLDs by including the necessary information into the array. The IANA (The Internet Assigned Numbers Authority) maintains a database of contact information for all countries. If a domain registry runs a whois server, it is often mentioned on the homepage of the respective organization (http://www.iana.org/cctld.html). Note that running a whois server is not a requirement, but a voluntary service. This section finishes with our working horse, a function to determine whether a specific domain is still available. The function uses only well-known elements, which we discussed earlier, so it should be easy to understand. The function returns false or true, depending on whether the specified function is used or available. <?php function is domain available($domain){ global $whois server; # set default return value $ret = false; # determine TLD $tld = domain tld($domain); # if the TLD is not empty and we know about a whois server for the TLD if(!empty($tld) && is array($whois server[$tld])){ # we send a whois request $data = whois request($whois server[$tld][0], $domain); # and check whether the whois server's response contains # a string which says that the domain is not used if(strstr($data, $whois server[$tld][1]) != ""){ $ret = true; } } return $ret; } ?> A web client The break-through of the Internet was based upon one network protocol: HTTP (the Hypertext Transfer Protocol, the last version is HTTP/1.1). HTTP is the protocol your web browser users when you access web sites. We will present a simple class now, which makes it possible to access HTTP resources transparently, even if you need to use a HTTP proxy. A HTTP proxy is a service most ISPs (Internet Service Providers) and companies deploy to accelerate web access and to reduce network traffic. Proxies cache data to achieve these goals. Proxies are protocol dependent and exist for a number of services, including HTTP. Network-wise, proxies sit between the client (web browser) and the server. The client sends a request to the proxy, which either returns a cached copy, or forwards the request to the web server. In PHP, you can use web resources like local files. The so-called fopen-wrappers allow you to use PHP's standard I/O functions (i.e. fopen(), fread(), fclose()) as if the files were stored on the local file system. <php # open the site $fd = fopen("http://www.php.net/", "r"); # if the above requests succeeded, send output to the current client if($fd){ fpassthru($fd); } ?> The lack of HTTP proxy support renders fopen-wrappers unusable for many purposes. For example, an Intranet web server might not be able to access an external web site by using fopen-wrappers, because it has no direct Internet direction and must send HTTP requests through a proxy. Hopefully, HTTP proxy support will be added in the final version of PHP 4.0. Since we want the class to be as simple as possible, we define it to be a HTTP/1.0 client performing only GET requests. It should return a file pointer, so that you could easily replace PHP's fopen() function for URLs with our self-developed class. We use a class here, since we want to be able to store certain preferences within the class without using global variables. Our framework looks like this: <?php class http { var $proxy host = ""; var $proxy_port = 0; function http fopen($host, $url, $port = 80) { } } Our "http" named class contains two variables, called $proxy_host and $proxy_port which you can set to the respective values which are valid in your environment. The class will make use of the proxy, if these variables are set. Otherwise, it accesses the HTTP server directly. The key difference here is that we simply change the fsockopen() parameter. To request a resource, our PHP scripts opens a TCP connection to the web server or the HTTP proxy, sends the HTTP request, reads the reply, and closes the connection. (Note that we only implement HTTP/1.0. HTTP/1.1 can be much more complex in this regard.) Below is the full code for the http class: <?php class http { var $proxy host = ""; var $proxy port = 0; function http fopen($host, $path, $port = 80) { # has the user set $proxy host? if(empty($this->proxy host)) { # we access the server directly $conn host = $host; $conn port = $port; } else { # we use the proxy $conn host = $this->proxy host; $conn port = $this->proxy port; } # build the absolute URL $abs url = "http://$host:$port$path"; # now we build our query $query = "GET $abs url HTTP/1.0\r\n". "Host: $host:$port\r\n". "User-agent: PHP/class http 0.1\r\n". "\r\n"; # open a connection to the server $fp = fsockopen($conn host, $conn port); # if the connection failed, return false if(!$fp) return false; # send our query fputs($fp, $query); # discard the HTTP header while(trim(fgets($fp, 1024)) != ""); # return the active file pointer return $fp; } } ?> Our http_fopen() function takes two parameters and an optional third one. The first parameter is the hostname or IP address of the server the data shall be retrieved from (e.g. "www.wrox.com" or "204.148.170.3"). The second one is the URI of the resource on that server (for example, "/icons/directory.gif"). The optional third parameter is the TCP port number (e.g. port 8080). The well- known port number for HTTP is 80, which is also our default port number. The next step is to determine whether the user has set the proxy variables. We test whether the $proxy_host variable is empty and based on that test we set two variables. The first identifier ($conn_host) is the hostname of the server we connect to, $conn_port is its port number. If $proxy_host is empty, we assign these variables the hostname and port number of the web server, otherwise we assign the configured proxy hostname and proxy port. $conn_url is set to include the name of the protocol (http), the host name or IP number of the web server, its port number, and the path of the resource. Note that there is no delimiter between the port number and the path, because the path should start with "/". We construct the HTTP request by specifying GET as the method (it retrieves whatever information is stored on the server), concatenating $conn_url and attaching the HTTP version that we are using. We add a "Host" header, which tells the server the hostname we want to access. Today, many HTTP servers do not have their own IP addresses anymore, they rely on HTTP clients sending them the server name so that the server software must distinguish between the virtual hosts it serves. These virtual hosts are virtual, because they appear to be a real host, but in fact the web server only simulates them. The web server maintains a list of available virtual hosts, and delivers different data to clients, depending on the virtual hosts they specify. Finally, we give ourselves a name by specifying it in the "User-agent" message-header. The end of the HTTP request is marked by an empty line. The line ending is CRLF (hexadecimal 0x13 and 0x10, can also be written as "\r\n" in PHP). After our request is constructed now, we open the TCP connection to the server (either to the web server or to the HTTP proxy, depending on our previous test). If the connection attempt does not succeed, we return false, so that the caller can easily test for a failed connection attempt. The next few lines read the HTTP response header, which is thrown away (we do this, because our design target was simplicity). When we see an empty line, the body of the HTTP response begins. This body contains the data the caller wants. Therefore, we stop the loop here, and return the file pointer. If the caller reads from this file pointer, the requested resource is directly accessible. The next example demonstrates the use of the http class. It fetches the specified web site, and passes it through to the client requesting our example script. Using the http class <?php include "http.class"; $http = new http; $fp = $http->http fopen("www.wroxconferences.com", "/"); if(!$fp) { print "Sorry, the server is not currently available"; exit; } print "<BASE HREF=\"http://www.wroxconferences.com/\"><p>"; fpassthru($fp); ?> The first action is to include the file that contains the http class. Then we create a new instance of the http class. We use the member function http_fopen() of that class to access the Wrox Conferences web server. If the result of http_fopen() is false, the connection attempt to the web server failed. Otherwise, we can manipulate the file pointer. In our example, we choose to pass through all available data on the file pointer to the current client. That means the client sees the Wrox Conferences homepage, as if www.wroxconferences.com would have been accessed directly. Note the <BASE> tag. It is used to tell the client that all relative links in the page shall be relative to the specified URL. The following screenshot shows how the output of the script looks like. Summary In this chapter we have shown how to build clients for TCP-based Internet protocols in PHP. We have provided examples for accessing Whois database servers as well as HTTP servers and proxies. This knowledge helps you to understand information flow on the Internet and implement protocols that use TCP as their transport layer. 17 Sending and Receiving E-mail E-mail is the most used Internet service today. Billions of e-mails are delivered each day. PHP integrates techniques to handle e-mail. There are many different ways in which they can be applied: Sending invoices to a customer; informing your customers about the latest news from your business; encouraging people to join your interest group. In this chapter, we focus on how to generate and send e-mails in PHP. Sending E-mail The mail() command You use the built-in mail() command to send simple text messages. mail() relies on the local mail system to deliver e-mails. So, if your program cannot rely on the local mail system, you shouldn't use mail(). We present an alternative later in this chapter. The prototype of the function: bool mail(string to, string subject, string message[, string additional_headers]); The function returns true, if the e-mail was correctly submitted to the local mail system. It does not imply that the e-mail was delivered. The fourth parameter is optional. An explanation of the parameters follows. Parameter Meaning Example to Recipient addresses, "user1@foo.com" or must be separated by comma "user1@foo.com,someone@bar.net" subject The subject of the e- mail "user registration" message The body of the message "Hi,\r\nthis is the second line of text\r\nthis is the third line of text" additional_headers (optional) This string is appended to the end of the e-mail header. Multiple header lines can be specified by separating them with "\r\n" "From: webmaster@foo.com\r\nReply-to: my@address.org" The next example sends an e-mail to a single recipient: <?php mail("recipient@domain.com", "This is the subject", "body of the message"); ?> The third parameter contains the body of the message. If you want to embed the e-mail text in the PHP code, the text can span over multiple lines: <?php mail("recipient@domain.com", "This is the subject", "Hello, welcome to our service. To access our site, you need the following data: username: $username password: $password If you should have problems with our service, please contact <mailto:support@domain.com>. To visit our site now, click here: http://www.domain.com/ - Webmaster "); ?> To address multiple recipients, you separate each e-mail address by a comma. [...]... hour, minute, second, month, day, year $lifetime = mktime(0, 0, 0, 12, 1, 1999); // midnight 01.12.1999 $lifetime = mktime(12, 50, 30, 6, 20, 2010); // 12:50:30 20. 06. 2010 // relative $lifetime = $lifetime = $lifetime = dates time() + 360 0; time() + 864 00; time() + 864 00 * 30; // lifetime of one hour // lifetime of one day // lifetime of one month (30 days) After we have calculated the lifetime, we... server) domain The domain of the server that set the cookie expire information Until the browser is closed secure Disabled Cookies in PHP Cookie support is integrated into PHP, so that a PHP developer can take full advantage of this technique Reading cookies from within PHP is as easy as accessing variables On startup of our script, cookies are automatically made available as global variables For example,... calculated in PHP using the time() and mktime() functions The time() function returns the timestamp for the current time, and the mktime() function converts a "human-friendly" date into a timestamp The parameters for this function are the hour, minute, second, month, day and year for the date to be converted (in that order) < ?php // expires in 360 0 seconds (1 hour) setcookie("name", $value, time() + 360 0);... beneficial over time The standard IMAP protocol is well supported by PHP, and when the two are combined produce a very suitable programming environment for creating e-mail facilities Powerful and versatile results can be accomplished quickly, by the combination of multiple PHP IMAP functions Some of these are listed below imap_open The PHP function, imap_open(), opens an IMAP stream to a mailbox int imap_open(string... and sent to the client PHP3 generates a warning message which reads Oops, php3 _SetCookie called after header has been sent (the message is slightly different with PHP4 ) If you get this message, it means that you need to look for data which was sent to the client before the setcookie() call A single space, a newline character, or any other text (whether plain HTML or printed from PHP) could be the cause... URL: http://somesite.com/yourpage .php? SessionID=ab3hemc5akeq2bmut31 PHP 4.0 provides both methods, since it tries to meet the needs of a large user base If you want to delete and set a cookie with the same name, pay attention to the order in which you call setcookie() PHP sends the cookies to the server in the reverse order to that of the setcookie() calls in the PHP script This affects us only if... all the details, you should read Chapter 16 (PHP Connectivity), which provides insight into the world of developing networking applications However, you have not been told how the class works, if you just want to use it to send e-mails We will show now how you can combine class mime_mail and class smtp_mail to deliver complex e-mails using direct SMTP access < ?php include "mime mail.inc"; include "smtp... visits PHP will automatically make available a $count variable to our script if the cookie is sent by the user agent (browser) We use the setcookie() function to send a request to the browser to set a cookie This request updates or creates a cookie on the client This code must appear at the very start of the page – any content (even whitespace) preceding the opening PHP tag will generate an error < ?php. .. the best programmers, it's important that the programming environment provides effective ways of detecting and diagnosing any bugs which do occur, and of gracefully handling any runtime errors which can be foreseen, such as failure to make a connection to a database The good news is that PHP is a very convenient environment for debugging and error handling PHP allows us to detect and react to errors... mktime(0,0,0,1,1,2002)); // expires at 6: 30 PM on 05/12/2020 setcookie("name", $value, mktime(18, 30, 0, 5, 12, 2020)); ?> What is Your Name? Let's look at another example This page prompts users to enter their name, which is then submitted to the server The server will send a "set cookie" request to the client and on subsequent visits the user will be greeted by name < ?php if($action == "setcookie") { setcookie("visitorname", . his or her choice will be send to the server. PHP makes the data available as $server variable. Thus we change our code to reflect this: < ?php # $server is already set by web server. or forwards the request to the web server. In PHP, you can use web resources like local files. The so-called fopen-wrappers allow you to use PHP& apos;s standard I/O functions (i.e. fopen(),. fclose()) as if the files were stored on the local file system. < ;php # open the site $fd = fopen("http://www .php. net/", "r"); # if the above requests succeeded,

Ngày đăng: 12/08/2014, 13:21

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan