Archive for the 'Functional Programming' Category

Simple Functional Sniffer & Switch Alternative

mix Because PHP is a server-side language, you will have times that you need to rely on client-side languages like CSS, JavaScript and even HTML5 to accomplish certain tasks. In developing the CMS, I realized that while incorporating JavaScript, CSS and HTML5 in heredoc strings, I’d established a barrier between PHP and everything else by only allowing these other languages to interact with PHP through objects. Of course, this is because PHP has emerged into an OOP language and the others have not.

What I failed to take into account is the fact that it’s perfectly possible for OOP structures to interact with non-OOP structures. To some extend that has been done with HTML/CSS UIs and PHP design patterns in several examples. That seems to work out fine, but where you want to use dynamic variables for more responsive HTML pages, we’re back to encapsulating HTML (along with Javascript and CSS) into heredoc strings in PHP. There’s nothing wrong with that, and there’s much to be said for having a fully integrated OOP design pattern with a pure PHP engine.

A Simple Functional JavaScript Sniffer

The problem I discovered in a pure PHP design is that other design possibilities are overlooked. The primary style tool for HTML documents is CSS, and the media queries in CSS3 are designed to be responsive to different devices—namely, those brought about by mobile computing. Sometimes (and I do mean sometimes) that solution seems to work fine. Other, times, however, the media queries fail to capture that chunk of CSS3 code that formats for the desired device. On top of that, it can be difficult calling up certain jQuery mobile files—or any other files—from CSS alone. In many ways, libraries in jQuery have proven to be far more robust than CSS3 alone and far easier to deal with. In several respects, probably in most, neither CSS nor jQuery mobile are programming so much as they are styling tools. As such, they’re the tail of the programming dog. This is not to say they’re less important; they’re just not programming.

So, to sort out the devices looking at our pages, (moving away from CSS media queries) is a programming task. In several other entries on this blog, I’ve looked at ways to sniff through the possible devices, and I think we need to conclude once and for all that user-agents are next to useless. So, by exclusion, we’re left with screen width. So,begin by looking at this simple JavaScript sniffer using two lambda functions:

?View Code JAVASCRIPT
//Save as file name "jsniff.js"
var wide = screen.width;
var beta=function() {wide >=900 ? window.location.href="Desktop.html" :  window.location.href="Tablet.html";};
var lambda=function() {wide <= 480 ? window.location.href="Phone.html" : beta();};

In past posts I’ve used the Chain Of Responsibility (CoR) design pattern to do the same thing using either user agents (forget about it!) or width determined by a JavaScript object. The little JavaScript lambda functions do the same thing, and while at some point of granularity your may wish you had your CoR pattern, generally, I think that there’s enough with the three general categories at this point in time to deal with multiple device. Use the buttons to test the functions. (Try it with your phone and tablet too.) Click PlayA for the sniffer and PlayB for the PHP functional alternative to the switch statement. The download button downloads the source code for both.

PlayAPlayBDownload

The process is pretty simple both from a programming and a lambda calculus perspective. From lambda calculus we get following definitions of true and false:

true := λx.λy.x
false := λx.λy.y

As algorithms, we might consider the following:

function(x, y) {return x;};
function(x, y) {return y;};

So, that means:

function (10,20) = 10; ← true : Is 10
function (10,20) = 20; ← false : Not 10

That’s not exactly lambda calculus, but it’s along those lines that we can eke out an idea. (If you’re thinking, “What about function(10,10) that would appear to be both true and false,” you see what I mean.)

So now we’ll add the values a and b and reduce it:

((λx.λy.x) a b) -> ((λy.a) b) -> a

That replaces λx with (λy.a) b and then a. So a is a. Well, it sounds true!

Then for false we have:

((λx.λy.y) a b) -> ((λy.y) b) -> b

In looking at this, we see that if a is a its true; otherwise it’s b which is not true. That’s pretty much like if-then-else. If true a, otherwise it’s b.

So the line in JavaScript would be a ternary:

lambda = function(a) { return a ? a : b ;};

as well as in PHP,

$lambda = function($a) { return $a ? a : $b ;};

For now, that’s enough linking up lambda calculus with Internet languages. With our JS “sniffer” using a simple HTML call, we can get the page configuration we want for our device based on the window size:

<html>
	<head>
		<title>Functional Sniff</title>
			<script src="jsniff.js"></script>
	</head>
	<body onload=lambda()>
	</body>
