Tag Archive for 'heredoc'

Page 2 of 2

PHP OOP: Back to Basics

beginBack to Basics

Whenever I venture outside of PHP, which has become more regular as I’m working on app development in both iOS and Android. The former is Objective C and the latter, Java. Both languages are embedded in OOP and design patterns. It is during these ventures abroad (so to speak) that I’m reminded of some core issues in good OOP. I usually notice them when I realize that I’m not exactly paying attention to them myself.

Don’t Have the Constructor Function Do Any Real Work

When I first came across the admonition not to have the constructor function do any real work, I was reading Miško Hevery’s article on a testability flaw due to having the constructor doing real work. More recently, I was reviewing some materials in the second edition of Head First Java, where the user is encouraged to,

Quick! Get out of main!

For some Java and lots of C programmers “main” is the name for a constructor function, but I like PHP’s __construct() function as the preferred name since it is pretty self-describing. “Main” is a terrible name because the real main is in the program made up of interacting classes.

In both cases, the warning about minimizing the work of the constructor function is to focus on true object oriented applications where you need objects talking to one another. Think of this as a series of requests where a group of people are all cooperatively working together, each from a separate (encapsulated) cubicle, to accomplish a task. By having the constructor function do very little, you’re forcing yourself (as a programmer) to use collaborative classes. Play the example and download the code to get started:
PlayDownload

A General Model for PHP OOP

As a nice simple starting place for PHP OOP, I’ve borrowed from the ASP.NET/C# relationship. ASP.NET provides the forms and UI, and C# is the engine. As an OOP jump-off point, we can substitute HTML for ASP.NET and PHP for C#. The Client class is the “requester” class. The UI (HTML) sends a request to the Client, and the Client farms out the request to the appropriate class. Figure 2 shows this simple relationship.

Figure 1: A Simple OOP PHP Model

Figure 1: A Simple OOP PHP Model

If you stop and think about it, OOP is simply a way to divide up a request into different specializations.

Avoid Conditional Statements if Possible

Figure 2: Requests begins with a UI built in HTML

Figure 2: Requests begins with a UI built in HTML

If you avoid conditional statements, and this includes switch statements, I think you can become a lot better programmer. In the example I built for this post, the user chooses from two different types of requests (classes), and each request has a refined request (method) that provides either of two different kinds of math calculations or display options. Figure 2 shows the UI (HTML) for the example. If the user selects “Do a Calculation” it sends the request to the Calculate class, but if the user selects “Display a story”, the request is handled by the Display class. Further, not only must the right class be selected, the right method in that class must be selected as well. The obvious answer is to get information from the UI and using a switch or set of conditional statements work out in the Client how to handle each request. You could even use (shudder) nested conditional statements. That approach could work, but when you start piling up conditional statements, you’re more likely to introduce errors, and when you make changes, you’re even more likely to make errors. The only good thing about conditionals is that you don’t have to tax your brain to use them.

Suppose for a second that all of your conditional statements were taken away. How, using the information sent from the HTML UI to the Client class can the selections be made without conditional statements? (Think about this for a moment.)

Think, pensez, pense, думайте, piense, 생각하십시오, denken Sie, 考えなさい, pensi, 认为, σκεφτείτε, , denk

Like all things that seem complex, the solution is pretty simple. (Aren’t they all once you know the answer.) Both classes were given the value of their class name in their respective radio button input tags. Likewise, the methods were given the value of their method names. With two radio button sets (request and method), only two values would be passed to the Client class. So all the Client had to do was to use the request string as a class name to instantiate an instance of the class, and employ the following built-in function:

call_user_func(array(object, method));

That generates a request like the following:

$myObject->myMethod;

In other words, it acts just like any other request for a class method. By coordinating the Client with the HTML UI, that was possible without using a single conditional statement. In this next section, we’ll now look at the code.
Continue reading ‘PHP OOP: Back to Basics’

