Link to home
Start Free TrialLog in
Avatar of mrmut
mrmutFlag for Croatia

asked on

PHP HEREDOC parsing process?

Hello guys, I have a question of PHP HEREDOC parsin process.

I am trying to implement HEREDOC as a templating engine, where I would have a programmatic output of pages, so no "naked" code inside.

The principle is simple - I have a series of strings with parts, or entire HEREDOC HTML pages, that are called with function that render the entire page.

This simple trick is utilized to process functions inside HEREDOC (as heredoc is parsed):
function fn($data) {
  return $data;
}
$fn = 'fn';

$my_string = <<<EOT
Number of seconds since the Unix Epoch: {$fn(time())}
EOT;

Open in new window



THE PROBLEM FOLLOWS:

Calling simple stuff from inside HEREDOC is fine, say PHP time, or a string or two. But if I call functions I made, for example those that pull stuff from a database, the function output is rendered first.

WTF I thought, and tested two PHP / Apache combos on two platforms and the behavior is the same.

Say I have:

<<<HEREDOC
1
2
3(function)
4(function)
5
HEREDOC;

What it will be outputted is:

3(function) - result
4(function) - result
1
2
5

**************************

Is there any way I could prevent this, or a workaround, or whatever?

The reason why I ask is that I would like to have clean and reusable snippets of HTML code inside PHP, without nasty includes and breaking out and into the code.


THANKS!! (I know this one is hard.)
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

You need to show us a simple example that does what you're talking about.  Although I don't think I would ever put the functions inside the HEREDOC myself.  I would always assign the function result to a simple variable before the HEREDOC and then use the variable inside it.
Avatar of mrmut

ASKER

I tried to put stuff inside variable before heredoc, but the result was the same. It was outputted before any other heredoc content.

Here is the sample (I will not be able to answer more jsut now, as I will go to sleep now, have to rise up early in the morning).


      
echo <<<HEREDOC
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
{$heredoc(splice_html_title($title))}
</head>
<body>
{$heredoc(splicemaster_return_message())}
{$heredoc(splice_quick_add_article_form())}
{$heredoc(list_articles("archive"))}
{$heredoc(display_all_articles_in_a_html_table())}
</body>
</html>
HEREDOC;
	}

Open in new window



First string calls local title.
Next two call static heredoc html elsewhere.
The final two call functions that build formatted HTML out of the database.

The final two functions are outputted first, before entire HEREDOC, everythng else follows )which is kind of crap, making the function more or less useless for the purpose).
I don't see how that works at all to do anything.  Too much missing to try to help you.
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here is an example showing how to use HEREDOC.  Please post back if you still have questions, ~Ray

<?php // demo/html5_template.php
error_reporting(E_ALL);


// SEE: http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28530287.html
// REF: http://php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc


// CREATE VARIABLES FOR OUR HTML
$dat = date('r');
$xyz = "Hello @mrmut, this page was rendered at $dat";


// CREATE OUR WEB PAGE IN HTML5 FORMAT, USING THE PRE-DEFINED VARIABLES
$htm = <<<EOD
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>HTML5 Page Created with HEREDOC Notation</title>
</head>
<body>

<noscript>Your browsing experience will be much better with JavaScript enabled!</noscript>

<p>$xyz</p>

</body>
</html>
EOD;


// RENDER THE WEB PAGE
echo $htm;

Open in new window


Executive summary: Make it easier on yourself by creating all of the variables first, then use the HEREDOC string as a template; don't try to embed data logic in the "view" portion of the application.
On this page http://us1.php.net/manual/en/language.types.string.php , it says...
Using single curly braces ({}) will not work for accessing the return values of functions or methods or the values of class constants or static class variables.

I got variables and variables returned from functions to work in this simple demo... but I can't get a function to return anything in a HEREDOC no matter what punctuation I put around it.
<?php 
error_reporting(E_ALL);
ini_set('display_errors','1');
 ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>HEREDOC Test</title>
</head>
<body>
<h1>HEREDOC Test</h1>
<?php 
$str1 = "This is string one.";
$str2 = "And this is string 2.";
$here1 = <<<HEREDOC
In this document: $str1 $str2
HEREDOC;

echo $here1;
echo "<br>";

function tfirst() {
	return "This is string one.";
	}
function tsec() {
	return "And this is string 2.";
	}

$fnc1 = tfirst();
$fnc2 = tsec();

$here2 = <<<HEREDOC
In this document: $fnc1 $fnc2
HEREDOC;

echo $here2;
echo "<br>";

$here3 = <<<HEREDOC
In this document: {tfirst()} {tsec()}
HEREDOC;

echo $here3; // this one fails.
echo "<br>";

 ?>
</body>
</html>

Open in new window

echo $here3; // this one fails.
As well it should.  Embedding logic in a display layer violates all kinds of design patterns.  It's one of those things like multiple inheritance.  Experienced programmers know better!
It was part of a simple demonstration of what did and did not work.  And the PHP man page says it won't work either.  I put that together because the OP didn't give an example that we could test.
Yep, good call Dave.
Avatar of mrmut

ASKER

Thanks all! This is overwhelming! Have to read all and test, than I will get back and reply!
Avatar of mrmut

ASKER

Thank you, echoing was the issue, return works as it should.
You are welcome - thanks for the points.
Avatar of mrmut

ASKER

No problems, I am grateful to you. I have also posted this as Stack Overflow with no good answers (apart from the usual: "why I am doing something at all") and have banged my head a LOT about this.

I know that using HEREDOC is not usual modus operandi with these things, but I like the idea of programmatic snippets that I can call from withing the program itself.