</html>

Try it out. It’s easy to write and it’s practical. What’s more, you can see how close everything is to a Boolean type decision. (The different device HTML5 files are in the materials in the download package; one of which uses the jQuery Mobile formatting.)

I Don’t Need No Stinkin’ Switch Statement

One of the nice things about functional programming is that it made me re-think how I was programming. One of the areas where I thought I’d be able to boil down an algorithm to something more compact came when I decided to break down a calendar output into four weekly segment. Using a jQuery calendar, I could pick a day and pass the information to a PHP class for processing. Initially, the switch statement came to mind as a solution in something like the following:

$d=$this->numDay;
switch ($d)
       {
         case ($d >=1 && $d<=7):
            return "jquery";
            break;
        case ($d> 7 && $d<= 14):
            return "haskell";
            break;
        case ($d> 14 && $d<= 21):
            return "php";
            break;
        default: return "racket";
       }

In looking for a range, each case acts like a little function. So why not use lambda functions in PHP to do the same thing. Each query (case/function) either returns a value or goes on to the next case. Here’s what it looks like:

$gamma=function($d) {return $d > 14 && $d <= 21 ? "php" : "racket";};
$beta = function($d) use ($gamma) {return $d > 7 && $d <= 14 ? "haskell" : $gamma($d);};
$lambda = function($d) use ($beta) {return $d >=1 && $d <=7 ? "jquery": $beta($d);};
return $lambda($this->numDay);

The last used lambda function is the first in the list ($gamma). That’s because in order for the subsequent function to call them with the use statement, the function used must be defined before the one using it. In functional programming, the use of one function by another is referred to as a closure.

The Language Mix-Master

With the key parts in place, take a look at the different parts and languages used. First of all, the program begins with an HTML5 UI. It links to the jQuery UI JavaScript files and the CSS files. A further stylesheet links to the local CSS.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>jQuery UI Datepicker - Default functionality</title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
  <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
   <link rel="stylesheet" href="lang.css">
  <script>
  $(function() {
    $( "#datepicker" ).datepicker();
  });
  </script>
</head>
<body>
  <h2>Language of the Week</h2>
  <h4>Click in the text box to select from pop-up calendar: </h4>
 <form action="LangWeek.php" method="post" name="useUI" target="showpix">
<p>Date: <input type="text" id="datepicker" name="pick" /></p>
<input type = "submit" value="Get Language" />
</form>
 <iframe name="showpix" width="300" height="300"></iframe>
</body>
</html>

A form links to a PHP file where it passes the selected datepicker() value. The iframe tag provides a visual feedback embedded in the HTML page. (Note: Remember, with HTML5, iframes are no longer evil.)

Finally, using a single PHP class, the selected date is reconfigured to an integer and evaluated by the lambda functions described above in lieu of a switch statement:

<?php
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);
 
class LangWeek
{
    private $dateNow,$dayMonth, $numDay;
 
    public function __construct()
    {
        $this->dateNow = $_POST['pick'];
        $this->dayMonth=substr($this->dateNow, 3,2);    // Start 03  : 2Length
        $this->numDay = intval($this->dayMonth);
        echo "<img src='images/{$this->chooseLanguage()}' . '.jpg'>";
    }
 
    private function chooseLanguage()
    {
        $gamma=function($d) {return $d > 14 && $d <= 21 ? "php" : "racket";};
        $beta = function($d) use ($gamma) {return $d > 7 && $d <= 14 ? "haskell" : $gamma($d);};
        $lambda = function($d) use ($beta) {return $d >=1 && $d <=7 ? "jquery": $beta($d);};
        return $lambda($this->numDay);
    }   
}
$worker = new LangWeek();
?>

Fortunately the jQuery date picker passes the date as a consistent string mm/dd/yyyy, and so the only requirement is to use a substring to find the day of the month and convert it to an integer. This is passed to the chooseLanguage() method that employs the lambda functions.

Mixing it Up

While this blog is dedicated to PHP Design Patterns and their application, I believe that PHP programmers should explore beyond OOP and try out different kinds of programming within an OOP framework, which happily exists within a Design Pattern. The willingness to explore and experiment keeps programming fresh and interesting in any language.

Share

Sandlight CMS VI: Strategy Administrative Module

admin A CMS is only as good as the administrative module, and the one provided here is fully functional based on a simple work flow. You can change the UI and work flow to best fit your own, but you have the flexibility design patterns offer; so making changes to fit your needs (or those of your customers) should not be difficult.

