1. Trang chủ
  2. » Công Nghệ Thông Tin

Beginning PHP and MySQL From Novice to Professional phần 5 pot

108 317 0

Đ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

Thông tin cơ bản

Định dạng
Số trang 108
Dung lượng 1,52 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Its prototype follows: array dns_get_recordstring hostname [, int type [, array &authns, array &addtl]] Although by default dns_get_record returns all records it can find specific to the

Trang 2

The key values and their respective properties are discussed earlier in this chapter,

so there’s no reason to describe them again (besides, all the names are rather explanatory) If you’re interested in just retrieving the value of a single property, pass

self-a key to the getProp() cself-all For exself-ample, suppose you wself-ant to know the size (in bytes)

of the file:

echo $files->getProp('size');

This produces the following output:

22616

Uploading Multiple Files

One of the beautiful aspects of HTTP_Upload is its ability to manage multiple file uploads To handle a form consisting of multiple files, all you have to do is invoke a new instance of the class and call getFiles() for each upload control Suppose the aforementioned professor has gone totally mad and now demands five homework assignments daily from his students The form might look like this:

<form action="multiplehomework.php" enctype="multipart/form-data" method="post"> Last Name:<br /> <input type="text" name="name" value="" /><br />

Homework #1:<br /> <input type="file" name="homework1" value="" /><br /> Homework #2:<br /> <input type="file" name="homework2" value="" /><br /> Homework #3:<br /> <input type="file" name="homework3" value="" /><br /> Homework #4:<br /> <input type="file" name="homework4" value="" /><br /> Homework #5:<br /> <input type="file" name="homework5" value="" /><br /> <p><input type="submit" name="submit" value="Submit Notes" /></p>

</form>

Trang 3

C H A P T E R 1 5 ■ H A N D L I N G F I L E U P L O A D S 399

Handling this with HTTP_Upload is trivial:

$homework = new HTTP_Upload();

At this point, simply use methods such as isValid() and moveTo() to do what you will

with the files

Summary

Transferring files via the Web eliminates a great many inconveniences otherwise

posed by firewalls and FTP servers and clients It also enhances an application’s ability

to easily manipulate and publish nontraditional files In this chapter, you learned just

how easy it is to add such capabilities to your PHP applications In addition to offering a

comprehensive overview of PHP’s file-upload features, several practical examples

were discussed

The next chapter introduces in great detail the highly useful Web development

topic of tracking users via session handling

Trang 5

■ ■ ■

C H A P T E R 1 6

Networking

You may have turned to this chapter wondering just what PHP could possibly have

to offer in regard to networking After all, aren’t networking tasks largely relegated to

languages commonly used for system administration, such as Perl or Python? While

such a stereotype might have once painted a fairly accurate picture, these days,

incorpo-rating networking capabilities into a Web application is commonplace In fact,

Web-based applications are regularly used to monitor and even maintain network

infra-structures Furthermore, with the introduction of the command-line interface (CLI)

in PHP version 4.2.0, PHP is now increasingly used for system administration among

developers who wish to continue using their favorite language for other purposes The

PHP developers, always keen to acknowledge growing needs in the realm of Web

appli-cation development and to remedy demands by incorporating new features into the

language, have put together a rather amazing array of network-specific functionality

This chapter is divided into sections covering the following topics:

DNS, servers, and services: PHP offers a variety of functions capable of retrieving

information about the network internals, DNS, protocols, and Internet addressing

schemes This section introduces these functions and offers several usage examples

Sending e-mail with PHP: Sending e-mail via a Web application is undoubtedly

one of the most commonplace features you can find these days, and for good reason

E-mail remains the Internet’s killer application and offers an amazingly efficient

means for communicating and maintaining important data and information

This section explains how to easily send messages via a PHP script Additionally,

you’ll learn how to use the PEAR packages Mail and Mail_Mime to facilitate more

complex e-mail dispatches, such as those involving multiple recipients, HTML

formatting, and the inclusion of attachments

Trang 6

402 C H A P T E R 1 6 ■ N E T W O R K I N G

Common networking tasks: In this section, you’ll learn how to use PHP to mimic

the tasks commonly carried out by command-line tools, including pinging a network address, tracing a network connection, scanning a server’s open ports, and more

DNS, Services, and Servers

These days, investigating or troubleshooting a network issue often involves gathering

a variety of information pertinent to affected clients, servers, and network internals such as protocols, domain name resolution, and IP addressing schemes PHP offers a number of functions for retrieving a bevy of information about each subject, each of which is introduced in this section

Note Several of the functions introduced in this chapter don’t work on Windows Check out the PEAR package Net_DNS to emulate their capabilities

DNS

The Domain Name System (DNS) is what allows you to use domain names (e.g.,

example.com) in place of the corresponding not-so-user-friendly IP address, such as

192.0.34.166 The domain names and their complementary IP addresses are stored and made available for reference on domain name servers, which are interspersed across the globe Typically, a domain has several types of records associated to it, one mapping the IP address to the domain, another for directing e-mail, and another for

a domain name alias, for example Often network administrators and developers require a means to learn more about various DNS records for a given domain This section introduces a number of standard PHP functions capable of digging up a great deal of information regarding DNS records

Checking for the Existence of DNS Records

The checkdnsrr() function checks for the existence of DNS records Its prototype follows:

int checkdnsrr(string host [, string type])

Trang 7

C H A P T E R 1 6 ■ N E T W O R K I N G 403

DNS records are checked based on the supplied host value and optional DNS

resource record type, returning TRUE if any records are located, and FALSE otherwise

Possible record types include the following:

A: IPv4 Address Record Responsible for the hostname-to-IPv4 address translation.

AAAA: IPv6 Address Record Responsible for the hostname-to-IPv6 address

translation

A6: IPv6 Address Record Used to represent IPv6 addresses Intended to supplant

present use of AAAA records for IPv6 mappings

ANY: Looks for any type of record

CNAME: Canonical Name Record Maps an alias to the real domain name.

MX: Mail Exchange Record Determines the name and relative preference of a

mail server for the host This is the default setting

NAPTR: Naming Authority Pointer Allows for non-DNS-compliant names,

resolving them to new domains using regular expression rewrite rules For

example, an NAPTR might be used to maintain legacy (pre-DNS) services

NS: Name Server Record Determines the name server for the host.

PTR: Pointer Record Maps an IP address to a host.

SOA: Start of Authority Record Sets global parameters for the host.

SRV: Services Record Denotes the location of various services for the supplied

domain

Consider an example Suppose you want to verify whether the domain name

example.com has a corresponding DNS record:

<?php

$recordexists = checkdnsrr("example.com", "ANY");

if ($recordexists) echo "The domain name has been reserved Sorry!";

else echo "The domain name is available!";

?>

This returns the following:

The domain name has been reserved Sorry!

Trang 8

$valid = checkdnsrr($domain[1], "ANY");

if($valid) echo "The domain exists!";

else echo "Cannot locate MX record for $domain[1]!";

?>

This returns the following:

The domain exists!

Keep in mind this isn’t a request for verification of the existence of an MX record Sometimes network administrators employ other configuration methods to allow for mail resolution without using MX records (because MX records are not mandatory)

To err on the side of caution, just check for the existence of the domain, without specifically requesting verification of whether an MX record exists

Further, this doesn’t verify whether an e-mail address actually exists The only definitive way to make this determination is to send that user an e-mail and ask him

to verify the address by clicking a one-time URL You can learn more about one-time URLs in Chapter 14

Retrieving DNS Resource Records

The dns_get_record() function returns an array consisting of various DNS resource records pertinent to a specific domain Its prototype follows:

array dns_get_record(string hostname [, int type [, array &authns, array &addtl]])

Although by default dns_get_record() returns all records it can find specific to the supplied domain (hostname), you can streamline the retrieval process by specifying a type, the name of which must be prefaced with DNS This function supports all the types introduced along with checkdnsrr(), in addition to others that will be introduced in a moment Finally, if you’re looking for a full-blown description of this hostname’s DNS

Trang 9

C H A P T E R 1 6 ■ N E T W O R K I N G 405

description, you can pass the authns and addtl parameters in by reference, which

specify that information pertinent to the authoritative name servers and additional

records also should be returned

Assuming that the supplied hostname is valid and exists, a call to dns_get_record()

returns at least four attributes:

host: Specifies the name of the DNS namespace to which all other attributes

correspond

class: Returns records of class Internet only, so this attribute always reads IN

type: Determines the record type Depending upon the returned type, other

attributes might also be made available

ttl: Calculates the record’s original time-to-live minus the amount of time that

has passed since the authoritative name server was queried

In addition to the types introduced in the section on checkdnsrr(), the following

domain record types are made available to dns_get_record():

DNS_ALL: Retrieves all available records, even those that might not be recognized

when using the recognition capabilities of your particular operating system Use

this when you want to be absolutely sure that all available records have been

retrieved

DNS_ANY: Retrieves all records recognized by your particular operating system

DNS_HINFO: Specifies the operating system and computer type of the host Keep in

mind that this information is not required

DNS_NS: Determines whether the name server is the authoritative answer for the

given domain, or whether this responsibility is ultimately delegated to another

server

Just remember that the type names must always be prefaced with DNS_

As an example, suppose you want to learn more about the example.com domain:

<?php

$result = dns_get_record("example.com");

print_r($result);

?>

Trang 10

This returns the following:

Array ( [0] => Array ( [host] => example.com [type] => NS

[target] => a.iana-servers.net [class] => IN [ttl] => 21564 )

[1] => Array ( [host] => example.com [type] => NS

[target] => b.iana-servers.net [class] => IN [ttl] => 21564 ) )

getmxrr()

Trang 11

C H A P T E R 1 6 ■ N E T W O R K I N G 407

Retrieving MX Records

The getmxrr() function retrieves the MX records for the domain specified by

hostname Its prototype follows:

boolean getmxrr(string hostname, array &mxhosts [, array &weight])

The MX records for the host specified by hostname are added to the array specified

by mxhosts If the optional input parameter weight is supplied, the corresponding

weight values will be placed there, which refer to the hit prevalence assigned to each

server identified by record An example follows:

Although we often use the word Internet in a generalized sense, referring to it in

regard to chatting, reading, or downloading the latest version of some game, what

we’re actually referring to is one or several Internet services that collectively define

this communication platform Examples of these services include HTTP, FTP, POP3,

IMAP, and SSH For various reasons (an explanation of which is beyond the scope of

this book), each service commonly operates on a particular communications port

