Archive for the 'JavaScript and PHP' 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:

?View Code HTML5

        
                Functional Sniff
                        
        
        
        

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.

?View Code HTML



  
  jQuery UI Datepicker - Default functionality
  
  
  
   
  


  

Language of the Week

Click in the text box to select from pop-up calendar:

Date:

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:


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 "";
    }
 
    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.

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:

?View Code HTML

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:

?View Code HTML

        
                Passing Width & Height with Closure
                
        
        
        

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’

PHP Command Design Pattern: Part I

commandEncapsulate a Request

On occasion when developing an application, you may want to issue a request, but you may not know about the requested operation or its receiver. Imagine that you’re developing a game, and you’re working on a “Commander” (like Captain Kirk of Star Trek). The commander will issue commands, but during development or execution, you’re not sure who’s going to carry out the command or exactly how it’s going to be done. For instance, suppose that a Weapons Officer on the bridge simply pushes a button when the Captain issues a command to fire a photon torpedo. However, suppose that the bridge is damaged and the Weapons Officer wounded and cannot carry out the command. Any decent game designer would allow for someone else to launch the torpedoes; a crew member working in the torpedo bay, for example. Therefore, you would not want to tightly couple the action of firing a photon torpedo with the Weapons Officer. Something like;

weapons_officer->firePhotons()

would not be a good idea. Instead, you’d want the request to be handled by anyone who could get to the torpedoes triggering mechanism—no matter who it was or what triggering device was employed.

The Command design pattern encapsulates the request as an object, and allows you to add parameters to the clients with different requests. You can also support undoable operations—like firing off a photon torpedo! In this particular example, the participants and implementation is quite simple. I employed a helper class (Move) to add a little flair to the example, but otherwise, it’s a very simple implementation of the Command design pattern. Fire off the torpedo and download the files to get started:
torpedoDownload

The movement operations were taken from an earlier post on this blog of working with SVG files—once again illustrating the re-use functionality of OOP design. The helper class, Move is almost wholly a re-use of the earlier implementation. The sound was added to the class for this example.

The Wholly Involved Client

The requesting client is fully involved in the Command pattern. It is associated directly with both the Receiver and the ConcreteCommand classes. Figure 1 shows the pattern’s class diagram:

Figure 1: Command class diagram

Figure 1: Command class diagram

In this example, I employed a single Client, Receiver, Invoker and ConcreteCommand. Largely, I re-purposed an abstract example that Chandima Cumaranatunge had used in ActionScript 3.0 Design Patterns that we had co-authored in 2007—the main difference being that the example is written in PHP and I added an action that involved sound and animation. However, it is largely the same. In looking at the code in the Client, you can see that it creates instances of a ConcreteCommand, Receiver and Invoker.


error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);
// Autoload given function name.
function includeAll($className)
{
    include_once($className . '.php');
}
//Register
spl_autoload_register('includeAll');
 
/* Client */
class Client
{
    public static function request()
    {
        $rec = new Receiver();
        $concom = new ConcreteCommand($rec);
        $invoker = new Invoker();
        $invoker->setCommand($concom);
        $concom->execute();
    }
}
$worker=Client::request();
?>

As you can see, the Client, chooses the concrete command and the invoker. Figure 2 shows the file diagram for this Command implementation:

Figure 2: Command file diagram

Figure 2: Command file diagram

This pattern can have different commands and different invokers, but the key lies in the Command interface (ICommand) that includes an execute() method that invokes the command. It doesn’t concern itself with what other object does the invocation; it just provides the interface for some object to carry out the command.Using the bare minimum, the interface has a single abstract method:


interface ICommand
{
   function execute( );
}
?>

The design allows for a number of different ConcreteCommand classes, especially flexible because of the simplicity of the interface. However, in this example, only a single concrete command implements the interface.


class ConcreteCommand implements ICommand
{
    private $receiver;
    function __construct(Receiver $rec)
    {
        $this->receiver = $rec;
    }
    public function execute()
    {
        $this->receiver->action();
    }
}
?>

The receiver has been identified by the Client and passed to the parameterized ConcreteCommand by the Client. The Client acts very much like a conductor in this pattern. It pulls a the pieces together and determines how they will interact together. All of the work is to carry out the command realized in the Receiver class.

The Invoker Makes it Happen