One of the key features of a dynamic Web page is that it can be updated easily, and by using a MySQL table and database, all of the update information can be stored in a single location (table.) Updating the page is simply a matter of updating the data in a record or by adding new records to the table. The administrative module for this CMS has the capacity to update data in an existing record, but the page presented is always the newest record. The CMS has certain drawbacks because you cannot delete records without throwing the system out of whack, but that was done for the purposes of ease of use. (Remember, you’re a programmer and can change whatever you want!)

Set the Table

Setting up the MySQL table involves three files: 1) an interface with the MySQL connection information; 2. a connection class; and a table-creation class. The following three classes: (Use your own MySQL connection information in the IConnectInfo interface.)

< ?php
//Filename: IConnectInfo.php
interface IConnectInfo
{
	const HOST ="your_host";
	const UNAME ="your_username";
	const PW ="your_pw";
	const DBNAME = "your_dbname";
	public static function doConnect();
}
?>
 
< ?php
//Filename: UniversalConnect.php
ini_set("display_errors","1");
ERROR_REPORTING( E_ALL | E_STRICT );
include_once('IConnectInfo.php');
 
class UniversalConnect implements IConnectInfo
{
	private static $server=IConnectInfo::HOST;
	private static $currentDB= IConnectInfo::DBNAME;
	private static $user= IConnectInfo::UNAME;
	private static $pass= IConnectInfo::PW;
	private static $hookup;
 
	public static function doConnect()
	{
		self::$hookup=mysqli_connect(self::$server, self::$user, self::$pass, self::$currentDB);
		try
		{	
			self::$hookup;
			//Uncomment following line for develop/debug
			echo "Successful MySql connection:<br />";
		}
		catch (Exception $e)
		{
			echo "There is a problem: " . $e->getMessage();
			exit();
		}
		return self::$hookup;
	}
}
?>
 
< ?php
include_once('IConnectInfo.php');
include_once('UniversalConnect.php');
class CreateTable
{
	private $drop;
 
	public function __construct()
	{
		$this->hookup=UniversalConnect::doConnect();
		$this->tableMaster="your_table_name";
		$this->dropTable();
		$this->makeTable();
		$this->hookup->close();	
	}
 
	private function dropTable()
	{
		$this->drop = "DROP TABLE IF EXISTS $this->tableMaster";
 
		try
		{
			$this->hookup->query($this->drop) === true;
			printf("Old table %s has been dropped.<br />",$this->tableMaster);
		}
		catch (Exception $e)
		{
			echo "Here is why it did not work:  $e->getMessage() <br />";
		}
	}
 
	protected function makeTable()
	{
		$this->sql = "CREATE TABLE $this->tableMaster (
			id SERIAL,
			topic NVARCHAR(24),
			header NVARCHAR(120),
			graphic NVARCHAR(60),
			story BLOB,
			PRIMARY KEY (id))";
		try
		{
		  $this->hookup->query($this->sql);
 
		}
		 catch (Exception $e)
		{
			echo 'Here is why it did not work: ',  $e->getMessage(), "<br />";
		}
		echo "Table $this->tableMaster has been created successfully.<br />";
	}
}
 
$worker=new CreateTable();
?>