Share

PHP CMS Project Part IV: La Petite Blog

cms4Bring in the MySql

At this stage there is still no design pattern in the project. You will see that re-use is starting to creep in, and we’re getting to the point where some decisions can be made about what design pattern would best fit this project. In Part V, you will see how a design pattern pulls everything together and why one is helpful to PHP programming.

In Part III of this series, you saw how external data from text files can be placed into an array and used by the DocHere class to populate a web page. In this installment, the same process shows how this can be done using data from a MySql database.

From Data Input to Web Page Display

The whole point of a CMS is to make updating a web site or blog easy. For the time being, I’m going to treat the web page example as a little blog–La Petite Blog. Figures 1 and 2 show how the data are to be entered and the end result pulled out of a database and displayed in the web page.

Figure 1: HTML form to send data to MySql database

Figure 1: HTML form to send data to MySql database

Figure 1 shows that the same categories of data used throughout the project are still in use. Even the CSS file is the same. The form is a simple HTML5 one. (Click View Code to see listing.)

< !doctype html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="heredoc.css"/>
    <meta charset="UTF-8"/>
    <title>Blogette Data Entry</title>
</head>
<body>
<h1>La Petite Blog</h1>
<h2>&nbsp;Enter data to update your blogette</h2>
<div>
    <form name = "content" action="InsertBlog.php" method="post">
        <input type="text" name="css" value="heredoc.css"/>&nbsp;CSS file
        <input type="text" name="title" />&nbsp;Title
        <input type="text" name="header1" />&nbsp;Header 1
        <input type="text" name="header2" />&nbsp;Header 2
        <textarea rows="5" cols="80" name="body1" >&nbsp;Add body text here</textarea>
        <textarea rows="5" cols="80" name="body2" >&nbsp;Add body text here</textarea>
        <input type="text" name="image1" />&nbsp;Image 1 file name
        <input type="text" name="image2"/>&nbsp;Image 2 file name
        <input type="text" name="caption1" />&nbsp;Caption for Image 1
        <input type="text" name="caption2"/>&nbsp;Caption for Image 2
        <input type="submit" value="Store data"/>
    </form>
</div>
</body>
</html>

The “entry” for the system is the class RetrieveBlog. It is almost identical to the Content class in Part III, and it generates the required results as shown in Figure 2.

Figure 2: Page content from database.

Figure 2: Page content from database.

Getting from the HTML5 data input to the PHP-generated web page takes a bit of doing, and so to get started, download the necessary files:
Download

From Data Input to Web View

The whole point of a CMS is to regularly update a web page easily. By the end of this stage, the only thing you’ll need with an FTP client for is to upload graphics. (Uploading graphic files from a web page using PHP is handled up an upcoming post apart from this series.) For now, though, you will be able to update all text in a web page as well as graphics are have already been placed in an image folder. Here’s what we’ll need:

  1. An HTML form for data entry (see above)
  2. A PHP class to create a MySQL Table to store data
  3. A PHP class to take the data from the HTML form and store it in the MySQL table
  4. A PHP class to retrieve the data from the and make it available to the web page

We’ll start with the table.
Continue reading ‘PHP CMS Project Part IV: La Petite Blog’

Share

PHP CMS Project Part II: Separating Tasks

cms2Separation of Content from Form

In Part I of A PHP CMS Project, you saw how a Web page could be placed in a variable using PHP’s HEREDOC operator. Once in HEREDOC, different parts of the page could be filled with content delivered through variables. Using a simple CSS format, it was possible to have the general layout of a Web page and updates through through a private methods in the same class.

This next step further separates the Web page structure from the data that it uses for content. Essentially, this steps makes the HEREDOC Web page a separate class and calls for content from another class. At this point, there’s no design pattern involved; just a little OOP. In fact everything is the same except the content. (Later on in this series you will see which design patterns would be useful.) Figure 1 shows what the new page looks like:

Figure 1: Content from an external source

Figure 1: Content from an external source

As you can see in Figure 1, the content on the page has changed, but the format is the same. The big difference is that all of the data were sent through an external object. You can test the page and download the source code by clicking the following buttons:
PlayDownload

Once you have downloaded the classes, you can see similarities and differences in the classes now and those in Part I. The first new class to examine is Content. Simply stated, this is the class that stores the data for the Web page. It has a single method, getContent() and no constructor function. As a rule of thumb, if I don’t need a specific constructor function (one using __construct), I don’t include one.

<?php
//Content.php
include_once('PageMaster.php');
class Content extends PageMaster
{
    public function getContent()
    {      
        $this->content = array("css" => "heredoc.css",
                         "title" => "Here's Doc!",
                         "header1" => "New York State of Mind",
                         "header2" => "The Travel Page",
                         "body1" => "<p>Let's go have some fun. This is what I did on my summer vacation. ",
                         "body2" => " There much to see in NYC. Tall buildings, yellow cabs and lots of people.</p>",
                         "image1" => "images/mermaid.png",
                         "image2" => "images/plane.png",
                         "caption1" => "<br /> New York has the best mermaids.<br /> ",
                         "caption2" => "<br /> Off to New York City.<br /> ");   
        return $this->content;
    }
}
?>

Now that the content is in a different class, it’s easier to change the content without having to change the DocHere class. Of course the idea is to leave the DocHere class alone and just change the content through the use of variables. However, instead of scalar variables, you can use a compound variable—an array in this case. So now, all of the content has moved from a set of variables in the same class as the HEREDOC Web page to an array in an external class.

Before looking at the updated DocHere class, you will find a small but significant change. Figure 2 shows the difference in how a variable is inserted into a HEREDOC document and how an array element from an external class is inserted into the same HTML tag:

Figure 2: Inserting variables and imported array elements.

Figure 2: Inserting variables and imported array elements.

Note that the same element names (or key names) are used as were for the variable names. (e.g., $this->header1 is now $this->hd[“header1”].) So now, the HTML page is in a single variable ($this->document), and all of the content for that page is in a single array ($this->hd).

To “catch” the data from the Content object, the DocHere class uses the $content variable ($this->content) it inherits from the abstract class PageMaster. Next, the $hd variable (short for ‘html data’) calls the getContent() method from the Content class. The getContent() method delivers the array with the data used in the HTML page.

<?php
//DocHere.php
include_once('PageMaster.php');
include_once('Content.php');
 
class DocHere extends PageMaster
{
    function __construct()
    {
        $this->content=new Content();
        $this->hd = $this->content->getContent();
        $this->document = <<<CMSTEMPLATE
        <!DOCTYPE html>
        <html>
        <head>
        <link rel="stylesheet" type="text/css" href={$this->hd["css"]}>
        <meta charset="UTF-8">
        <title>{$this->hd["title"]}</title>
        </head>
        <body>
        <header>
            <h1>{$this->hd["header1"]}</h1>
        </header>
            <article>
                <header>
                <h2>{$this->hd["header2"]}</h2>
                </header>
                {$this->hd["body1"]}
                {$this->hd["body2"]}
                <section class="doRight" >
                    <img src={$this->hd["image1"]}>
                    <caption ><span class="pixcaption">{$this->hd["caption1"]}</span> </caption>
                </section>
                <section class="doLeft">
                    <img src={$this->hd["image2"]}>
                    <caption><span class="pixcaption">{$this->hd["caption2"]}</span> </caption>
                </section>
            </article>
        </body>
        </html>
 
CMSTEMPLATE;
    echo $this->document;
    }   
}
?>

The business logic if pretty well taken care of in the DocHere and Content classes. So you may well ask, What’s up with the abstract class, PageMaster?

Adding an Abstract Class

