0

Can php be modified to create a custom way to call a php function without opening and closing php tags? For example, given an example function like this that is included in my static pages:

<?php
    function title(){
    $files = array(
    "service.php"=>"This is a Service Page Title",
    "index.php"=>"This is a Home Page Title",
    "contact.php"=>"This is a Contact Page Title"
    );

    foreach($files as $file => $title) {
            $thisFile = basename($_SERVER['PHP_SELF']);
                 if($file == $thisFile){
                    echo $title;
                    break;
                }
            }
       };
 ?>

Is there anyway to modify php at its core, so that it could be called, for example, like this:

<title>{{Title}}</title>

Instead of this:

<title><?php title(); ?></title>

Seems everyone under the sun is writing template engines that use this nice friendly syntax with the double curly braces to surround variables. I was just trying to think of a way to avoid installing something else and just do this with native php.

emailcooke
  • 271
  • 1
  • 4
  • 17

4 Answers4

1

Most of the time a fancy template engine is entirely unnecessary. You can easily accomplish this by running a simple str_replace loop of your tokens and their values over the otherwise-ready HTML (that you've stored into a variable) before you echo it all out. Here's what I do:

$html = '<b>My-ready-HTML</b> with {{foo}} and {{bar}} thingys.';

// Or: $html = file_get_contents('my_template.html');

$footsy = 'whatever';
$barsie = 'some more';

$tags = [
    'foo' => $footsy,
    'bar' => $barsie
    ];

function do_tags($tags, $html) {    
    foreach ($tags as $key=>$val) {
        $html = str_replace('{{'.$key.'}}', $val, $html);
    }
    return $html;
}

$output = do_tags($tags, $html);

echo $output;
Markus AO
  • 4,771
  • 2
  • 18
  • 29
  • Otherwise pass the `$html` with reference, `do_tags($tags, &$html)` to spare you from that little bit of extra memory that goes into having both `$html` and `$output` contain raw and parsed versions of your HTML. – Markus AO Apr 24 '15 at 05:05
  • I appreciate the help with this. Right away I felt like this was the right answer so gave it a +1 and checked it off. However it actually won't run. Have you tested it? – emailcooke Apr 24 '15 at 18:31
  • Hey sorry, there was a missing semicolon and obviously `$foo` and `$bar` were undefined etc. This was an adaptation off the top of my head. I have now tidied it up so it'll execute as expected when copy-pasted. – Markus AO Apr 25 '15 at 07:34
  • You can of course expand on the concept by using e.g. something like `{{!functisFoo}}` and then in your tag-parser function, do as ye: `if (preg_match("#{{!([a-zA-Z]*)}}#", $html, $m)) { $html = str_replace($m[0], $m[1](), $html); }` ... and have your tag replaced with the return value of a function -- `function functisFoo()` in this example. – Markus AO Apr 25 '15 at 07:45
0

You can store all html codes in PHP variable and print it out at the end, this method can avoid many open and closing PHP tag. Like this:

<?php
print "<html><head><title>".title()."</title></head><body></body></html>";

?>

instead of:

<html><head><title><?php echo title(); ?></title></head><body></body></html>
Eng Cy
  • 1,527
  • 11
  • 15
  • This is a bad way to program your code, do not do this if you want to code in a professional environment. Not only does your code readability suffer, you could end up with massive strings that can become a nightmare to debug. – Walker Boh Apr 24 '15 at 04:17
  • Can you explain why become a nightmare to debug? Will anyone debug the string? lol – Eng Cy Apr 24 '15 at 04:21
  • Let's say you are missing a closing tag or have a small syntax error in the string containing the html code. There is no easy way to debug this. This also restricts IDEs from being able to apply proper syntax highlighting to your code. A better approach that would retain readability is to echo html strings on their own line. I will clarify in my answer – Walker Boh Apr 24 '15 at 04:24
0

Instead of:

<title><?php echo title(); ?></title>

Try using:

<title><?= title() ?></title>

Anything beyond that you may as well be using (and in a sense will be) a templating engine, because you'll have to parse the block of code and interpret the {{}} brackets.

Sharn White
  • 624
  • 3
  • 15
  • 1
    Remember that this option needs activated shorttag-option in `php.ini` activated. – bish Apr 24 '15 at 04:33
  • Thanks for the reply but this is not really a solution since the idea is to get away from how verbose php can be. This is for a project on my own server so hacking at the php core is not a problem at all. Given that, I was looking for a way to just create by own [parser tokens](http://php.net/manual/en/tokens.php) to escape from html. Perhaps something that allows you to echo a string with double curlys `{{$string}}` and call a function with triple curlys `{{{functionName}}}`. None of this is easier to me either but it scales better with front end designers. – emailcooke Apr 24 '15 at 12:22
0

A similar effect is achievable using short_tags. Instead of doing

<?php echo $blah ?>

do

<?= $blah ?>

or

<?= callFunction() ?>

If you have php version 5.4 or greater, these tags will be supported. Prior to that, short_tags are disabled by defaut. Even in 5.4+, they can be disabled by the server so use it wiseley.

Another way is to echo html in a string so you don't have to switch in and out of php. Just remember to keep it readable for yourself and others:

<?php

$text = "Hello, World!";

echo "<html>
          <head>
          </head>
          <body>
              <span>" . $text . "</span>
          </body>
      </html>";

You can also use heredocs:

$html = <<<HTML
    <html>
        <head>
        </head>
        <body>
            <span>$text</span>
        </body>
    </html>
HTML;

echo $html;

Edit: I also wanted to point out ob_start and ob_get_clean. What this will do is "record" everything that should be printed out on the screen without printing it out. This allows you to complete all of the logic in your code before the contents are displayed on the screen. You still need to either open and close php tags or echo strings containing html.

<?php

ob_start();

$text = "Hello, World!";

?>

<html>
    <head>
    </head>
    <body>
        <span><?= $text ?></span>
    </body>
</html>

<?php

$html = ob_get_clean();
echo $html; //All output stored between ob_start and ob_get_clean is then echoed onto the web page at this point.

This may not be helpful for small webpages that don't need to process a lot of information. But if you have a lot of information to be displayed. It's beneficial to send large chunks of data to HTML over sending lots of smaller bits and can increase performance.

Walker Boh
  • 750
  • 6
  • 13
  • Are there any performance issues with opening a php tag at the start of a page and closing it at the end so that everything is processed vs. opening and closing, say, 6 times withing the page for a function or echo? Based on this suggestion, I could avoid the 'concat' periods and quotes by just using: `{$text} – emailcooke Apr 24 '15 at 12:11
  • There is a slight performance decrease when switching in and out of php tags multiple times but it's not noticeable. I edited my answer to include a way to increase performance when dealing with a large web page with a lot of logic – Walker Boh Apr 24 '15 at 14:34
  • Why not use heredoc instead of quotes for the strings when you have multiple lines? `$html = <<foo bar ... FOO;` – Markus AO Apr 25 '15 at 07:49
  • Good point, Markus. I forgot about heredocs. Edited my answer to include them. Thanks! – Walker Boh Apr 27 '15 at 14:57