For example, HTTP’s default port is 80, and SSH’s default port is 22 These days, the

widespread need for firewalls at all levels of a network makes knowledge of such

matters quite important Two PHP functions, getservbyname() and getservbyport(),

are available for learning more about services and their corresponding port numbers

Retrieving a Service’s Port Number

The getservbyname() function returns the port number of a specified service Its

prototype follows:

int getservbyname(string service, string protocol)

Trang 12

408 C H A P T E R 1 6 ■ N E T W O R K I N G

The service corresponding to service must be specified using the same name as that found in the /etc/services file The protocol parameter specifies whether you’re referring to the tcp or udp component of this service Consider an example:

<?php

echo "HTTP's default port number is: ".getservbyname("http", "tcp");

?>

This returns the following:

HTTP's default port number is: 80

Retrieving a Port Number’s Service Name

The getservbyport() function returns the name of the service corresponding to the supplied port number Its prototype follows:

string getservbyport(int port, string protocol)

The protocol parameter specifies whether you’re referring to the tcp or the udp component of the service Consider an example:

<?php

echo "Port 80's default service is: ".getservbyport(80, "tcp");

?>

This returns the following:

Port 80's default service is: http

Establishing Socket Connections

In today’s networked environment, you’ll often want to query services, both local and remote Often this is done by establishing a socket connection with that service This section demonstrates how this is accomplished, using the fsockopen() function Its prototype follows:

resource fsockopen(string target, int port [, int errno [, string errstring [, float timeout]]])

Trang 13

C H A P T E R 1 6 ■ N E T W O R K I N G 409

The fsockopen() function establishes a connection to the resource designated by

target on port port, returning error information to the optional parameters errno

and errstring The optional parameter timeout sets a time limit, in seconds, on how

long the function will attempt to establish the connection before failing

The first example shows how to establish a port 80 connection to www.example.com

using fsockopen() and how to output the index page:

This returns the following:

HTTP/1.1 200 OK Date: Mon, 09 Oct 2006 23:33:52 GMT Server: Apache/2.0.54 (Fedora)

(Red-Hat/Linux) Last-Modified: Wed, 15 Nov 2005 13:24:10 GMT ETag:

"63ffd-1b6-80bfd280" Accept-Ranges: bytes Content-Length: 438

Connection: close Content-Type: text/html

You have reached this web page by typing "example.com", "example.net", or

"example.org" into your web browser

These domain names are reserved for use in documentation and are not available

for registration See RFC 2606, Section 3

Trang 14

410 C H A P T E R 1 6 ■ N E T W O R K I N G

The second example, shown in Listing 16-1, demonstrates how to use fsockopen()

to build a rudimentary port scanner

Listing 16-1 Creating a Port Scanner with fsockopen()

// Build an array of port values

$range =range($rangeStart, $rangeStop);

echo "<p>Scan results for $target</p>";

// Execute the scan

foreach ($range as $port) {

$result = @fsockopen($target, $port,$errno,$errstr,1);

if ($result) echo "<p>Socket open at port $port</p>";

}

?>

Scanning www.example.com, the following output is returned:

Scan results for www.example.com:

Socket open at port 21

Socket open at port 25

Socket open at port 80

Socket open at port 110

Trang 15

C H A P T E R 1 6 ■ N E T W O R K I N G 411

A far lazier means for accomplishing the same task involves using a program

execu-tion command such as system() and the wonderful free software package Nmap

