• Aucun résultat trouvé

Separation of concerns is a programming discipline and another step one can take when organizing code. The concept involves separating different sections of code from each other so that those sections can be worked on separately without interference from other sections. Within the same language, this would equate to modularization of code. Here it is applied in order to keep the many different parts of a modern web application separate. This is also known as loose coupling.

What Is Separation of Concerns?

Separation of concerns in web application development means isolating PHP from HTML, HTML from CSS, and JavaScript from HTML. The nature of the PHP parser makes it easy to code all these elements together. In fact it does this so well that sub-optimal coding habits, in terms of secure development, have developed over the years that are hard to break. A large number of programming examples demonstrate code examples of PHP/HTML and JavaScript all combined into single functions and single pages that are difficult to assess for security purposes.

An example of combined code that is difficult to visually assess and apply security measures to is the following.

<? if (!empty($left)) {?>

<div id = "columnLeft"><div class = "mainBox">

<?php echo $contentLeft; ?>

</div><?php echo $userName;?></div>

<p>Today's quote: <?php echo $quote;?></p>

<?php} else {?>

<style type = "text/css">

#divContent {width: 80%; padding-top: 15px;}

</style>

<?php} ?>

This code combines PHP, HTML, and CSS. It is more difficult to read and change than it needs to be. The four variables in this snippet, $left, $contentLeft,

$userName, and $quote, are hard to find and apply security measures to. The code works, but it makes working on the code more difficult. This is the main reason to put effort into separating concerns and keeping different kinds of code separated from each other.

The purpose here is to learn how to separate the parts, and to develop a coding practice that continually implements this structure. It is not difficult to write PHP code that keeps these elements separate, but it does take consideration and planning.

Keep HTML as HTML

HTML means Hyper Text Markup Language. With rapid PHP development it is easy to forget that the purpose of HTML is to mark up the document. It is not to contain application logic. HTML should represent the document. When HTML is clean, with the absence of non-HTML elements contained within, it becomes much easier to actually see the document. For example, here is a pure HTML document.

<!DOCTYPE html>

<head>

<m eta http-equiv = "Content-Type" content = "text/html; charset = utf-8"/>

</head>

<html>

<body>

<h1>Main Heading</h1>

<div>

<p>Document Data.</p>

</div>

<div>

<p>More Document Data</p>

</div>

</body>

</html>

This structure is very clear and a designer can easily understand it and reorganize it as needed. There is another benefit as well. Additional power and flexibility is gained by taking the steps to ensure clean HTML. When HTML is clean like this, it can be more effectively manipulated by external CSS and JavaScript without hard-to-find side effects.

Keep PHP Out of HTML

Keeping PHP out of HTML is the first task. Displaying into a browser is one of the most basic and widespread usages of PHP. Almost every application does this at least once. Consider the following code example.

<?php

$teamArray = array(

"Aprilia" = > "Guintoli",

"Yamaha" = > "Lorenzo",

"Honda" = > "Marquez",

foreach $teamArray as $team = > $rider) { echo "<tr>";

echo "<td>". $team. "</td>";

echo "<td>". $rider . "</td>";

echo "</tr>";

}

echo "</table>";

?>

Echoing HTML inline with PHP is a poor practice.

• It makes it hard to visually spot variables.

• It loses HTML syntax highlighting from the editor, which enforces the first reason.

• It is harder to determine actual out context.

• It makes it harder to insert escape filtering where needed without mistakes.

Let’s look at how it could be greatly simplified and separated. PHP processing begins at the top of the file. Then PHP processing is turned off with a PHP closing tag. This now starts direct HTML output. No echo or print statements are needed.

When the value of variables is needed in the HTML, PHP is again turned on inline with the HTML to output the value.

<?php

fu nction _H($data){ echo htmlscpecialchars($data, ENT_QUOTES,

"UTF-8");}

//end PHP processing, begin direct HTML output

?>

<?php foreach ($teams as $team = > $rider):?>

<tr>

<td><?php _H$team);?></td>

<td><?php _H($rider);?></td>

</tr>

<?php endforeach;?>

</table>

The results of structuring PHP and HTML separation like this are:

• PHP section is clear.

• HTML structure and indenting is clear. A designer can work with it.

• HTML syntax highlighting is back.

• It is easy to see where the output variables are: there are two.

• It is easy to determine the output context, and correct escaping was applied via the _H() façade. In this case, straight HTML context.

Keep JavaScript Out of HTML

There are two main ways that JavaScript is embedded inline with HTML. The first is by including a script tag in the HTML and executing JS code within it. This is a very convenient technique. So convenient that it sometimes is not worth the hassle of moving it to a separate file. It is quick, easy, and effective.

<script type = "text/javascript">

document.write("<div>New Section</div>");

function checkPassword() {}

</script>

The second method is by attaching JS code to HTML attributes, such as the onclick() event shown here.

<i nput type = "button" value = "Check Password" onclick = "check-Password()"/>

This method is even more seductive to use because it seems so right. It is event driven, which is desirable, and it is connected to the object needing it. It is very object oriented. The problems however cause a clean HTML document to no longer be clean. The disadvantages are:

• JavaScript cannot be cached by browser.

• JavaScript is spread out over several locations. Changing JS usually results in changing the JS and the HTML.