The connection routines have been improved upon over time, and you can find out more about it in the original post on the subject on this blog. For now, Play the application and Download the source files. (When you click the Play button, you enter the Login UI. Use the same un/pw combination from the Functional Protective Proxy post on this blog. (Hint, you can find it in the ILogin abstract class.)
PlayDownload

In creating the table at first I used the TEXT data type for a large block of text, but then decided that a BLOB type may have a slight advantage. The BLOB is a VARBINARY and TEXT is VARCHAR, and BLOB seemed to have a slight advantage. However, the advantage may be smaller than I originally thought. Check out the MySQL docs on these two data types and you can see the differences for yourself. Figure 1 shows what the editor in the administration module looks like:

Figure 1: Administrative Module Editor

Figure 1: Administrative Module Editor

From Proxy to Strategy

The login module of this CMS is based on the Proxy pattern. Now, as in previous CMS examples, the administrative module is based on a Strategy pattern. Each object in the Strategy pattern represents an algorithm to accomplish a different task. In this case, the tasks include:

  • Entering data
  • Editing data
  • Displaying data
  • Displaying a page based on stored data.

All requests go through a context relying on a Strategy interface. In this case, I used an abstract class which allowed the addition of several protected properties and a constant with the name of the table. This is all in addition to the main method in an abstract public function, the algorithm method, executeStrategy(). Following the Strategy design pattern, begin with the Context. Continue reading ‘Sandlight CMS VI: Strategy Administrative Module’

Share

Sandlight CMS V: Functional Protective Proxy Login

loginOn this blog, the Protective Proxy pattern has several different implementations, and if you’d like to refresh your memory, this post has the foundation upon which the others are built. The design pattern for the Proxy is relatively simple: the user logs into a site, and instead of going directly to the subject page, users are sent to a Proxy subject where their credential are checked. If the Proxy page determines valid credentials (typically a username and password), the user is sent to the subject page where the content resides.

With an administrative login, the work to be done (in this case) is to add and edit dynamic content for a page. The upper right portion of the main page is made up of materials that come from a database so that adding and changing content is relatively simple. However, before even getting to the administrative editing portion of the CMS, you want to be sure that only those with permission have access to the dynamic editor. So this post deals only with the login portion of the CMS. Go ahead and test it and download the source files:
PlayDownload

Rats! I forgot to tell you the username and password. You can find them in the source code in the download or in this post; so go ahead and dig them up and try again. It will help you understand how this proxy implementation works.

The Functional Protective Proxy

As noted above, other examples of the Proxy design pattern have been used and explained elsewhere on this blog. In this (protective) Proxy implementation, only one feature has changed: the methods are all written using functional programming protocols. Figure 1 shows the design pattern diagram for this implementation of the Proxy.

Figure 1: Class diagram for Protective Proxy

Figure 1: Class diagram for Protective Proxy

As far as protective Proxys go, this one is not unusual. The ReLog could have been handled by sending the user back to the LoginUI, but by having a different looking UI, it helps the user pay attention a bit more prior to re-entering the username and password. The path it follows is pretty simple:

  1. LoginUI: User enters username and password.
  2. LoginClient: Sends login request to LoginProxy.
  3. ILogin: Sets up two abstract methods and a concrete method along with encoded usernames and passwords. It also provides several protected properties. Both the LoginProxy and Login classes implement (extend) this abstract class interface
  4. LoginProxy: Evaluates username and password and sends it to Login if correct and ReLog if not.
  5. Login: Calls AdminUI (to be developed).
  6. ReLog: Re-start process requesting user name and password.

You can obscure the password and username better than I did for this example of the Proxy implementation. When used in an actual environment, you can store the codes in a special MySql table, a Json file, a text file or even a hidden element in an HTML5 document. Since users are not going to be logging in, other than the site administrator, you should be sure that they cannot even find where to log in! It’s a lot easier than trying to protect a site where users are expected to login.

When you look at the different classes, you won’t see much functional programming except in LoginProxy class. That’s because, there’s not a lot of code in any of the classes. The UI (LoginUI and ReLog) classes create and display HTML pages, the client class calls the proxy class (LoginProxy) but it’s the LoginProxy that has to do all of the thinking. Using functional operations, primarily lambda functions (PHP anonymous functions), the class methods determines what to do next: send on the request to the Login object or reroute it to the start-over class, ReLog. That’s pretty much it. In looking at the LoginProxy class code, you can see the functional operations at work:

< ?php
class LoginProxy extends ILogin
{
	//Proxy Subject
	public function doLogin()
	{ 	
		$this->sun=$_GET['username'];
		unset($_GET['username']);
		$this->spw=$_GET['password'];
		unset($_GET['password']);
 
		try
		{
			$this->security=$this->setPass();
			$this->igor=$this->sun==base64_decode($this->security[0]) && $this->spw==base64_decode($this->security[1]);
			$lambda=function($x) {$alpha=$this->igor ? $this->passSecurity=true : NULL; return $alpha;};
			$lambda($this->igor);
			$this->loginOrDie();
		}
 
		catch(Exception $e)
		{
			echo "Here's what went wrong: " . $e->getMessage();
		}
	}
 
	protected function loginOrDie()
	{
		$badPass=function($x) {$delta= $x ? ($this->goodLog=new Login()) : ($this->badLog=new ReLog());};
		$badPass($this->passSecurity);
		$goodPass=function($x) {$tau= $x ? ($this->goodLog->doLogin()) : NULL;};
		$goodPass($this->passSecurity);
	}
}
?>

Using the two methods implemented from the ILogin interface (abstract class), doLogin() and loginOrDie(), the functions work to determine whether 1) the password and username are correct and 2) send the request to the correct object: Login or ReLog.

