Solved

PHP HEREDOC parsing process?

Posted on 2014-10-02
13
195 Views
Last Modified: 2014-10-03
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.)
0
Comment
Question by:mrmut
  • 4
  • 4
  • 3
  • +1
13 Comments
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 40358139
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.
0
 

Author Comment

by:mrmut
ID: 40358152
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).
0
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 40358174
I don't see how that works at all to do anything.  Too much missing to try to help you.
0
 
LVL 52

Accepted Solution

by:
Julian Hansen earned 500 total points
ID: 40358214
In your custom functions are you using echo to output the results or return?

If you are using echo you will get the results you have seen for obvious reasons - you would need to use a return.

This simple code seems to work - if I understand your question it is what you are wanting?
<!doctype html>
<html>
<head>
<title>Test</title>
<script src="http://code.jquery.com/jquery.js"></script>
</head>
<body>
<?php
function myTestFunction($d)
{
	return "The square of {$d} is " . ($d * $d);
}
function heredoc($d) 
{
	return $d;
}
$heredoc = 'heredoc';
echo <<< HEREDOC
This is a test to see if this
{$heredoc(myTestFunction(2))}
Is called at the right point
HEREDOC;
?>
</body>
</html>

Open in new window

Outputs
This is a test to see if this The square of 2 is 4 Is called at the right point 

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40358226
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.
0
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 40358259
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

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40358267
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!
0
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 40358288
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.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40358426
Yep, good call Dave.
0
 

Author Comment

by:mrmut
ID: 40358736
Thanks all! This is overwhelming! Have to read all and test, than I will get back and reply!
0
 

Author Closing Comment

by:mrmut
ID: 40359602
Thank you, echoing was the issue, return works as it should.
0
 
LVL 52

Expert Comment

by:Julian Hansen
ID: 40359653
You are welcome - thanks for the points.
0
 

Author Comment

by:mrmut
ID: 40359664
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.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article discusses four methods for overlaying images in a container on a web page
Introduction This article is intended for those who are new to PHP error handling (https://www.experts-exchange.com/articles/11769/And-by-the-way-I-am-New-to-PHP.html).  It addresses one of the most common problems that plague beginning PHP develop…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to dynamically set the form action using jQuery.

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now