• Document is less clear as an HTML document.

The desired result is that HTML should only be changed when the document needs to change, not the JS. JS changes should not affect the document. Here is how to keep JS separate from HTML. In the HTML document, make the following changes.

First, change the head tag to include the JS file.

<head>

<m eta http-equiv = "Content-Type" content = "text/html; charset = utf-8"/>

<script src = "scripts.js"></script>

</head>

Second, remove the onclick event from the input button, and add an ID.

<i nput type = "button" id = "checkPass" value = "Check Password" "/>

In scripts.js, add the following code:

function checkPassword() { }

var btn = document.getElementById("checkPass");

btn.addEventListener("click", checkPassword, false);

See below for a full example HTML.

<!DOCTYPE html>

<head>

<script src = "scripts.js"></script>

</head>

<html>

<body>

<h1>Main Heading</h1>

<div>

<p>Document Data.</p>

</div>

<div>

<i nput type = "button" id = "checkPass" value = "Check Password"

"/>

</div>

</body>

</html>

Now the HTML is clean again. Only HTML is contained in the document. Code has been removed and is dynamically attached to the markup via external JavaScript.

The HTML has no knowledge of this attachment. It does not know if it happens or when it happens. The ID added is consistent with HTML purposes. The ID describes the document. All layout, formatting, and syntax highlighting is preserved. The docu-ment is described.

The JavaScript is isolated so that it can be changed at will with no effect on the doc-ument. Nicholas Zakas, an acknowledged expert in JavaScript, wrote that by doing this, debugging is made easier because the first place a person looks for JavaScript

errors is in the JS files, not the HTML file. JavaScript in multiple locations simply increases maintainable complexity.

The JS is now cacheable as a separate file for the browser cache. The HTML file is smaller, and loads faster, and the scripts.js file can be downloaded separately from the HTML file by the browser.

Content Security Policy

Last, but most important, keeping Javascript out of HTML means that Content Security Policy (CSP) header directives can be used. CSP is a powerful weapon in the prevention of rogue script execution. CSP cannot be leveraged for sites that contain inline HTML javascript, since this is exactly what CSP prevents. The security benefit obtained from successfully implementing separation of code is the ability to effectively use CSP.

See the online chapter, Secure Development with Content Security Policies, at http://www.projectseven.net/secdevCSP.htm

Keep CSS Out of JS

JavaScript has direct programmatic control over CSS styling elements, as seen below.

document.getElementById('notice').style.color = 'blue';

The power and convenience of using Javascript to control CSS this way is hard to give up. However, it should be given up. CSS is for styling. JavaScript is for making things happen. By removing CSS from JavaScript, a designer can completely control all elements of styling solely via the CSS file. If JS is making styling changes as well, then it becomes cumbersome to control effects. The designer should not have to search through JS files looking for other styling code. Here is how the two are separated.

In scripts.js add

//applying CSS via JQuery

$("notice").addClass("makeBlue");

//removing CSS style via JQuery

$("notice").removeClass("makeBlue");

In app.css add .makeBlue {

color:blue;

}

The CSS is removed from the JavaScript. Style is completely controlled by the CSS file. The JavaScript simply applies the style, or removes the style. Both mechanisms are functioning as they were intended. HTML is for markup, JavaScript is for events, CSS is for styling.

Use of IDs and Classes in HTML

Use of HTML ID and Class attributes within HTML tags is a very powerful technique. It is also an underused practice. By properly marking up a document with IDs and Class attributes, precise external control can be leveraged over the HTML document, thereby keeping it cleaner.

<!DOCTYPE html>

<head>

<me ta http-equiv = "Content-Type" content = "text/html; charset = utf-8"/>

<script src = "scripts.js"></script>

<script src = "app.css"></script>

</head>

<html>

<body>

<h1 id = "title">Main Heading</h1>

<div id = "top" class = "main">

<p>Document Data.</p>

</div>

<div id = "bottom" class = "main">

<i nput type = "button" id = "checkPass" value = "Check Password"

"/>

</div>

</body>

</html>

With this markup, the document is completely clean of non-HTML elements.

However, it can be completely controlled by external JavaScript and com-pletely styled via external CSS. Each Div can be selected individually based on HTML ID attribute, or both of them by selecting the HTML Class attribute

“main”. The  H1 header can be selected by its ID attribute. With these markup identifiers in place, JavaScript can be directly applied to any document element, as can CSS.

The real power of jQuery is its selector functionality. It can select based on ID, Class, or HTML tag. It can select and dynamically attach code, or manipulate style by adding or removing CSS classes. By leveraging the power of jQuery selectors it is very easy to keep HTML clean as markup.

Remember, HTML is for markup, JavaScript is for events, CSS is for styling.

Summary

In this chapter we looked at how to keep code and style information out of HTML markup. Separation of concerns with regard to PHP/HTML/JavaScript/CSS pays a large dividend in keeping a project clearer to understand. HTML is not meant to be the repository of an application’s logic. HTML is meant to display a result.

jQuery selectors give a developer all the power he needs to manipulate an HTML document for events and style. The developer just needs to plan ahead and structure accordingly.

A source of additional information on this topic is Maintainable JavaScript (Zakas, 2012).

12 9

9