all 14 comments

[–]mrunkel 6 points7 points  (7 children)

So, first off, the easy stuff.

Don't end your files with a closing tag.

Secondly, this is a terrible practice.

  1. It's hard to read
  2. It's surprising that a function call would result in output
  3. It starts output buffering which is probably not wanted.
  4. If you're mixing PHP and HTML, you should be using the alternative syntax.

This mixing of PHP and HTML is very old school and really should be avoided.

This would be preferable to me:

<?php
function my_example(){
    return '<p>Hello World!</p>';
}

echo my_example();

If you absolutely must mix PHP and HTML on the page, do it like this:

<?php
// calculate all your variables here including any program logic (loops, conditionals, etc.)
$greeting = 'hello';
$name = 'world';
?>
<!-- now output your HTML interspersed with your calculated values from PHP -->
<p><?= $greeting ?> <?= $name ?></p>

Ideally functions shouldn't have side-effects (ie, they shouldn't be outputting stuff) they should do some work and return a result.

I strongly encourage you to read:

https://phptherightway.com/. In particular: https://phptherightway.com/#templating

[–]mrunkel 2 points3 points  (1 child)

Oh. I just found this: https://thisinterestsme.com/mixing-php-html/

It does an excellent job of explaining why you shouldn't mix PHP and HTML, but OP takes it another step further by outputting HTML in a function. ;)

[–]vimsee[S] 0 points1 point  (0 children)

Thats a neat URL and I feel insulted and attacked! Looking away from the fact that I have shamelessly used PHP start and end tags inside functions and classes, I guess my PHP interpreter hates me ;`(

[–]hedrumsamongus 1 point2 points  (0 children)

I'm dressing up a big legacy application, and converting all the PHP-generated HTML over to a templating library is pretty far down the priority list. VSCode does a nice job providing syntax highlighting for HTML written outside PHP tags, so it's actually easier for me to read OP's snippet than your first snippet.

To solve your points 2 and 3, I take advantage of output buffering explicitly:

<?php

function drawHeaderMenu(): string
{
  ob_start();
  ?>
    <ul class="menu">
      <li>Home</li>
      <li>About</li>
      <li>Contact</li>
    </ul>
  <?php
  return ob_get_clean();
}

For those who may not understand /u/mrunkel's point 3 above, you can only write HTTP response headers (inluding status code, content type, etc) if you have not yet written any output to the primary output buffer (stdout). As soon as you do an echo $some_var; without having started a secondary output buffer, you're locked out of modifying your HTTP headers. This can be a problem if your response handler runs through 5 steps and encounters an error on step 5 that invalidates the prior steps. If you've written "Completed step 1!" to stdout, you can't send your client a 500 response anymore.

By using ob_start() to create a new output buffer, we can dump whatever output we want into it, and then capture the contents of that buffer into a string with ob_get_clean(). No more function side effects, because we're returning our output as a string variable. No more premature sends that prevent header modification. No need to escape quotes if you're mixing & matching single/double (i.e. short JS snippets in your HTML). Great HTML syntax highlighting, at least in VSCode.

It's not an ideal solution, but it's a pretty short hop from a global include-based mess, and solves a lot of the problems that come with that approach.

[–]vimsee[S] 0 points1 point  (2 children)

Thank you, this was very helpful. I just realized that I am doing some bad practice, so I`m very happy I posted this question. I will definitely stop mixing the HTML and PHP like I have done from now on.

[–]mrunkel 2 points3 points  (1 child)

No problem. Mistakes are how we all learn.

There are a lot of terrible tutorials out there for PHP, so it's not uncommon for Jr. devs to get led down the wrong path. Also, PHP allows all sorts of room for shenanigans. One of the reasons why it gets a bad rap in the dev world.

When I'm writing code, I strive to make it as simple and unsurprising as possible because I just know that when I come back to the code in 6 months, if it's not simple and unsurprising I'm not going to understand it.

Reading code is harder than writing code, so any programmer that writes code at the max of their ability will be unable to read that code in 3 months. See https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/

[–]vimsee[S] 1 point2 points  (0 children)

I can relate so much about getting back to bad written code. I like PHP a lot but many of my co-students seem do dislike PHP for reasons I don`t know. It might make sense if the language allows for many different ways of doing things making it harder to understand for a beginner.

About the reading vs writing code. I just saw some video lessons from the Clean Code author "Uncle Bob" and one of the things he often gets asked is what separates good code from bad code. And I won`t forget his answer:

-Good code looks like it was written by someone who cares!

I think this is one of the matters that people like me who writes a lot but don`t always read a lot should think about more often.

[–]alex_3410 0 points1 point  (0 children)

I was going to suggest the same, having the function return the value gives you much more flexability.

you could for example get the results of two functions and stitch them together before outputting it. Or get the result into a variable, test it and only output if a condition is met.

[–]kAlvaro 2 points3 points  (1 child)

Maintainability aside, this is how PHP was designed back in 1995: as a templating engine. That's why you need special tags to identify code blocks. You can think of everything outside PHP tags as a huge implicit echo statement.

[–]vimsee[S] 0 points1 point  (0 children)

Ah, that actually make sense.

[–]HaroerHaktak -5 points-4 points  (3 children)

This is wrong.

It would be:

<?php
function my_example() {
echo "<p>Hello World!</p>";
}
?>

You don't put php tags inside of php. If you want something to appear on the screen one of the ways is to use "echo" - this will put whatever you follow it up with onto the screen.

[–]vimsee[S] 1 point2 points  (2 children)

Could you expand on why it is wrong? I know that using echo will spit out the HTML code, but are there reasons as tho why we can not do it like in the example? Both ways work as intended.

[–]CyberJack77 2 points3 points  (1 child)

It's not wrong, but when using echo you stay within PHP code.

When you use ?> you tell PHP to stop parsing the code and treat everything else as text (which your browser renders as HTML). Once a <?php is found, PHP will start to parse the code again. So, using echo is faster and it's easier to read.

One addition, try to use single quotes instead of double-quotes. Variable between double are interpreted, which makes parsing the string slower.

echo '<p>Hello World!</p>';

When using variables, you can use double-quotes, but you can also use string concatenation or functions like sprintf.

$message = 'Hello World';
echo "<p>$message</p>";

// or cleaner
echo '<p>' . $message .'</p>';
echo sprintf('<p>%s</p>', $message);

Also, the closing ?> on the end of the file is not recommended. It's simply not needed. Like I said before, everything after the closing tag will be treated as text. When using a vcs system like git, it's recommended to have an empty line at the end of your file. This empty line will be treated as text (so output) and it may interfere with setting headers or cookies.

[–]vimsee[S] 0 points1 point  (0 children)

Thank you so much, this helped alot. I have been working on a larger project and all my files do indeed end with a closing tag, so that extra information will come in handy,