Returning to the Star Trek example where the Captain commands the Weapons Officer to “fire a photon torpedo,” the Weapons Officer is the invoker. That is, by pressing the Fire button, she executes the command. However, as we noted, maybe the Weapons Officer is unable to carry out the order because she has been knocked out in a battle, and so someone else has to do it. Because the command and the invocation of the command are loosely coupled, any available invoker could carry out the command. First, take a look at the Invoker class:


class Invoker
{
    private $currentCommand;
    public function setCommand(ICommand $c)
    {
        $this->currentCommand = $c;
    }
    public function executeCommand()
    {
        $this->currentCommand->execute();
    }
}
?>

Note that both a method for setting the command and one for executing the command are part of the Invoker class. The Client sets the command, but how is it executed? Again, it is the Client, but the execute() method is through the ConcreteCommand instance; also called by the Client.

The Receiver Knows What to Do

In order for the command to be carried out, at least one object needs to do what the command requires. In this case, it’s the Receiver. Following the path so far:

  1. The Command tells what to do.
  2. The Invoker tells an object to carry out the command
  3. The Receiver carries out the requirements of the command.

Keep in mind that all of this is done with loosely coupled objects, and different participants can carry out the different roles.


class Receiver
{
   private $speed;
   private $photon;
 
   public function action()
   {
         $this->speed= 20;
         $this->photon = 16; 
         $launcher=new Move();
         echo $launcher->setVelocity($this->speed,$this->photon);
   }
}
?>

I suppose this is a bit elaborate for an abstract example, but it seemed a little more illustrative with something other than an echo statement that the Receiver object announced. Besides, it illustrates re-use of a class as a helper class for the Receiver to do a bit more. As you can see from Move helper class, a the property IDs from the original use have been retained—e.g., ‘ship’ and ‘torpedo’ used for the same purpose.


//Helper class
class Move
{
   private $velocity;
   private $capacity;
 
   public function setVelocity($speed,$ship)
   {
      $this->velocity=$speed;
      $this->capacity=$ship;
 
      $ship =<<
      
         
         
         
           
             
             
              
               
                 Oopz
 
                 
                 
                 
                 
               
               
       
       
SHIP;
      return $ship;
   }
}

You can revise the actions of the Receiver to virtually anything you want. The important point with the Command class is that the original command (request) is encapsulated through the ICommand interface, and in the development process there can be any number of different requests fulfilled by different receivers and launched by different Invoker objects. Further with added commands, you can also add new invokers and ever receivers.

Beyond Abstract Command Structures

Even though this example has not been quite as abstract as originally planned, it is still pretty basic. What I’d like to do in subsequent examples is to build on this basic pattern where multiple commands, invokers and receivers work in concert through the Command design pattern. In the meantime, feel free to try out some of your own ideas and offer suggestions for further improvement and/or refinement.

PHP Bridge Pattern CMS

bridgeCMSA Flexible CMS

The previous post on the PHP Bridge Design pattern shows how a Bridge pattern has two connected but independent interfaces to make design flexibility for different online devices. This post explores how that same flexibility extends to making a Content Management System (CMS). Most of the Bridge participants in the design are unchanged or only slightly changed.

The major change in the Bridge design pattern actually makes it more in line with the original intention of the Bridge. The RefinedAbstraction participant (RefinedPage) no longer includes concrete content for the page. Instead, it provides the parameters for a client to add the content. This change adds flexibility and gives the developer more options than the original StandardPage class.

Two UIs and Multiple Clients

In order to make a decent CMS, you need to have at least two UIs:

  1. An Administrative UI for previewing and adding new content
  2. A User UI for viewing but not changing content

In creating the Administrative UI (HTML5/PHP/JavaScript), I had to use two PHP clients. One client is to preview the new data entered by the admin and the other client is to store the new data (after previewing and possibly editing it). Figure I provides a general overview of the UIs and the Clients that will use the Bridge pattern for a CMS:

Figure 1: User Interfaces and Clients

Figure 1: User Interfaces and Clients

The Administrative UI (BridgeCMSAdmin.html) uses the BridgeCMSAdminClient class for displaying different content and the StoreDataClient class for storing the information in a JSON file. An important condition to remember is that when using JSON files, you need to make their permissions available for reading and writing. (See the Memento II post and the special mini-post on setting permissions on Raspberry Pi systems.) Thus, the need for two clients; one for previewing new material and another for storing it in a JSON file. A lot of files are involved in this CMS; so take a look at the two different UIs and download the files for everything:
PlayPlayAdminDownload