What functional programming seems to do, among other things, is to create a series of binary queries with Booleans. For example, the protected variable $igor ($this->igor) has a double boolean assigned to it whereby two (2) comparative statements must resolve to true. By doing so, $igor becomes a Boolean value. (Who’s the Boolean now?! Snap!) Next, $igor, is a Boolean, as an argument in a lambda function ($lambda) determines whether the $passSecurity variable is to be changed from false to true—yet another Boolean!

In the loginOrDie() method, the $passSecurity variable is used again—this time as an argument—in the the $badPass() and $goodPass() lambda functions. That’s how this implementation of the protective Proxy determines whether the password and username are valid. The same determination could have been done using imperative conditional statements (e.g., if, switch), but in moving towards more functional programming within design pattern structures, the functional statements accomplish the same task with non-imperative programming.

In looking at the Login class, what is referenced as the “Real Subject” in design patterns, it does little more than pass the request to a user interface where the actual administration work can be done.

< ?php
class Login extends ILogin
{
	//Real Subject
	public function doLogin()
	{ 
		$this->loginOrDie();
	}
 
	protected function loginOrDie()
	{
		$admin=new AdminUI();
		$admin->dataStrat();
	}
}
?>

A tighter implementation would have us place the UI for the Administration module in the Login itself, but we’re not striving for “tightness.” Rather, this code moves a loosely bound module in a Proxy pattern to the next module using a Strategy pattern. As you will see in the interface used by both the LoginProxy and Login classes, the Login class only implements the two abstract methods and uses none of the other other protected properties or method. Continue reading ‘Sandlight CMS V: Functional Protective Proxy Login’

Share

Sandlight CMS II : Mobile First!

mobileFirstI’m not a graphic designer, and so I depend on others for the graphic elements and arrangement of my Web pages. However, I strive to make a site that is clear, easy to understand and useful. My focus is on good user experience (UX) and information design—clear communication with the user. In order to have good UX, you need to know something about Responsive Web Design (RWD), and if you don’t, check out the RWD link. Further, if you are unfamiliar with the approaches to RWD, I’m sold on the Mobile First approach, but possibly for different reasons than designers. Let me explain.

In designing my own site, my focus is on content categories, ease of maintenance, which includes updates and changes, and device flexibility. So I have to keep all of those in mind. I want PHP to handle regular updates by using content from a MySql database (the Content Management of CMS), and I need it to work on different devices. By tackling mobile first, I have to create a diamond-tipped focus on exactly what I want the user to view because even with the new “Phablets,” I’m not dealing with a lot of screen real estate. Currently, my old working mobile phone has a CSS resolution of 320 x 480, and my Phablet is 414 x 736. That’s less that 100 units different. (By CSS resolution, I’m referring to what CSS reads as far as screen width is concerned. See this table.)

Choosing the Devices

In an another sniffer program using a Chain of Responsibility (CoR) design pattern and a PHP user agent ($_SERVER['HTTP_USER_AGENT']) posted on this blog, the sniffer detected the user agent and then found the handler responsible for that agent. Now that user agents have been replaced by CSS screen width (as determined by a JavaScript function) for determining the device, we can use the same CoR pattern making the necessary changes. However, instead of getting real pages, we can use stand-ins that only have the roughest page content. All of the content will be encapsulated into PHP classes using heredoc strings. Near-future posts cover the mechanics of working out the MySql to provide dynamic content for the pages, along with other details necessary for the CMS. For now, though, the dummy pages will only contain enough material to demonstrate that each is appropriate for the selected device. Use the buttons below to see the current state of the CMS and download the files for this portion:
PlayDownload

Note that all devices can now access the Flag Counter. Where is your country on the Flag Counter? (See the note about the Flag Counter at the end of this post.)

Back to the Chain of Responsibility Pattern (CoR)

The CoR pattern is handy because it’s easy to update and change. For example, suppose that having three device categories (e.g., phone, tablets and desktops) proves to be inadequate and you want to add two more; one for laptops and another for phablets. It’s a simple matter to add to the chain and add device classes to handle the new devices. Figure 1 shows the first design pattern to be used in the CMS:

Figure 1: Chain of Responsibility Implementation