At this state of development, the abstract class, PageMaster is nothing more than a placeholder for an abstract class or interface we may need later in the development process. The three variables (or more correctly properties) of the abstract class can be inherited using protected visibility.

<?php
//PageMaster.php
abstract Class PageMaster
{
    protected $content; 
    protected $hd;
    protected $document;
}
?>

One OOP principle that you may be able to extract from this is the use of polymorphism. The $content object is used in both implemented classes. In the Content class, the $content property is an array, while that same property name in the DocHere class is an instance of the Content object. It’s not the best example of polymorphism, but it’s a start. (You can see more typical and useful examples of polymorphism in abstract methods—with properties the polymorphism is almost the same as the difference between the same local variable name used in different functions.) Further, keep in mind that that actual array from the Content object is stored in the $hd array; not the $content object in the DocHere class. It is passed to $hd using the following:

$this->hd = $this-content->getContent())

So for now, don’t worry about the PageMaster abstract class. However, in future development, of both the abstract class and the CMS project, you may find it quite important.

Why The Baby Steps?

Some readers may wonder why this example is taking its sweet time working up to both a CMS and design pattern in PHP. In reference to the book (PHP Design Patterns, some readers have complained that it is too difficult to understand. Despite the fact that it was written for advanced PHP developers, there’s no getting around the fact that design patterns are hard to learn. (Even the authors of the original Design Patterns book say that design design patterns and OOP are hard to comprehend, and their audience consists of C++ and Java developers!) With a plethora of bad examples of design patterns in PHP that are easy to understand on the internet, I thought working slowly through the logic of some examples on this blog may come up with both a good design pattern example and make it both practical and comprehensible. Any reader feedback on this topic will be quite helpful and welcomed.

Share

A PHP CMS Project: Part I

cmsWeb Pages in Classes

One of the more difficult styles of programming for me that most PHP programmers use is mixing in HTML and PHP. It certainly gets the job done, and for most that’s all that counts. However, with certain types of projects, mixing HTML is difficult to maintain and re-use. So, I thought that a good starting point for making a CMS is using a HEREDOC string inside a class. Once the basic structure is in place, data could be updated using external data without having to change the basic structure of a Web page or re-writing the HTML. Figure 1 shows the final results of an HTML page created with a PHP class. The “external data” at this point is “stored” in a class method. The page is very simple based on a typical Web page with headers, body text and captioned images. Figure 1 shows the results:

Figure 1: Page with data added

Figure 1: Page with data added

To get an idea of how to use this, and see it live on a Web page use these buttons to play it and download the files:
PlayDownload

(Depending on what you’re using to view this page, the two images are going to be more or less distanced from one another in the browser. You can jiggle the CSS to make any adjustments you want, but I just re-sized the browser. Likewise, the two header fonts may need some adjustment as well since I downloaded two non-standard art deco fonts.)

HEREDOC: A Web Page in a String in a Class

The first thing I did was to use PHP’s HEREDOC syntax. (You can find out about using HEREDOC in the manual.) I’ve come to reference HEREDOC in all caps since after the <<< operator the HEREDOC name is in all caps. Essentially, this approach places the entire Web page in a string. You have to be careful when using HEREDOC to place the closing HEREDOC name on the far left of the script with nothing more than a semi-colon after it.

You may be thinking that such an approach is very limiting because the entire Web page is contained within a single string. However, the Web page in the HEREDOC string is actually a template for what you may want to add. Just like using an external link to get your CSS, all of the content for the page is from external sources. In this initial example, the “external” source is simple a private method (getContent()) within the DocHere class as can be seen in the following listing:

//DocHere.php
<?php
class DocHere
{
    private $document;
    private $css;
    private $title;
    private $header1;
    private $header2;
    private $header3;
    private $body1;
    private $image1;
    private $image2;
    private $caption1;
    private $caption2;
 
    function __construct()
    {
        $this->getContent();
        $this->document = <<<CMSTEMPLATE
        <!DOCTYPE html>
        <html>
        <head>
        <link rel="stylesheet" type="text/css" href=$this->css>
        <meta charset="UTF-8">
        <title>$this->title</title>
        </head>
        <body>
        <header>
            <h1>$this->header1</h1>
        </header>
            <article>
                <header>
                <h2>$this->header2</h2>
                </header>
                $this->body1
                <section class="doRight" >
                    <img src=$this->image1>
                    <caption ><span class="pixcaption">$this->caption1</span> </caption>
                </section>
                <section class="doLeft">
                    <img src=$this->image2>
                    <caption><span class="pixcaption">$this->caption2 </span> </caption>
                </section>
            </article>
        </body>
        </html>
 
CMSTEMPLATE;
    echo $this->document;
    }
 
    private function getContent()
    {
        $this->css = "heredoc.css";
        $this->title = "Here's Doc!";
        $this->header1 = "The Main Section";
        $this->header2 = "This is a Section Header";
        $this->body1 = "<p>Here is whatever has to be said, thought, discussed or just chatter.";
        $this->body1 .= " You can tell the reader as much or as little as you like.</p>";
        $this->image1 = "images/rose.png";
        $this->caption1="<br /> Lady with flowers and the moon.<br /> ";
        $this->image2 = "images/poland.png";
        $this->caption2="<br /> I really want to visit Poland.<br /> ";
 
    }
}
?>

In looking at the class, think of it in three parts:

  1. Set of variables declared for use in the Web page
  2. The HEREDOC string containing the Web page template
  3. Content for the page

By placing all of the variables in a private visibility, you can quickly and easily encapsulate data that actually goes into the Web page. The variables provide a clear outline of what is available to change in the page. Keeping in mind that his is a Web page to be updated with external data, the private visibility helps to limit what kind of external data gets to be on the page. (It must be assigned to a private variable through some kind of public access.)

The HEREDOC string just makes it easy to drop in a Web page without a lot of string concatenation. In fact, you can create and test a standard HTML page and copy and paste it into the HEREDOC variable ($document.) Just remember to replace the content with the set of private variables.

Finally, the getContent() method is just a place-holder for whatever kind of data resource you want to use. As we develop this into a useful CMS application, we will want to keep in mind the decomposition process where we keep all of the parts separate and simple.

Finishing Touches

Before finishing up this first part, take a look at an external data source used in the program: the CSS file.

@charset "UTF-8";
/* heredoc.css */
/* CSS Document */
/*468966,FFF0A5,FFB03B,B64926,8E2800 */
body {
	background-color: #FFF0A5;
	color: #8E2800;
	font-family: Georgia, "Times New Roman", Times, serif;
}
h1 {
	font-family: "Raconteur NF", futura, fantasy;
	background-color: #468966;
	color: #FFB03B;
	text-align: center;
}
h2 {
	font-family: NITECLUB, fantasy;
	color: #468966;
}
.pixcaption {
	font-style: italic;
	font-size: 11px;
	color: #B64926;
}
.doRight {
	float: right;
	padding-left: 10px;
}
.doLeft {
	float: left;
	padding-right: 10px;
}

As noted, the CSS style sheet is simple, and you may want to make adjustments to your own taste or requirements in an external style sheet. If you use jQuery tools in your HTML pages, you will find that they can fit in the current format quite easily.

A little trigger script launches the DocHere object (class):

<?php
//calldoc.php
include_once('DocHere.php');
$worker = new DocHere();
?>

The external trigger script is a temporary stand-in for a Client class to be developed later for making specific requests. Be sure to place the calldoc.php file in the same directory as the DocHere.php file.

External Data Options

In developing a CMS, even a simple one such as the one in this series of posts, you need to begin thinking about how data are to be updated. In the next installment in this series, we’ll try out some externally supplied data and start thinking about what kind of design pattern would help to maintain a Web site through a PHP CMS.

Share