spacer
Home News Links People Catalog
spacer
activepages
spacer

Last Lecture: Various and Asundried Intermediate PHP Concepts

Chosen from the suggested list by survey of class participants. The goal of tonight is to give you confidence in finding materials on
the Web and playing with them to learn (ideally doing something useful you need to do in the process).

PHP in Stylesheets

As a reminder that PHP can be used with any text-based language for dynamic presentation, we'll look at an example of how you
can change the stylesheet associated with a website based on calendar date.

You can drive the dynamic styling from any variable that changes anywhere on the Web. So, consider connecting your style sheet
to a back-end database (using the appropriate PHP database connection functions) or to an external web service. The following
example just uses the built-in clock on your server to access the current date and time to dynamically change the style of the
calendar based on those values. I put both the current_month and year into PHP's available $_SESSION[] array variable that
stays active throughout the current browser session. I then use the $year and $month values to change the definition of different
style attribute definitions for associated HTML content.

I change the style associated with the whole body of the calendar to set the font family of the text and background color for the page.

I change the color of those cells in the grid of the calendar month table that are not associated with days in the month (through the
class named <b>filler</b> that I've established in the HTML code).

Lastly, I change the font style for the calendar header I've identified with an id=cal_header attribute in the HTML code.

The take home message on this one is that you can change any of the text in a style sheet by placing it's definition within a block
of code associated with a PHP conditional function. In fact, you can change the text in *any* text-generated file with PHP - a CSS
being just one example of an unbounded number of languages (with XML, you can even create your own language and then change
it dynamically via PHP in its schema or the pages generated for use with the schema).

  <?php
      // putting the date and year values into session variables
      $_SESSION['month'] = date("n");
      $_SESSION['year'] = date("Y");
      // putting variables into normal variables
      $month = $_SESSION['month'];
      $year = $_SESSION['year'];
      //$month = 2;
      $month_name = date("M",mktime(0,0,0,$month,1,$year));
      $year = 2011;
      // gives the numerical value for the weekday falling on the 1st of month
      $firstDayNumber = date("w",mktime(0,0,0,$month,1,$year));
      // gives the numerical value for the weekday falling on the last day of the month
      $lastDayNumber = date("w", mktime(0,0,0,$month+1,0,$year));
      // gives the total number of days in the current month
      $numberOfDays = date("t",mktime(0,0,0,$month,1,$year));
  ?>

  <html>
  <head>
  <title>My Site with Styles By Date</title>
  </head>
  <style>

  body {
  <?php
      if($month< 3) {
      	echo 'background:#CCCCCC;font-family:Arial, Helvetica, sans-serif';
      } else if($month< 6) {
      	echo 'background:#FFDDDD;font-family:"Times New Roman", Times, serif';
      } else if($month< 9) {
      	echo 'background:#FFFF20;font-family:"Courier New", Courier, monospace';
      } else if($month< 12) {
      	echo 'background:#FFDD20;font-family:Georgia, "Times New Roman", Times, serif';
      } else {
      	echo 'background:#CCCCCC;font-family:Arial, Helvetica, sans-serif';
      }
  ?>

  }
  .filler {
  <?php
      if($month< 3) {
      	echo "background:#666666";
      } else if($month< 6) {
      	echo "background:#66444;";
      } else if($month< 9) {
      	echo "background:#666644";
      } else if($month< 12) {
      	echo "background:#664400";
      } else {
      	echo "background:#666666";
      }
  ?>

  }
  #cal_header {
  <?php
      if($month%2==0) { //If an even month
      	echo "font-weight:bold";
      } else {
      	echo "font-weight:100";
      }
  ?>
  }
  </style>
  <body>

  <table border="1" cellspacing="0" cellpadding="5">
  <tr>
  <td><b>--</b></td>

  <td align="center" colspan="5" id="cal_header"><?php echo $month_name.' '.$year ?></td>
  <td><b>--</b></td>

  </tr>
  <tr>
  <td><b>Su</b></td>
  <td><b>Mo</b></td>

  <td><b>Tu</b></td>
  <td><b>We</b></td>
  <td><b>Th</b></td>

  <td><b>Fr</b></td>
  <td><b>Sa</b></td>
  </tr>

  <tr>
  <?php
      $j=1;
      for($i=0; $i < $firstDayNumber; $i++) {
      	echo "<td class=filler> </td>";
      }
      $count = 0;
      for($j; $j < 7-$firstDayNumber+1; $j++) {
      	$count++;
      	echo "<td>$j</td>";
      }
      echo "</tr><tr>";
      for($k=$j; $k <= $numberOfDays ; $k++) {
      	$new_count++;
      	echo "<td>$k</td>";
      	if($new_count == 7)	{
      		echo "</tr>";
      		$new_count=0;
      	} // end of if statement
      }
      while ($new_count<7) {
      	$new_count++;
      	echo "<td class=filler> </td>";
      }
  ?>

  </table>
  </body>
  </html>