Figure 1: Chain of Responsibility Implementation

In Part I of this series, you can see how the device width and height is determined using a JavaScript closure (object) to pass the information to HTML and on to PHP. Since we only need to find the width, the JavaScript code has been slightly altered and placed in a separate file (deviceCatcher.js) in case it needs to be reused.

?View Code JAVASCRIPT
//deviceCatcher.js
function getWide()
{
	var wide = screen.width;
	return function()
	{
		return wide;
	}
}
var w = getWide();
//Send data to PHP class, CoRClient.php	
var lambdaPass= function() {window.location.href = "CoRClient.php?hor=" + w();};

The HTML file simply calls the closure function which passes the values to PHP:

<html>
	<head>
		<title>Device Catcher</title>
		<script src="deviceCatcher.js" type="text/javascript"></script>
	</head>
	<body onload=lambdaPass()>
	</body>
</html>

The HTML file is a trigger to get the ball rolling with the client class (CoRClient).

Starting the Chain

The client pulls the viewing device’s width from the superglobal, and passes it to a PHP variable. Given the variability in the width of device screens, I made the decision to work with three sizes to get started: 1) phone, 2) tablet, and 3) desktop. So, depending on the width, the request would be handled by one of those three device groups. I used the following cutoff sizes:

  1. Phone: >= 480
  2. Tablet: >=481 and < 900
  3. Desktop: >= 900

I used this table as a guide, but cutoff points can be anything you want.

Getting the width from the superglobal is easy enough using a static variable:

self::$wide=$_GET['hor'];

The, using the cutoffs, the program needs to generate three strings, phone, tablet, and desktop to send to the Request class that stores the appropriate string. The most obvious way is to use conditional statements (if or switch) to generate the correct string for Request. For example an imperative algorithm such as the following would do the trick:

if(self::$wide < = 480)
{
	return "phone";
}
elseif (self::$wide >= 900)
{
	return "desktop";
}
else
{
	return "tablet";
}

However, a functional program would be more compact, and like the JavaScript closure used in Part I, it would be an “object.” Transformed into a functional closure, the operation would look like the following:

$beta = self::$wide >= 900 ? 'desktop' : 'tablet';
$lambda = function($x) use ($beta) {
	$alpha =  $x < = 480 ? 'phone' : $beta;
	return $alpha;};

Using ternary operations ?: , $alpha and $beta both have function-like qualities. for example, $beta could have been written as a function beta() as shown in Figure 2:

Figure 2: "Functional" variables

Figure 2: “Functional” variables

As you can see in Figure 2, $beta provides the same functionality as beta(), and $beta can be used as a reference in the $lambda function along with $alpha in a PHP closure. (For some reason, when $beta is assigned an anonymous function, I was unable to get it to be added as a closure in the $lambda anonymous function.)
Continue reading ‘Sandlight CMS II : Mobile First!’

Share

Sandlight CMS I: Device Closures

devicesIn previous posts on this blog, I’ve included PHP patterns that deal with the issue of creating sites for multiple devices. In developing a Content Management System (CMS) for my Sandlight site, I wanted to start from scratch and use both elements of OOP and design patterns as well as functional programming. (Functional programmers may furrow their collective brows and mutter You’re ruining FP, but there’re enough arguments among FP advocates, that I’m not overly concerned.)

The Problem with User Agents

The problem with user agents (UAs) such as $_SERVER['HTTP_USER_AGENT'] in PHP, is that the information they provide is insufficient. For example, if you get “trident” from a user agent, it could be anything from a Microsoft-based computer to a MS phone. Devices identified as “iPad” can be the iPad Minis or the full-size iPads. And of course, if you get “Android” or “iPhone,” it can be any size screen from the early smart phones to what some call “Phablets”— the big phones like iPhone 6+ and Galaxy Note 3. To get started, take a look at this table. Not only will that table give you a range of mobile devices, it provides the way in which browsers communicate the type of device currently reading a page. (The CSS column is the most relevant for setting up a CMS that will adjust to different devices.)

How Can You Get the Screen Size for PHP?

If you’ve used CSS3, you are familiar with CSS media queries where you can direct the CSS to different classes and IDs depending on the screen size. It’s just as easy using JavaScript. The built-in document properties, screen.width and screen.height can be passed to variables and in turn to PHP. The procedure is a simple one-line program:

