Solved

PHP HEREDOC parsing process?

Posted on 2014-10-02
13
201 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
Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

 
LVL 54

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 109

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
 
LVL 109

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 109

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 54

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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
javascript: add id amounts 5 47
Can't find PHP files on account that has WordPress 3 26
send post values 7 26
Change background color in td if any value is 1 9 11
Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
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 look for a specific file type in a local or remote server directory using PHP.

770 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