PHP with Scalable Vector Graphics (the SVG standard)

Let's try using PHP with Scalable Vector Graphics (SVG — see http://commons.wikimedia.org/wiki/SVG_examples).

In the example that follows, we are changing the look of two overlapping rectangles with rounded corners. I have created
two PHP variables, $stroke and $width to generate a new random value upon loading of the page each time. I have also
used the PHP predefined function rand() to randomly choose digits in a color attribute for the blue rounded rectangle (one
rand() call for each digit varying from 0 to 9. Any of the attribute values in SVG can be dynamically changed via any PHP
pre-defined function. Hopefully, one set of functions you would find especially useful are the functions that integrate with a
mysql back-end relational database management system (as in our MAMP exposure in class).

Go ahead, throw this PHP code into the source of a file you call DynamicSVG.php. Drop it in your MAMP Web server. Access
the page in your browser and reload multiple times to see how the presentation changes based on the rand() function calls.

<?php
  header('Content-Type: text/xml; charset=utf-8');
  $stroke=rand(1,10);
  $width=rand(200,400);
  echo '<?xml version="1.0"?>';
  echo '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
  echo '<svg xmlns="http://www.w3.org/2000/svg" width="750" height="750">';
  echo '  <rect x="80" y="60" width="'.$width.'" height="'.rand(200,640).'" rx="20" style="fill:#ff0000; stroke:#000000;stroke-width:'.$stroke.'px;" /> ';
  echo '  <rect x="140" y="120" width="'.($width+50).'" height="250" rx="40" style="fill:#'.rand(0,9).rand(0,9).rand(0,9).rand(0,9).'ff; stroke:#000000; stroke-width:2px; fill-opacity:0.7;" />';
  echo '</svg>';
?>
PHP with 3D Modeling Content (the X3D standard)

Let's try using PHP with HTML5 integration with X3D (see http://www.x3dom.org/?page_id=5):

<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<meta http-equiv='Content-Type' content='text/html;charset=utf-8'/>
<link rel='stylesheet' type='text/css' href='http://x3dom.org/x3dom/example/x3dom.css'/>
</head>
<body style="font-size: 14px;">
<h1>X3D</h1>
<p> X3D is an open standard for 3D content delivery.
<h2>What is X3D?</h2>
<p>X3D is a royalty-free open standards file format and run-time architecture to represent and communicate 3D scenes and objects using XML. It is an ISO ratified standard that provides a system for the storage, retrieval and playback of real time graphics content embedded in applications, all within an open architecture to support a wide array of domains and user scenarios.
</p><p>
X3D has a rich set of componentized features that can tailored for use in engineering and scientific visualization, CAD and architecture, medical visualization, training and simulation, multimedia, entertainment, education, and more.
</p><p>
The development of real-time communication of 3D data across all applications and network applications has evolved from its beginnings as the Virtual Reality Modeling Language (VRML) to the considerably more mature and refined X3D standard.
</p>
<p>
You can read more about this topic on <a href="http://www.web3d.org/about/overview/">web3d.org</a>.</p>
<X3D xmlns='http://www.web3d.org/specifications/x3d-namespace' showStat='false' showLog='false' x='0px' y='0px' width='1000px' height='600px' style='border: 0px; position:fixed; top:0px; left:0px; z-index:1;'>
   <Scene DEF='scene'>
      <transform id="root" scale="<?php echo (rand(5,20)/10.0); ?> 1 1">
         <Shape>
            <Appearance>
            <?php
            $red=rand(0,10);
            $green=rand(0,10);
            $blue=rand(0,10);
            echo "<Material diffuseColor='0.8 0.2 0.2' />";
            echo "\n";
            ?>
            </Appearance>
         <Sphere DEF='sphere'/>
      </Shape>
   </transform>
   <transform id="root" translation="<?php echo (rand(15,40)/-10.0); ?> 0 0">
      <Shape>
         <Appearance>
            <?php
            $red=rand(0,10);
            $green=rand(0,10);
            $blue=rand(0,10);
            echo "<Material diffuseColor='".($red/10)." ".($green/10)." ".($blue/10)."' />";
            echo "\n";
            ?>
         </Appearance>
         <Box DEF='box'/>
      </Shape>
   </transform>
</Scene>
</X3D>
<script type="text/javascript" src="http://x3dom.org/x3dom/example/x3dom.js"></script>

</body>
</html>



Integrating an External Web Service

Let's integrate the ISBN Book Database search Web Service into a dynamic Web page with PHP:

First we find information about the service from the provider. Hopefully, they have a useful website to help us along. They do: https://isbndb.com/docs/api/

We have to register for an access key in order to use their service (a reasonable enough request so they can track us for service load balancing).
Use the e-mail verification process they provide to get yourself a key. I used my e-mail account to get a key string back as A6WFYFWT.
I then built a handler class to manage reqests to the database. Note how all that is really necessary is the base URL, the access key, the
operation type, and the value to search upon for that operation. You can verify the service works with your key before implementing it in PHP.
Just put the URL location as http://isbndb.com/api/books.xml?access_key=A6WFYFWT&index1=isbn&value1=9780060852566 in the
address bar of your favorite browser. The service returns a valid XML document with your search response.

You can design a handler class anyway you want (and, of course, you don't even have to use a class if you just want to create free-standing functions).
I have chosen to define two constant variables (use PHP's define() pre-defined function for this purpose). I define class variables for them both in the
constructor of my class. I create a single method I call request() to process requests to the ISBNdb search service. And, within that method, I generated
the URL as a concatenation of partial URL string components and the variables used in the handler. PHP's @file_get_contents() pre-defined function lets
me get back the XML that is generated by the service. An example of using the service handling class follows the class declaration. Just three lines to
create a handler object, pass in my search parameters to the request method, and print out the results to whatever PHP-enabled page I put the code into.
By now, you should be able to create your own form with the two parameters so that someone can change the request type and the request parameter
dynamically. Give it a try!

<?php

// This could go in a separate configuration file
define( 'ISBN_ACCESS_KEY', 'A6WFYFWT' ); //Generated by owner (me)
define( 'ISBN_REQUEST_URL', 'http://isbndb.com/api/books.xml' );

class ISBNHandler {

    var $pubKey, $requestURL;

    function __construct() {
        $this->pubKey = ISBN_ACCESS_KEY;
        $this->requestURL = ISBN_REQUEST_URL;
    }

    function request($operation, $data ) {
        $url = "{$this->requestURL}?access_key={$this->pubKey}&index1={$operation}&value1={$data}";
        $response = @file_get_contents( $url );
        return $response;
    }
}

//To use it
$ih = new ISBNHandler;
$items = $ih->request( 'isbn', '1575211939');
echo $items;

?>

The Amazon Product Advertising API

Two weeks ago I provided a link to an example of creating an API Handler in PHP for an Amazon Product Advertising API.
As I investigated the site further (and you may have as well) for Fall 2013, I saw that the Amazon Web Service now requires the user to be either a registered Amazon Product Advertising API
Developer or an Associate Seller in the Amazon Business Services group. The API has grown significantly since I last played with it which likely attests to some rich feature sets
with a strong, popular following among developers.

As a result, I will just make three general comments about the Amazon example:

1. The API provides a nice on-line reference guide (see the Reference API link in the second column of the table as you scroll down) to help you learn about what's available and how to implement the available services on in your own code.

2. The handler code uses the infamous PHP built-in array type for managing the pairs of attributes and values that need to be sent through the CGI-compliant portion of the service request URL.

3. PHP is a wonderfully popular language for connecting to external Web services in order to gain access to dynamic data that is better managed by an other organization. The Web Service Definition Language (WSDL) attempts to provide a standard way to advertise proper use of Web Services and available Web Services Directories are becoming even more popular on the Web for helping you discover services your Web solutions may benefit from using. That said, Web Service implentations can be implemented in many other languages as well (my first language for doing so was Java, for example). There are two skills involved: Learning to read API documentation and learning to code solutions - both are highly valuable to a organizational development team.

Here is an example of using a weather API that won't require we buy a key to use:

The Weather API documentation is at:http://openweathermap.org/current

Let's go over it together in the upcoming weeks as well as go over all the examples of the code in the video...

As we will focus on in upcoming weeks, we can pass variable values into our PHP code via the browser's location field (where you type in a URL). Here's a version of a Weather API example using the Common Gateway Interface to pass city and state information to PHP I have put up on my domain:

If I request the following URL:
http://bdcampbell.net/dynphp/weather.php?city=Nashville&state=tn

I get back current temperature and sunrise (time based on UTC time zone which is five hours ahead of CDT) for Nashville, Tennessee.

The code I use to embed it in a PHP document is:
<!doctype html>
<html>
<head>
<title>Weather API Example</title>
<style>
body { background-color:yellow; }
</style>
</head>
<body>
<?php
//API Key: 9c4b10bda32ae8ecd9e0783b518fc8ed
//example use: http://localhost:8888/weather.php?city=Providence&state=ri
$city=$_GET["city"];
$state=$_GET["state"];
$weather_data = file_get_contents('http://api.openweathermap.org/data/2.5/weather?q='.$city.','.$state.'&appid=9c4b10bda32ae8ecd9e0783b518fc8ed');
echo $weather_data;
//echo $data['temp'];
echo '<hr/>';
$json = json_decode($weather_data, true);
//T(F) = T(K)  9/5 - 459.67
echo "Current Weather in ".$city.": ".($json['main']['temp'] * 9/5 -459.67)."°F<br/>";
$ts=$json['sys']['sunrise'];
$sunrise = new DateTime("@$ts");
echo "Next Sunrise at: ".date_format($sunrise, 'Y-m-d H:i:s')."\n";
?>


Consider playing with another published API you find on the Web and sharing your results via a Forum post. I find the open movie database to be straight-forward based on what we did last night:

Example use: http://www.omdbapi.com/?t=Poltergeist

Documentation: http://www.omdbapi.com/

Generating JavaScript with PHP

Since JavaScript is also a text-based language, we can use PHP to create dynamic JavaScript. There will be times when you
need to use other languages than PHP because you want to get a desired effect on the client side (PHP is a server-side only language).
JavaScript can be quite useful for realtime activities involving the browser, playing sounds and manipulating graphics with the mouse
or keyboard. The downside of JavaScript is clients/surfers can somewhat easily turn off or disable javascript with their browser and
potentially render your script inoperable. Ah, but there are workarounds for this!

For some websites, the flow of session processing is one-directional and you may want to prevent surfers from going back to a
previous page in the session with their browser. Some adventure games might not want you to go back to a previous state in
the current session, for example. We can use PHP to reject the use of the forward and backward buttons on the browser, as well
as the URL locator but we have to take control of the session window through a pop-up. The code to generate the pop-up is
available as a JavaScript window method called open() and you can use the code to pop a window from within an HTML or
PHP-enabled page. Be sure to save the following as example2.php if you want the referral to work as intended (and makes sure
the MAMP server port is 8888 - if not, change the 8888 to reference the port where your MAMP has installed the Web server (most
likely port 80, which is the default and not necessary to add explicitly if that is in fact the case).

Here is our code to start off the page sequence

  <?php 
  $page_number=1;
  ?>
  <html>
  <head>
  <script type="text/javascript">
  function nextpage()
  {
 	//alert("Function Call Works!");
	window.open('http://bdcampbell.net/dynphp/<?php echo $page_number; ?>.php', 'Page <?php echo $page_number; ?>', 'toolbar=no,status=no,width=640,height=480');
  }
  </script>

  </head>
  <body>
  Go to next page from correct place:
  <input type="button" value="Next Page" onclick="nextpage()" />

  </body>
  </html>

The URL to the page or script you will be launching goes in the first parameter slot, the name of the window second and then window generation options after that.
The value options for toolbar and status bar are simply yes or no. Yes would display the item, and no won't. The width and height control the size of the
window you want to create. Other options are available by checking a JavaScript manual for the window open() method. The receiving page checks for
the referring URL and if it is coming from the correct place, allows the content for that page to appear including a button for continuing on to the next page.

The receiving page of the first button click checks to make sure the page has been referred to by http://localhost:8888/example2.php (the first page you provided
above). If so, it created the second page in the sequence and sets up the expectation to move on to the third.

<?php 
	$page_number=1;
?>

<html>
<head>
<title>My Site with Styles By Date</title>
<script>
function new_page() {
	window.open('http://bdcampbell.net/dynphp/<?php echo $page_number+1; ?>.php?pno=<?php echo $page_number+1; ?>','window_name', 'toolbar=no,status=no,width=640,height=480');
}
</script>

</head>
<body>
<?php
  if($_SERVER['HTTP_REFERER'] != "http://localhost:8888/example2.php")
  {
	exit("Sorry, you cannot access this page from here");
  }
?>
<HTML>
<BODY>
<center>You came to page one from a valid place, thank you!
</BODY>

</HTML>
<form name="pop_window">
	<input type="button" value="Next Page" onClick="window_name=new_page()">
</form>

</body>
</html>
The next page would continue in the same manner but with a different referral which at this point continues to be available as an increase in the pno attribute value
that is passed from page to page and accessed via the PHP $_REQUEST pre-defined array variable :
<?php
$page_number=$_REQUEST['pno'];
 ?>
<html>
<head>
<title>My Site with Styles By Date</title>

<script>
function new_page() {
	window.open('http://bdcampbell.net/dynphp/<?php $page_number+1 ?>.php?pno=<?php $page_number+1 ?>','window_name', 'toolbar=no,status=no,width=640,height=480');
}
</script>
</head>
<body>
<?php
if($_SERVER['HTTP_REFERER'] != "http://bdcampbell.net/dynphp/".($page_number-1).".php")
{
  echo $_SERVER['HTTP_REFERER'];
  //exit("Sorry, you cannot access this page from here");
}
?>

<HTML>
<BODY>
<center>You came to page two from a valid place, thank you!
</BODY>
</HTML>
<form name="pop_window">
<input type="button" value="Next Page" onClick="window_name=new_page()">

</form>
</body>
</html>

Using regular expressions to extract data

Let’s say you have a block of text like below and you want to extract out the all links from, you can use preg_match_all to do just that.

$content = 'He is going everywhere, 
<a href="http://www.bjmckay.com">B.J. McKay</a> and his 
best friend Bear. Rolling down to 
<a href="http://www.dallas.net">Dallas</a>, who is providing 
my palace, off to New Orleans or who knows where.';

The pattern you want to look for would be the link anchor pattern, like <a href=”(something)”>(something)</a>. The actual regular expression might look something like

$regex_pattern = '/<a href="(.*)">(.*)<\/a>/';

Once you have your pattern you apply the $content and $regex_pattern to preg_match_all() like this

preg_match_all($regex_pattern,$content,$matches);
print_r($matches);

preg_match_all will store all the matches into the array $matches, so if you output the array, you’ll see something like this.

Array(
    [0] => Array
        (

            [0] => <a href="http://www.bjmckay.com">B.J. McKay</a>

            [1] => <a href="http://www.dallas.net">Dallas</a>
        )
 
    [1] => Array

        (
            [0] => http://www.bjmckay.com
            [1] => http://www.dallas.net

        )
 
    [2] => Array
        (
            [0] => B.J. McKay
            [1] => Dallas
        )

)

From this array, $matches, you should be able to loop through and get the information you need.

Also, PHP also provides the function preg_match(). The difference is preg_match() only matches a single instance of the pattern, whereas preg_match_all() tries to find all matching instances within the content. The phone number regular expression example that follows shows the use of preg_match().

<?php
$content = 'He is going everywhere, <a href="http://www.bjmccay.com">B.J. McKay</a>
and his best friend Bear. Rolling down to <a href="http://www.dallascityhall.com/">Dallas</a>, who is providing my palace, off to New Orleans or who knows where.';

$regex_pattern = '/<a href="(.*)">(.*)<\/a>/';

preg_match_all($regex_pattern,$content,$matches);
print_r($matches);

echo '<br/><br/>';

foreach ($matches[0] as $m) {
echo $m.'<br/>';
}

echo '<br/>';

$phone_number = '203-866-8516';

$phone_pattern = '/\(?(\d{3})\)?-?? ?(\d{3})-(\d{4})/';
preg_match_all($phone_pattern,$phone_number,$valid);
print_r($valid[0]);
?>

Go ahead and walk through some examples of using regular expressions in PHP

Security Considerations


Managing users and permissions

We'll do an example of setting users and permissions through a userid and password. We can use a form front-end or a post service to post the information.

Userid: Password:

We can process the form just like we could process a CGI post or get from any other method. We can dole out privileges to PHP function based on submitted values:

<?php
if ($_GET['userid']=='bob') {
echo 'HI BOB<br/><br/>';
if ($_GET['pword']=='patriots_win_tonight_big') {
echo 'YOU ARE A GOOD GUY';
} else {
exit('See Ya. You are not a good guy');
}
} else {
exit('You are not welcomed here');
}
?>

Browser detection

Let's take a look at the PHP get_browser() function.