<script>
  window.location.href = "WiHi.php?hor=" + screen.width + "&vert=" + screen.height;
</script>

The JavaScript variables are hor and vert and can retrieved in PHP using $_GET[‘hor’] and $_GET[‘hi’]. So while that code can be saved as an html file and pass the data to a PHP class, it also offers up an opportunity to demonstrate how to add functional programming (FP) to JavaScript and to use FP with OOP. Use the buttons to test the program on as many devices as you have to see the range of screen sizes. Download the complete file set as well:
PlayDownload

Instead of stopping here and announce Mission Accomplished, I’d like to consider functional programming in JavaScript and closures in particular. In order to understand why I think it’s important to do this, consider the general purpose of both OOP design patterns and functional programming. Both were developed to better organize programming so that larger programs (consider what goes into your favorite game program) can be developed, maintained and changed.

Hackers vs Programmers

Hackers and hacks have a history of unthoughtful and malicious programming. It takes talent to build a house, but none to burn one down. The term “hack” originated as a program created by programmers who just threw code at a problem until something worked. The problem with hacks and hackers is that while the short-term goals may be accomplished, especially with short programs, hacks are like a guy with a machete chopping his way through the jungle to make a trail. The next time he comes down the trail, it’ll be grown over, and he’ll have to hack a new path. Figure 1 illustrates creating a hack vs. creating a program:

Figure 1: Hacking vs. Programming

Figure 1: Hacking vs. Programming


Compared to a modern highway, where planning, use of structure and interactive cooperation can create something of lasting value, hacks are a one-time accomplishment. It’s a kid playing in the mud. Fun until he’s got to start cleaning his own clothes.

Functional Programming in JavaScript

As you probably know, JavaScript does not have classes per se, and so we’re not going to try to create an OOP class in JS. However, the JavaScript folks are fortunate in having the book, Functional JavaScript (O’Reilly, 2013) by Michael Fogus. Functional programming is an important framework to understand in both PHP and JavaScript, and you can find a number of articles and other works covering FP in JS in addition to the Fogus book.

The “objects” in FP are called closures. In variations on JS and in special FP libraries (e.g., Underscore.js) you can find more FP functionality just as in the Hack dialect of PHP has functional operations for PHP not found in standard PHP. However, for here, I’d like to stick to plain vanilla JS and create what Fogus referred to as a “closure simulators” (faux closures), but they serve the same purposes. (PHP also has closures and a built-in Closure class.) I tend to think of closures as FP “objects,” but that characterization has a number of fuzzy edges; however, it’s a convenient way to think about them. Fogus summarizes a closure

as a function that captures the external bindings (i.e., not its own arguments) contained in the scope in which it was defined for later use (even after that scope has completed.)

—Michael Fogus p. 60, Functional JavaScript (O’Reilly, 2013)

A bit more dramatic description by Fogus is,

Closures are the programming language equivalent of vampires—they capture minions and give them everlasting life until they themselves are destroyed. The only difference is that closures don’t sparkle when exposed to sunlight.
—Michael Fogus p. 61, Functional JavaScript( O’Reilly, 2013)

Unfortunately, the PHP manual describes closures as equivalent to anonymous functions or lambdas. Simon Holywell in Functional Programming in PHP (p. 33) clarifies the manual’s misconception by noting that PHP closures are functional structures that include the use clause. In any event, both Holywell and Fogus describe a type of “object” where data can be packaged and used elsewhere in a program. So let’s take a look at a closure in JavaScript:

<html>
	<head>
		<title>Passing Width & Height with Closure</title>
		<script type="text/javascript">
			//Use closure "objects" to store screen size
			function getWide()
			{
				var wide = screen.width;
				return function()
				{
					return wide;
				}
			}
			function getHi()
			{
				var hi = screen.height;
				return function()
				{
					return hi;
				}
			}
 
			//Pass closures to variables
			var w = getWide();
			var h = getHi();
 
		        //Send data to PHP class, WiHi.php	
			var lambdaPass= function() {window.location.href = "WiHi.php?hor=" + w() + "&vert=" + h();};
		</script>
	</head>
	<body onload=lambdaPass()>
	</body>
</html>

The two functions, getWide() and getHi() are simulated closures, but functionally, they work just like closures. In fact, they work pretty much like objects. These two closures are passed to variables, w and h, which themselves are then closures and can be used to return the width and height of the device screen. Continue reading ‘Sandlight CMS I: Device Closures’

Share