Client 1 - Connecting to the Server

   

Client 1 ”Connecting to the Server

The first PHP/PostgreSQL client establishes a connection to a PostgreSQL server and displays the name of the database to which you connect. Listing 15.4 show the client1a.php script.

Listing 15.4 client1a.php
 1 <?php  2   //Filename: client1a.php  3  4   $connect_string = "dbname=movies user=bruce";  5  6   $db_handle = pg_connect( $connect_string );  7  8   echo "<HTML>\n";  9   echo   "<HEAD>\n"; 10   echo     "<TITLE>client1</TITLE>\n"; 11   echo   "<BODY>\n"; 12   echo     "<CENTER>"; 13   echo       "Connected to " . pg_dbname( $db_handle ); 14   echo     "</CENTER>\n"; 15   echo   "</BODY>\n"; 16   echo "</HTML>"; 17 ?> 

This script connects to a database whose name is hard-coded in the script (at line 4). At line 6, you attempt to make a connection by calling the pg_connect() function. pg_connect() returns a database handle (also called a database resource ). Many of the PostgreSQL- related functions require a database handle, so you need to capture the return value in a variable ( $db_handle ).

PHP's pg_connect() function comes in two flavors:

 $db_handle = pg_connect(  connection-string  ); $db_handle = pg_connect(  host  ,  port  [,  options  [,  tty  ]],  database  ); 

In the first form (the one you used in client1.php ), you supply a connection string that contains a list of property = value pairs [1] . Table 15.1 lists the properties that can appear in a pg_connect() connection string. In client1.php , you specified two properties: dbname=movies and user=bruce .

[1] When you call pg_connect() with a single argument, PHP calls the PQconnectdb() function from PostgreSQL's libpq API. PHP is yet another PostgreSQL API implemented in terms of libpq.

Table 15.1. Connection Attributes

Connect-string Property

Environment Variable

Example

user

PGUSER

user=korry

password

PGPASSWORD

password=cows

dbname

PGDATABASE

dbname=accounting

host

PGHOST

host=jersey

hostaddr

PGHOSTADDR

hostaddr=127.0.0.1

port

PGPORT

port=5432

If you don't specify one or more of the connect-string properties, default values are derived from the environment variables shown in Table 15.1. If necessary, pg_connect() will use hard-coded default values for the host ( localhost ) and port ( 5432 ) properties. The second form for the pg_connect() function is a bit more complex. In this form, you can provide three, four, or five parameters. The first two parameters are always treated as a hostname and port number, respectively. The last parameter is always treated as a database name. If you pass four or five parameters, the third parameter is assumed to be a list of backend (server) options. If you pass five parameters, the fourth one is expected to be a tty name or filename to which the PostgreSQL server will write debugging information. Just in case you find that a little hard to follow, here are the valid combinations:

 $db_handle = pg_connect(  host  ,  port  ,  database  ); $db_handle = pg_connect(  host  ,  port  ,  options  ,  database  ); $db_handle = pg_connect(  host, port  ,  options  ,  tty  ,  databas  e ); 

You might have noticed that you can't specify the username and password using the multiparameter form of pg_connect() ”you have to use the PGUSER and PGPASSWORD environment variables. The tricky thing about using environment variables with PHP is that the variables come from the web server's environment. In other words, you have to set PGUSER and PGPASSWORD before you start the web server. Another option is to use the PHP's putenv() function:

 ... putenv( "PGUSER=korry" ); putenv( "PGPASSWORD=cows" ); $db_handle = pg_connect( NULL, NULL, NULL, NULL, "movies" ); ... 

I'm not very comfortable with the idea of leaving usernames and passwords sitting around in the web server's document tree. It's just too easy to make a configuration error that will let a surfer grab your PHP script files in plain-text form. If that happens, you've suddenly exposed your PostgreSQL password to the world.

A better solution is to factor the code that establishes a database connection into a separate PHP script and then move that script outside the web server's document tree. Listing 15.5 shows a more secure version of your basic PostgreSQL/PHP script.

Listing 15.5 client1b.php
 1 <?php  2   //Filename: client1b.php  3  4   include( "secure/my_connect_pg.php" );  5  6   $db_handle = my_connect_pg( "movies" );  7  8   echo "<HTML>\n";  9   echo   "<HEAD>\n"; 10   echo     "<TITLE>client1</TITLE>\n"; 11   echo   "<BODY>\n"; 12   echo     "<CENTER>"; 13   echo       "Connected to " . pg_dbname( $db_handle ); 14   echo     "</CENTER>\n"; 15   echo   "</BODY>\n"; 16   echo "</HTML>"; 17 ?> 

If you compare this to client1a.php , you'll see that you replaced the call to pg_connect() with a call to my_connect_pg() . You've also added a call to PHP's include() directive. The include() directive is similar to the #include directive found in most C programs: include( filename ) inlines the named file into the PHP script ( .php ). Now let's look at the my_connect_pg.php file (see Listing 15.6).

Listing 15.6 connect_pg.php
 1 <?php  2   // File:  my_connect_pg.php  3  4   function my_connect_pg( $dbname )  5   {  6     $connect_string  = "user=korry password=cows dbname=";  7     $connect_string .= $dbname;  8  9     return( pg_connect( $connect_string )); 10   } 11 ?> 

This script defines a function, named my_connect_pg() , which you can call to create a PostgreSQL connection. my_connect_pg() expects a single string argument, which must specify the name of a PostgreSQL database.

Notice that the username and password are explicitly included in this script.Place this script outside the web server's document tree so that it can't fall into the hands of a web surfer. The question is: Where should you put it? When you call the include() directive (or the related require() function), you can specify an absolute path or a relative path. An absolute path starts with a / (or drive name or backslash in Windows). A relative path does not. The PHP interpreter uses a search path (that is, a list of directory names ) to resolve relative pathnames. You can find the search path using PHP's ini_get() function:

 ... echo "Include path = " . ini_get( "include_path" ); ... 

The ini_get() function returns a variable defined in PHP's initialization file [2] ; in this case, the value of include_path . On my system, ini_get("include_path") returns " .:/usr/local/php ". PHP searches for include files in the current directory (that is, the directory that contains the including script), and then in /usr/local/php . If you refer back to Listing 15.5, you'll see that I am including secure/my_connect_pg.php . Combining the search path and relative pathname, PHP will find my include file in /usr/local/php/secure/my_connect_pg.php . The important detail here is that /usr/local/php is outside the web server's document tree ( /usr/local/htdocs ).

[2] You can find the PHP's initialization file using echo get_cfg_var( "cfg_file_path" ).

The my_connect_pg.php script not only secures the PostgreSQL password, it also gives you a single connection function that you can call from any script ”all you need to know is the name of the database that you want.

If everything goes well, the user will see the message "Connected to movies."

Let's see what happens when you throw a few error conditions at this script. First, try to connect to a nonexistent database (see Figure 15.3).

Figure 15.3. Connecting to a nonexistent database.

graphics/15fig03.gif

That's not a friendly error message. Let's see what happens when you try to connect to a database that does exist, but where the PostgreSQL server has been shut down (see Figure 15.4).

Figure 15.4. Connecting to a database that has been shut down.

graphics/15fig04.gif

Again, not exactly the kind of message that you want your users to see. In the next section, I'll show you how to intercept this sort of error and respond a little more gracefully.

   


PostgreSQL
PostgreSQL (2nd Edition)
ISBN: 0672327562
EAN: 2147483647
Year: 2005
Pages: 220
Authors: Korry Douglas

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net