(http://insecure.org/nmap/) This method is demonstrated in the section on

common networking tasks

Mail

This powerful feature of PHP is so darned useful, and needed in so many Web

appli-cations, that this section is likely to be one of the more popular sections of this chapter, if

not the whole book In this section, you’ll learn how to send e-mail using PHP’s popular

mail() function, including how to control headers, include attachments, and carry out

other commonly desired tasks

This section introduces the relevant configuration directives, describes PHP’s

mail() function, and concludes with several examples highlighting this function’s

many usage variations

Configuration Directives

There are five configuration directives pertinent to PHP’s mail() function Pay close

attention to the descriptions because each is platform-specific

SMTP = string

Scope: PHP_INI_ALL; Default value: localhost

The SMTP directive sets the Mail Transfer Agent (MTA) for PHP’s Windows platform

version of the mail function Note that this is only relevant to the Windows platform

because Unix platform implementations of this function are actually just wrappers

around that operating system’s mail function Instead, the Windows implementation

depends on a socket connection made to either a local or a remote MTA, defined by

this directive

sendmail_from = string

Scope: PHP_INI_ALL; Default value: NULL

The sendmail_from directive sets the From field of the message header This

param-eter is only useful on the Windows platform If you’re using a Unix platform, you must

set this field within the mail function’s addl_headers parameter

Trang 16

412 C H A P T E R 1 6 ■ N E T W O R K I N G

sendmail_path = string

Scope: PHP_INI_SYSTEM; Default value: the default sendmail path

The sendmail_path directive sets the path to the sendmail binary if it’s not in the system path, or if you’d like to pass additional arguments to the binary By default, this is set to the following:

Scope: PHP_INI_ALL; Default value: 25

The smtp_port directive sets the port used to connect to the server specified by the SMTP directive

mail.force_extra_parameters = string

Scope: PHP_INI_SYSTEM; Default value: NULL

You can use the mail.force_extra_parameters directive to pass additional flags to the sendmail binary Note that any parameters passed here will replace those passed

in via the mail() function’s addl_parameters parameter

As of PHP 4.2.3, the addl_params parameter is disabled if you’re running in safe mode However, any flags passed in via this directive will still be passed in even if safe mode is enabled In addition, this parameter is irrelevant on the Windows platform

Sending E-mail Using a PHP Script

E-mail can be sent through a PHP script in amazingly easy fashion, using the mail() function Its prototype follows:

boolean mail(string to, string subject, string message [, string addl_headers [, string addl_params]])

The mail() function can send an e-mail with a subject and a message to one or several recipients You can tailor many of the e-mail properties using the addl_headers parameter, and can even modify your SMTP server’s behavior by passing extra flags via the addl_params parameter

Trang 17

C H A P T E R 1 6 ■ N E T W O R K I N G 413

On the Unix platform, PHP’s mail() function is dependent upon the sendmail

MTA If you’re using an alternative MTA (e.g., qmail), you need to use that MTA’s

send-mail wrappers PHP’s Windows implementation of the function instead depends

upon establishing a socket connection to an MTA designated by the SMTP

configura-tion directive, introduced in the previous secconfigura-tion

The remainder of this section is devoted to numerous examples highlighting the many

capabilities of this simple yet powerful function

Sending a Plain-Text E-mail

Sending the simplest of e-mails is trivial using the mail() function, done using just the

three required parameters Here’s an example:

<?php

mail("test@example.com", "This is a subject", "This is the mail body");

?>

Try swapping out the placeholder recipient address with your own and executing

this on your server The mail should arrive in your inbox within a few moments If

you’ve executed this script on a Windows server, the From field should denote

what-ever e-mail address you assigned to the sendmail_from configuration directive Howwhat-ever,

if you’ve executed this script on a Unix machine, you might have noticed a rather odd

From address, likely specifying the user nobody or www Because of the way PHP’s mail

function is implemented on Unix systems, the default sender will appear as the same

user under which the server daemon process is operating You can change this default, as

is demonstrated in the next example

Taking Advantage of PEAR: Mail and Mail_Mime

While it’s possible to use the mail() function to perform more complex operations

such as sending to multiple recipients, annoying users with HTML-formatted e-mail,

or including attachments, doing so can be a tedious and error-prone process However,

the Mail (http://pear.php.net/package/Mail) and Mail_Mime (http://pear.php.net/

package/Mail_Mime) PEAR packages make such tasks a breeze These packages work

in conjunction with one another: Mail_Mime creates the message, and Mail sends it

This section introduces both packages

Installing Mail and Mail_Mime

To take advantage of Mail and Mail_Mime, you’ll first need to install both packages To

do so, invoke PEAR and pass along the following arguments:

Trang 18

414 C H A P T E R 1 6 ■ N E T W O R K I N G

%>pear install Mail Mail_Mime

Execute this command and you’ll see output similar to the following:

Starting to download Mail-1.1.13.tgz (17,527 bytes)

done: 17,527 bytes

downloading Mail_Mime-1.3.1.tgz

Starting to download Mail_Mime-1.3.1.tgz (16,481 bytes)

done: 16,481 bytes

install ok: channel://pear.php.net/Mail_Mime-1.3.1

install ok: channel://pear.php.net/Mail-1.1.13

Sending an E-mail with Multiple Recipients

Using Mime and Mime_Mail to send an e-mail to multiple recipients requires that you identify the appropriate headers in an array After instantiating the Mail_Mime class you call the headers() method and pass in this array, as is demonstrated in this example:

// Recipient Name and E-mail Address

$name = "Jason Gilmore";

Trang 19

// Instantiate Mail_mime Class

$mimemail = new Mail_mime();

// Create New Instance of Mail Class

$email =& Mail::factory('mail');

// Send the E-mail!

$email->send($recipient, $mailheaders, $message) or die("Can't send

message!");

?>

Sending an HTML-Formatted E-mail

Although many consider HTML-formatted e-mail to rank among the Internet’s greatest

annoyances, how to send it is a question that comes up repeatedly Therefore, it seems

prudent to offer an example and hope that no innocent recipients are harmed as a result

Despite the widespread confusion surrounding this task, sending an

HTML-formatted e-mail is actually quite easy Consider Listing 16-2, which creates and sends

an HTML-formatted message

Trang 20

// Recipient Name and E-mail Address

$name = "Jason Gilmore";

Trang 21

C H A P T E R 1 6 ■ N E T W O R K I N G 417

// Instantiate Mail_mime Class

$mimemail = new Mail_mime();

// Create New Instance of Mail Class

$email =& Mail::factory('mail');

// Send the E-mail Already!

$email->send($recipient, $mailheaders, $message) or die("Can't send

message!");

?>

Executing this script results in an e-mail that looks like that shown in Figure 16-1

Because of the differences in the way HTML-formatted e-mail is handled by the

myriad of mail clients out there, consider sticking with plain-text formatting for

such matters

Figure 16-1 An HTML-formatted e-mail

Trang 22

418 C H A P T E R 1 6 ■ N E T W O R K I N G

Sending an Attachment

The question of how to include an attachment with a programmatically created e-mail often comes up Doing so with Mail_Mime is a trivial matter Just call the Mail_Mime object’s addAttachment() method, passing in the attachment name and extension, and identifying its content type:

$mimemail->addAttachment('inventory.pdf', 'application/pdf');

Common Networking Tasks

Although various command-line applications have long been capable of performing the networking tasks demonstrated in this section, offering a means for carrying them out via the Web certainly can be useful For example, at work we host a variety of Web-based applications within our intranet for the IT support department employees to use when they are troubleshooting a networking problem but don’t have an SSH client handy In addition, these applications can be accessed via Web browsers found on most modern wireless PDAs Finally, although the command-line counterparts are far more powerful and flexible, viewing such information via the Web is at times simply more convenient Whatever the reason, it’s likely you could put to good use some of the applications found in this section

Note Several examples in this section use the system() function This function is introduced in Chapter 10

Trang 23

The preceding code should be fairly straightforward except for perhaps the system call

to killall This is necessary because the command executed by the system call will

continue to execute if the user ends the process prematurely Because ending

execu-tion of the script within the browser will not actually stop the process for execuexecu-tion

on the server, you need to do it manually

Sample output follows:

PING www.example.com (192.0.34.166) from 123.456.7.8 : 56(84) bytes of data

64 bytes from www.example.com (192.0.34.166): icmp_seq=0 ttl=255 time=158 usec

64 bytes from www.example.com (192.0.34.166): icmp_seq=1 ttl=255 time=57 usec

64 bytes from www.example.com (192.0.34.166): icmp_seq=2 ttl=255 time=58 usec

www.example.com ping statistics

-5 packets transmitted, 3 packets received, 0% packet loss

round-trip min/avg/max/mdev = 0.048/0.078/0.158/0.041 ms

PHP’s program execution functions are great because they allow you to take

advantage of any program installed on the server that has the appropriate

permis-sions assigned

Creating a Port Scanner

The introduction of fsockopen() earlier in this chapter is accompanied by a

demon-stration of how to create a port scanner However, like many of the tasks introduced

in this section, this can be accomplished much more easily using one of PHP’s program

execution functions The following example uses PHP’s system() function and the

Nmap (network mapper) tool:

Trang 24

A snippet of the sample output follows:

Starting nmap V 4.11 ( www.insecure.org/nmap/ )

Interesting ports on (209.51.142.155):

(The 1500 ports scanned but not shown below are in state: closed)

Port State Service

22/tcp open ssh

80/tcp open http

110/tcp open pop-3

111/tcp filtered sunrpc

Creating a Subnet Converter

You’ve probably at one time scratched your head trying to figure out some obscure network configuration issue Most commonly, the culprit for such woes seems to center on a faulty or an unplugged network cable Perhaps the second most common problem is a mistake made when calculating the necessary basic network ingredients:

IP addressing, subnet mask, broadcast address, network address, and the like To remedy this, a few PHP functions and bitwise operations can be coaxed into doing the calculations for you When provided an IP address and a bitmask, Listing 16-3 calculates several of these components

Trang 25

C H A P T E R 1 6 ■ N E T W O R K I N G 421

Listing 16-3 A Subnet Converter

<form action="listing16-3.php" method="post">

<p>

IP Address:<br />

<input type="text" name="ip[]" size="3" maxlength="3" value="" />

<input type="text" name="ip[]" size="3" maxlength="3" value="" />

<input type="text" name="ip[]" size="3" maxlength="3" value="" />

<input type="text" name="ip[]" size="3" maxlength="3" value="" />

</p>

<p>

Subnet Mask:<br />

<input type="text" name="sm[]" size="3" maxlength="3" value="" />

<input type="text" name="sm[]" size="3" maxlength="3" value="" />

<input type="text" name="sm[]" size="3" maxlength="3" value="" />

<input type="text" name="sm[]" size="3" maxlength="3" value="" />

// Concatenate the IP form components and convert to IPv4 format

$ip = implode('.', $_POST['ip']);

$ip = ip2long($ip);

// Concatenate the netmask form components and convert to IPv4 format

$netmask = implode('.', $_POST['sm']);

$netmask = ip2long($netmask);

// Calculate the network address

$na = ($ip & $netmask);

// Calculate the broadcast address

$ba = $na | (~$netmask);

Trang 26

422 C H A P T E R 1 6 ■ N E T W O R K I N G

// Convert the addresses back to the dot-format representation and display echo "Addressing Information: <br />";

echo "<ul>";

echo "<li>IP Address: " long2ip($ip)."</li>";

echo "<li>Subnet Mask: " long2ip($netmask)."</li>";

echo "<li>Network Address: " long2ip($na)."</li>";

echo "<li>Broadcast Address: " long2ip($ba)."</li>";

echo "<li>Total Available Hosts: ".($ba - $na - 1)."</li>";

echo "<li>Host Range: " long2ip($na + 1)." - "

long2ip($ba - 1)."</li>";

echo "</ul>";

}

?>

Consider an example If you supply 192.168.1.101 as the IP address and

255.255.255.0 as the subnet mask, you should see the output shown in Figure 16-2

Figure 16-2. Calculating network addressing

Testing User Bandwidth

Although various forms of bandwidth-intensive media are commonly used on today’s Web sites, keep in mind that not all users have the convenience of a high-speed network connection at their disposal You can automatically test a user’s network speed with PHP by sending the user a relatively large amount of data and then noting the time it takes for transmission to complete

Trang 27

C H A P T E R 1 6 ■ N E T W O R K I N G 423

To do this, create the datafile that will be transmitted to the user This can be

anything, really, because the user will never actually see the file Consider creating it

by generating a large amount of text and writing it to a file For example, this script will

generate a text file that is roughly 1.5MB in size:

Trang 28

424 C H A P T E R 1 6 ■ N E T W O R K I N G

// Calculate the time taken to send the data

$duration = $stop - $start;

// Divide the file size by the number of seconds taken to transmit it $speed = round($fsize / $duration,2);

// Display the calculated speed in Kilobytes per second

echo "Your network speed: $speed KB/sec.";

?>

Executing this script produces output similar to the following:

Your network speed: 59.91 KB/sec

Summary

Many of PHP’s networking capabilities won’t soon replace those tools already offered on the command line or other well-established clients Nonetheless, as PHP’s command-line capabilities continue to gain traction, it’s likely you’ll quickly find a use for some

of the material presented in this chapter, perhaps the e-mail dispatch capabilities if nothing else

The next chapter introduces one of the most powerful examples of how to use PHP effectively with other enterprise technologies, showing you just how easy it is to interact with your preferred directory server using PHP’s LDAP extension

Trang 29

■ ■ ■

C H A P T E R 1 7

PHP and LDAP

As corporate hardware and software infrastructures expanded throughout the last

decade, IT professionals found themselves overwhelmed with the administrative

overhead required to manage the rapidly growing number of resources being added to

the enterprise Printers, workstations, servers, switches, and other miscellaneous

network devices all required continuous monitoring and management, as did user

resource access and network privileges

Quite often the system administrators cobbled together their own internal modus

operandi for maintaining order, systems that all too often were poorly designed,

inse-cure, and nonscalable An alternative but equally inefficient solution involved the

deployment of numerous disparate systems, each doing its own part to manage some

of the enterprise, yet coming at a cost of considerable overhead because of the lack of

integration The result was that both users and administrators suffered from the absence

of a comprehensive management solution, at least until directory services came along.

Directory services offer system administrators, developers, and end users alike a

consistent, efficient, and secure means for viewing and managing resources such as

people, files, printers, and applications The structure of these read-optimized data

repositories often closely models the physical corporate structure, an example of

which is depicted in Figure 17-1

Numerous leading software vendors have built flagship directory services products

and indeed centered their entire operations around such offerings The following are just

a few of the more popular products:

• Fedora Directory Server: http://directory.fedoraproject.org/

• Microsoft Active Directory: http://www.microsoft.com/activedirectory/

• Novell eDirectory: http://www.novell.com/products/edirectory/

• Oracle Collaboration Suite: http://www.oracle.com/collabsuite/

Trang 30

426 C H A P T E R 1 7 ■ P H P A N D L D A P

Figure 17-1 A model of the typical corporate structure

All widely used directory services products depend heavily upon an open

specifi-cation known as the Lightweight Directory Access Protocol, or LDAP In this chapter,

you will learn how easy it is to talk to LDAP via PHP’s LDAP extension In the end, you’ll possess the knowledge necessary to begin talking to directory services via your PHP applications

Because an introductory section on LDAP wouldn’t be nearly enough to do the topic justice, it’s assumed you’re reading this chapter because you’re already a knowledgeable LDAP user and are seeking more information about how to communi-cate with your LDAP server using the PHP language If you are, however, new to the topic, consider taking some time to review the following online resources before continuing:

LDAP v3 specification (http://www.ietf.org/rfc/rfc3377.txt): The official

specification of Lightweight Directory Access Protocol Version 3

The Official OpenLDAP Web site (http://www.openldap.org/): The official Web

site of LDAP’s widely used open source implementation

IBM LDAP Redbooks (http://www.redbooks.ibm.com/): IBM’s free 700+ page

introduction to LDAP

Trang 31

C H A P T E R 1 7 ■ P H P A N D L D A P 427

Using LDAP from PHP

PHP’s LDAP extension seems to be one that has never received the degree of

atten-tion it deserves Yet it offers a great deal of flexibility, power, and ease of use, three

traits developers yearn for when creating the often complex LDAP-driven applications

This section is devoted to a thorough examination of these capabilities, introducing the

bulk of PHP’s LDAP functions and weaving in numerous hints and tips on how to

make the most of PHP/LDAP integration

Note The examples found throughout this chapter use an LDAP server made available for testing

purposes by the OpenLDAP project However, because the data found on this server is likely to change

over time, the sample results are contrived Further, read-only access is available, meaning you will not

be able to insert, modify, or delete data as demonstrated later in this chapter Therefore, to truly

under-stand the examples, you’ll need to set up your own LDAP server or be granted administrator access to

an existing server For Linux, consider using OpenLDAP (http://www.openldap.org/) For Windows,

numerous free and commercial solutions are available, although Lucas Bergman’s OpenLDAP binaries for

Windows seem to be particularly popular See http://www.bergmans.us/ for more information

Connecting to an LDAP Server

The ldap_connect() function establishes a connection to an LDAP server identified

by a specific host name and optionally a port number Its prototype follows:

resource ldap_connect([string hostname [, int port]])

If the optional port parameter is not specified, and the ldap:// URL scheme

pref-aces the server or the URL scheme is omitted entirely, LDAP’s standard port 389 is

assumed If the ldaps:// scheme is used, port 636 is assumed If the connection is

successful, a link identifier is returned; on error, FALSE is returned A simple usage

example follows:

<?php

$host = "ldap.openldap.org";

$port = "389";

$connection = ldap_connect($host, $port)

or die("Can't establish LDAP connection");

?>

Trang 32

428 C H A P T E R 1 7 ■ P H P A N D L D A P

Although Secure LDAP (LDAPS) is widely deployed, it is not an official specification OpenLDAP 2.0 does support LDAPS, but it’s actually been deprecated in favor of

another mechanism for ensuring secure LDAP communication known as Start TLS.

Securely Connecting Using the Transport Layer Security Protocol

Although not a connection-specific function per se, ldap_start_tls() is introduced

in this section nonetheless because it is typically executed immediately after a call to ldap_connect() if the developer wants to connect to an LDAP server securely using the Transport Layer Security (TLS) protocol Its prototype follows:

boolean ldap_start_tls(resource link_id)

There are a few points worth noting regarding this function:

• TLS connections for LDAP can take place only when using LDAPv3 Because PHP uses LDAPv2 by default, you need to declare use of version 3 specifically, by using ldap_set_option() before making a call to ldap_start_tls()

• You can call the function ldap_start_tls() before or after binding to the tory, although calling it before makes much more sense if you’re interested in protecting bind credentials

Binding to the LDAP Server

Once a successful connection has been made to the LDAP server (see the earlier section “Connecting to an LDAP Server”), you need to pass a set of credentials under the guise of which all subsequent LDAP queries will be executed These credentials

Trang 33

C H A P T E R 1 7 ■ P H P A N D L D A P 429

include a username of sorts, better known as an RDN, or Relative Distinguished Name,

and a password To do so, you use the ldap_bind() function Its prototype follows:

boolean ldap_bind(resource link_id [, string rdn [, string pswd]])

Although anybody could feasibly connect to the LDAP server, proper credentials

are often required before data can be retrieved or manipulated This feat is

accom-plished using ldap_bind() This function requires at minimum the link_id returned

from ldap_connect() and likely a username and password denoted by rdn and pswd,

respectively An example follows:

<?php

$host = "ldap.openldap.org";

$port = "389";

$connection = ldap_connect($host, $port)

or die("Can't establish LDAP connection");

ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);

ldap_bind($connection, $username, $pswd)

or die("Can't bind to the server.");

?>

Note that the credentials supplied to ldap_bind() are created and managed within

the LDAP server and have nothing to do with any accounts residing on the server or

the workstation from which you are connecting Therefore, if you are unable to connect

anonymously to the LDAP server, you need to talk to the system administrator to

arrange for an appropriate account

Also, demonstrated in the previous example, to connect to the test ldap.openldap.org

server you’ll need to execute ldap_set_option() because only the version 3 protocol

is accepted

Closing the LDAP Server Connection

After you have completed all of your interaction with the LDAP server, you should

clean up after yourself and properly close the connection One function, ldap_unbind(),

is available for doing just this Its prototype follows:

boolean ldap_unbind(resource link_id)

Trang 34

or die("Can't establish LDAP connection");

// Bind to the server

ldap_bind($connection) or die("Can't bind to LDAP.");

// Execute various LDAP-related commands

// Close the connection

Retrieving LDAP Data

Because LDAP is a read-optimized protocol, it makes sense that a bevy of useful data search and retrieval functions would be offered within any implementation Indeed, PHP offers numerous functions for retrieving directory information Those functions are examined in this section

Searching for One or More Records

The ldap_search() function is one you’ll almost certainly use on a regular basis when creating LDAP-enabled PHP applications because it is the primary means for searching a directory based on a specified filter Its prototype follows:

Trang 35

C H A P T E R 1 7 ■ P H P A N D L D A P 431

resource ldap_search(resource link_id, string base_dn, string filter

[, array attributes [, int attributes_only [, int size_limit

[, int time_limit [int deref]]]]])

A successful search returns a result set, which can then be parsed by other

func-tions, which are introduced later in this section; a failed search returns FALSE Consider

the following example in which ldap_search() is used to retrieve all users with a first

name beginning with the letter A:

$results = ldap_search($connection, "dc=OpenLDAP,dc=Org", "givenName=A*");

Several optional attributes tweak the search behavior The first, attributes, allows you

to specify exactly which attributes should be returned for each entry in the result set

For example, if you want to obtain each user’s last name and e-mail address, you

could include these in the attributes list:

$results = ldap_search($connection, "dc=OpenLDAP,dc=Org", "givenName=A*",

"surname,mail");

Note that if the attributes parameter is not explicitly assigned, all attributes will

be returned for each entry, which is inefficient if you’re not going to use all of them

If the optional attributes_only parameter is enabled (set to 1), only the attribute

types are retrieved You might use this parameter if you’re only interested in knowing

whether a particular attribute is available in a given entry and you’re not interested in

the actual values If this parameter is disabled (set to 0) or omitted, both the attribute

types and their correspondinsg values are retrieved

The next optional parameter, size_limit, can limit the number of entries retrieved

If this parameter is disabled (set to 0) or omitted, no limit is set on the retrieval count The

following example retrieves both the attribute types and corresponding values of

the first five users with first names beginning with A:

$results = ldap_search($connection, "dc=OpenLDAP,dc=Org", "givenName=A*", 0, 5);

Enabling the next optional parameter, time_limit, places a limit on the time, in

seconds, devoted to a search Omitting or disabling this parameter (setting it to 0)

results in no set time limit, although such a limit can be (and often is) set within the

LDAP server configuration The next example performs the same search as the previous

example, but limits the search to 30 seconds:

$results = ldap_search($connection, "dc=OpenLDAP,dc=Org", "givenName=A*", 0, 5,

30);

Trang 36

432 C H A P T E R 1 7 ■ P H P A N D L D A P

The eighth and final optional parameter, deref, determines how aliases are handled Aliases are out of the scope of this chapter, although you’ll find plenty of information about the topic online

Doing Something with Returned Records

Once one or several records have been returned from the search operation, you’ll probably want to do something with the data, either output it to the browser or perform other actions One of the easiest ways to do this is through the ldap_get_entries() function, which offers an easy way to place all members of the result set into a multi-dimensional array Its prototype follows:

array ldap_get_entries(resource link_id, resource result_id)

The following list offers the numerous items of information that can be derived from this array:

return_value["count"]: The total number of retrieved entries

return_value[n]["dn"]: The Distinguished Name (DN) of the nth entry in the

result set

return_value[n]["count"]: The total number of attributes available in the nth

entry of the result set

return_value[n]["attribute"]["count"]: The number of items associated with

the nth entry of attribute

return_value[n]["attribute"][m]: The mth value of the nth entry attribute return_value[n][m]: The attribute located in the nth entry’s mth position

Trang 37

C H A P T E R 1 7 ■ P H P A N D L D A P 433

ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);

ldap_bind($connection)

or die("Can't bind to the server.");

// Retrieve all records of individuals having first name

// beginning with letter K

$results = ldap_search($connection, $dn, "givenName=K*");

// Dump records into array

$entries = ldap_get_entries($connection, $results);

// Determine how many records were returned

Executing this script produces output similar to this:

Kyle Billingsley (billingsley@example.com)

Kurt Kramer (kramer@example.edu)

Kate Beckingham (beckingham.2@example.edu)

Retrieving a Specific Entry

You should use the ldap_read() function when you’re searching for a specific entry

and can identify that entry by a particular DN Its prototype follows:

resource ldap_read(resource link_id, string base_dn, string filter

[, array attributes [, int attributes_only [, int size_limit

[, int time_limit [int deref]]]]])

Trang 38

434 C H A P T E R 1 7 ■ P H P A N D L D A P

For example, to retrieve the first and last name of a user identified only by his user

ID, you might execute the following:

// Bind to the LDAP server

ldap_bind($connection) or die("Can't bind to the server.");

// Retrieve the desired information

$results = ldap_read($connection, $dn, '(objectclass=person)',

array("givenName", "sn"));

// Retrieve an array of returned records

$entry = ldap_get_entries($connection, $results);

// Output the first and last names

printf("First name: %s <br />", $entry[0]["givenname"][0]);

printf("Last name: %s <br />", $entry[0]["sn"][0]);

// Close the connection

ldap_unbind($connection);

?>

This returns the following:

Trang 39

C H A P T E R 1 7 ■ P H P A N D L D A P 435

First Name: William

Last Name: Gilmore

Counting Retrieved Entries

It’s often useful to know how many entries are retrieved from a search PHP offers one

explicit function for accomplishing this, ldap_count_entries() Its prototype follows:

int ldap_count_entries(resource link_id, resource result_id)

The following example returns the total number of LDAP records representing

indi-viduals having a last name beginning with the letter G:

$results = ldap_search($connection, $dn, "sn=G*");

$count = ldap_count_entries($connection, $results);

echo "<p>Total entries retrieved: $count</p>";

This returns the following:

Total entries retrieved: 45

Sorting LDAP Records

The ldap_sort() function can sort a result set based on any of the returned result

attributes Sorting is carried out by simply comparing the string values of each entry,

rearranging them in ascending order Its prototype follows:

boolean ldap_sort(resource link_id, resource result, string sort_filter)

An example follows:

<?php

// Connect and bind

$results = ldap_search($connection, $dn, "sn=G*", array("givenName", "sn"));

// Sort the records by the user's first name

ldap_sort($connection, $results, "givenName");

Trang 40

Inserting LDAP Data

Inserting data into the directory is as easy as retrieving it In this section, two of PHP’s LDAP insertion functions are introduced

Adding a New Entry

You can add new entries to the LDAP directory with the ldap_add() function Its prototype follows:

boolean ldap_add(resource link_id, string dn, array entry)

An example follows, although keep in mind this won’t execute properly because you don’t possess adequate privileges to add users to the OpenLDAP directory:

<?php

/* Connect and bind to the LDAP server */

$dn = "ou=People,dc=OpenLDAP,dc=org";

$entry["displayName"] = "John Wayne";

$entry["company"] = "Cowboys, Inc.";

Ngày đăng: 09/08/2014, 14:21

TỪ KHÓA LIÊN QUAN