To use the Administrator Module, follow these steps in the listed order:

  1. Type in Header data, select a graphic from the drop down menu, and then type in text for the body.
  2. Click a Desktop, Tablet or Phone radio button and then click Preview Page
  3. When you have everything the way you want it, First click Transfer to Storage and next click Store Data
  4. Now click the Play button and see the page you created.

In the admin UI, I used a drop down menu with only three selections for the graphic file since only three were set up. However, it would not be difficult to upload graphics and their file names. (See the post on uploading graphics using the Template Method.)

The UIs and their Clients

The main feature in creating a CMS is the Administrative UI. It calls two different clients for dealing with previews and persistent data storage. Unless you’re planning on a fairly long body text entry, the JSON file works fine. Look at the code below, and you can see that one of the issues is that the data that is entered for the preview must be transferred to a different form. It transferring the data is a simple task with a little JavaScript. The following script is all it takes:

?View Code JAVASCRIPT
function transferData(formNow)
{
    formNow.header.value = bridgeWork.header.value;
    formNow.graphic.value = bridgeWork.graphic.value;
    formNow.bodytext.value = bridgeWork.bodytext.value;
}

Stored in an external JS file, it was used only when the data was going to be stored; however, before storing it, it had to be transferred from the bridgeWork form to the dataStore form.

?View Code HTML
< !DOCTYPE html>


    
    
    CMS Admin Bridge


    

Enter Update Data

 Header

Enter the text for the body below:

Preview New Data

 Desktop
 Tablet
 Phone

 

Store New Data

 

Then using build-in PHP JSON json_encode() method, the data were placed into an array and stored in the JSON file. This was done using the StoreDataClient class:

< ?php
class StoreDataClient
{
    private static $dataStorage=array();
    private static $jsonFile="content.json";
    //Client stores data
    public static function store()
    {
        if (isset($_POST['jsonstore']))
        {   
            self::setStore();
        }
      file_put_contents(self::$jsonFile,json_encode(self::$dataStorage,JSON_UNESCAPED_UNICODE));
    }
 
    private static function setStore()
    {
        //Pushes data from HTML to array
        array_push(self::$dataStorage,$_POST['header'],$_POST['graphic'],$_POST['bodytext']);
    }
}
StoreDataClient::store();
?>

Just in case you’re wondering why a single PHP client class was not used for both preview and storage, it’s simple:

OOP Principle: Each class should have only a single responsibility.

We don’t want to cram classes; so each responsibility has its own class. (Click below to see the other client and the rest of the CMS.)
Continue reading ‘PHP Bridge Pattern CMS’

PHP Memento Design Pattern Part II: Store & Retrieve

mementoWith a Little Help from Our Friends

As you saw in Part I of the Memento Design Pattern post, the design itself is fairly simple; at least judging from the class diagram. Also, in the first example, you saw how a state could be preserved in a Caretaker array and recalled upon request. However, I wanted to use the Memento with a more practical implementation of remembering a previous state to which users could return. For instance, the capacity to remember a choice on a Web page after looking at a series of choices would be an ideal use of the Memento pattern. The idea is to build an encapsulated set of objects that encompasses the UI, and the previous post shows how that can be accomplished. The latest problem encountered using the Memento pattern with PHP is that PHP doesn’t have the necessary UI event handlers, and the UI event handlers in JavaScript, while able to pass data, must do so through a PHP file; not an object.

The result is that each time JavaScript passes a bit of data, it also re-instantiates a class in a file. When that happens, all of the stored states are reset to null. So while the Memento is great at storing data in an array (or scalar for that matter), getting that state back with another call via JavaScript (even if it’s encapsulated in a PHP object) nulls all of the stored states.

So, while JavaScript is OK for handling UI events and passing states to PHP, every state passed resets any saved states because the participants have to be re-instantiated. After trying out different methods, I eventually reached the conclusion that I was going to have to stash the Memento’s current state in a JSON (JavaScript Object Notation) file. PHP includes JSON methods, and while this does not exactly solve the problem of passing data without resetting the state, it can preserve the state stored in a Memento object. Take a look at the example and download the files to see all of the code employed:
PlayDownload

