Mixing PHP and HTML is okay sometimes

Mising PHP with HTML, CSS or JavaScript should be avoided, but there are ways to generate dynamic assets properly. Read this to learn how.

337 views

Edited: 2021-02-21 17:35

mixing php with html

In really old PHP scripts it was a common practice to mix HTML with PHP; this was done by escaping in and out of PHP using <?php and ?> in the HTML code itself. Modern PHP applications do not do that very often. The practice of mixing PHP with front-end code might result in something we call spaghetti code, which can be impossibly hard to read for other developers.

There is a place where it is okay to do some limited mixing, and that is inside your HTML template files. HTML templates should not contain logic, but can contain presentation logic — although, often presentation logic is also best to keep away from your templates.

The way I would instead go about it, would be to create a html_generator class, and then use this to keep most of my html generation code, which I might even re-use in other projects. Sometimes I might even prefer to create an extra class and place it in the same directory as whatever relies on it to generate HTML — perhaps a specific feature or page on a website that needs to generate HTML.

What the best approach is will depend on your code. Some code is unique to a specific feature, and might not be a good fit in a generic "html generator" class used by the rest of the application. It might also make sense, sometimes, to keep small HTML fragments for certain things.

Avoid echo'ing directly to the output buffer

When you echo to output content, it will not really be sent directly to the browser — unless you remember to flush — it will first go to the output buffer where it sits until the script has finished executing, and only then will it be sent off to the user.

You should only be echo'ing content when it is ready, and you are sure no other developers need to access it from somewhere else in the code.

The bad thing about using echo directly is that the content will go to the output buffer, and the output buffer might have been polluted with other content, which makes it hard for developers to work with the content. You could of course use ob_get_clean to retrieve the contents in the buffer, but this is impractical — instead you should always try to return the data to the calling location. E.g:

function say_something(string $string) {
  return $string;
}

Wordpress templates tend to echo content directly, and that tend to make it harder to develop child themes.

Stand-alone scripts is okay

Of course it is still fine to mix HTML in small stand-alone scripts. You should not have to load your entire framework of choice just to create simple stuff. The main problem is when people use the technique for crating their entire website.

I keep a small playgound.php script that I only use to quickly test things; I actually have a few playground scripts that I regularly use. But, I used to have more stand-alone scripts; one example was a simple statistics script to show me how many monthly visitors my site had — I have since re-written most such scripts as extensions to my CMS.

It is completely fine to start out with a small stand-alone script, and then implement it when you are ready. You should just organize your code in a way, so you can easily tell which scripts are stand-alone, and which belong to the integrated system.

Note. By integrated system is meant your ugly-procedural-system, CMS, or framework. Even if you just use vanilla PHP, you should still have organized your code in a maintainable way. Always put in reasonable efforts when coding.

How to organize stand-alone scripts

Stand-alone PHP scripts should be kept in a directory of your website or project's root directory; in many cases this would be something like /var/www/my-project-name/scripts/.

Note that /var/www/ is often the default location of the web server root when you are using Linux hosting; it is perhaps most common for Debian and Ubuntu based systems.

Separation of concerns

Separation of concerns is a principle that helps you write better and more maintainable code by dividing your into smaller "parts" that each handle a specific feature or part of your application.

A logical way to think about it, is that you should keep your HTML templates in separate files, away from your PHP code, and then have them loaded from your PHP application when needed. This can often be done simply by including the file with require- and include- related expressions.

In the HTML files themselves, you should avoid business logic such as loop structures and if statements; instead you should aim to keep such code in your PHP files. This keeps the logic of your application separated from the presentation.

You do not need to keep all your HTML in template files. It is also fine to "generate" it from PHP functions. The important part is that you organize your code in a way that separates the concerns, as this tends to make your code more readable and maintainable. If you do create functions or methods dedicated to generating HTML, then you should generally return the code rather than echo it directly to the output buffer.

One of the better ways to categorize your code, is by using object orientated PHP; this allows you to more easily re-use parts of your code in other projects, without your code conflicting with other people's code. You could have a class that makes it easier to read and write files to your file system; having it as a class means that it is more portable, and easy to inject into any project that needs this functionality.

Mixing PHP with JavaScript and CSS

When it is possible to mix HTML with PHP, it is of course also possible to mix your PHP code with CSS and JavaScript — But the fact that it is possible does not make it a good practice.

There are times when you want to output some dynamically generated CSS or JavaScript, which is totally fine when you know what you are doing. Generally, the same principle of separation of concerns should be applied.

If you have a function that generates some CSS or JavaScript code that needs to be embedded on your page, then you could simply embed it directly in a style or script element in your HTML page.

Injecting JavaScript and CSS from PHP

A good way to inject dynamically generated front-end code while also keeping your logic separated from your presentation logic, would be to simply have a function or method that injects code into your HTML — the CSS/JavaScript may be generated elsewhere, either in a dedicated generator class, or from within individual plugins or features that you are developing.

In my own framework, I have a separate template handler class that deals with loading my HTML templates, CSS, and JavaScript.

This class has a function that basically takes existing assets in the code, and combines it with whatever is provided as a string. E.g.

function add_to_head_script(string $script_code) {
   $tpl_content->head_script = $tpl_content->head_script + $script_code;
}

This is very useful, because I can now add script code from anywhere in my application. If I was developing a plugin, then I could generate some dynamic CSS or JavaScript within the plugin, and then just call a function like this to have it added to my HTML.

The $tpl_content object contains all of the content that is ready to be inserted into my HTML.

Note. you could also use an array instead. Using an object gives the benefit of auto-completion in your code editor.

You can also have a function like this that updates external CSS or JavaScript files, but you should be aware that keeping your code in external files is not always going to be useful. You do not want code specific to one page to be loaded for all of your pages, as that would just be a waste of bandwidth and slow down your website.

Template files

Template files can be .php files that simply contain a mix of HTML and PHP, and that can be included in-place after populating the $tpl_content object:

<!doctype html>
<head>
  <title>Hallo World</title>
  <?=$tpl_content->head_scripts;?>
</head>
</body>
  <h1><?=$tpl_content->main_heading;?></h1>
  <?=$tpl_content->content;?>
</body>

You might choose to include the template in a respond function. E.g.:

function respond(tpl_content $tpl_content) {
  // Send the HTTTP headers
  $this->send_response_headers();

  // Populates the template and sends it to the output buffer
  require '/templates/default.php';
  exit();
}

I hope this article helped you understand things more clearly. You can post your own comments and questions in the comment section. Have fun until next time!

Links

  1. Escaping from HTML - php.net

Tell us what you think:

  1. How much faster is C++ than PHP to increment and display a counter in a loop?
  2. How to create a router in PHP that also handles request- methods and parameters.
  3. Detecting the request method used to fetch a web page with PHP, routing, HTTP responses, and more.
  4. How to create a custom error handler for PHP that handles non-fetal errors.
  5. Setting custom HTTP Headers with cURL is useful when changing User Agent or Cookies. Headers can be changed two ways, both using the curl_setopt function.

More in: PHP Tutorials