JSON and PHP

For those of you unfamiliar with JSON and PHP, you can find it here in the PHP Manual. As noted, to work with PHP and a Memento design pattern the way I wanted to implement it required that I have some way to provide a persistent record of a “saved state.” In a nutshell, JSON is a faster-loading version of XML with hooks into PHP where data can be exchanged. That is an oversimplification to be sure, but as far as I was concerned if a state could be saved and retrieved quickly when wanted, my requirements would be met. I did not want to involve MySQL, XML or simple text files (even though JSON files [ext .json] are text files). JSON was the fastest in saving and retrieving, and PHP has methods for parsing JSON data.

The Caretaker

If you have not done so already, read Part I of the Memento Design Pattern. That will bring you up to speed on the structure and participants of the Memento design pattern.

The Caretaker participant in the Memento pattern is the warehouse for the saved Memento objects passed through the Originator. Essentially, the Memento is passed to the Caretaker where it is stored until called for retrieval. However, a PHP object cannot be stored as a straight JSON file, and so once the Memento object is passed to the Caretaker (in this example), I passed the Memento value to a JSON file. The second Caretaker method returns the stored JSON value directly to the client rather than re-loading a Memento object and returning it. You can see how this all works in the Caretaker class code:

< ?php
class Caretaker
{
    private $storage;
    private $caretakerStore;
    private $caretakerStorage;
 
    public function addMemento (Memento $m)
    {
        $jsonData["hold"][0] = $m->getState();
        $this->caretakerStore="store.json";
        file_put_contents($this->caretakerStore,json_encode($jsonData,JSON_UNESCAPED_UNICODE));
    }
 
    public function getMemento()
    {
        $this->caretakerStorage = file_get_contents("store.json");
        $jsonData = json_decode($this->caretakerStorage,true);
        $this->storage= $jsonData["hold"][0];
        return $this->storage;
    }
}
?>

The two methods in the Caretaker are pretty straightforward getter/setter ones. The addMemento($m) method expects to receive a Memento object. (The type hint enforces it to.) However, instead of storing the entire Memento as was done in the example in Part I, the Caretaker uses the Memento’s getState() method to access the saved state. Then the state is stored in an associative array element named “hold.” ($jsonData[“hold”][0]). Written to a .json file the saved state might look like the following:

{"hold":["7"]}

The value “7” is the saved string that is used to recall the correct file (dp7.jpg) in the patterns folder. While this might appear to be breaking encapsulation, the value is returned in a Caretaker private property, $this->storage.

To get a better sense of the Caretaker in the context of this particular implementation take a look at Figure 2:

Figure 2: File diagram of Memento used for recalling Web image

Figure 2: File diagram of Memento used for recalling Web image

The PhpCatcher class is an attempt to encapsulate the HTML UI into an object and have methods available to set and retrieve Memento object values using the Caretaker as a warehouse. To set the Memento and send it to the Caretaker, the exact same object communications are used as in Part I. However, the Caretake extracts the value from the Memento and stores it in the .json file instead of in a PHP array that stays extant through UI interactions. So, to recall a Memento value, the PhpCatcher goes directly to the Caretaker’s getMemento() method. (Perhaps a more accurate name for the getter would be getMementoValue().) In any event, at the time of this posting, I was unable to find a way to store the Memento in a JSON object and retrieve it; so the PHPCatcher communicates directly with the Caretaker as a client.

You need to use PHP 5.4+ and you need to set your .json file permissions

  • The PHP built-in JSON methods and constants used require PHP 5.4. If you find it impossible to install 5.4, instead of using JSON, you can use a text file, an XML file or even a MySQL file for storing the Memento value.
  • File permissions are grouped into three categories:

    1. Owner
    2. Group
    3. Everyone

    Further, each permission has three levels:

    1. Read
    2. Write
    3. Execute

    You need to set your .json file so that everyone can read, write and execute the .json file. I set mine for ‘777’ so that all groups and the owner had total access. On your computer or LAN, there’s not a lot to worry about; however, if you are nervous about opening up your .json file to the world on your hosting service, you need to read up on permissions security to see if doing so will cause unwanted problems.

If you’re using a Raspberry Pi, you can find out how to change your permissions for this implementation here.

Continue reading ‘PHP Memento Design Pattern Part II: Store & Retrieve’