Section 5: Advanced Output Manipulation

Using If Statements

XPHP content can be conditionally evaluated in your web page, thanks to support for if statements. To set an if statement on an XPHP tag, use the <if> tag.

There are two manners in which if statements can be used. The first involves checking for the presence of a PHP variable:

<!-- prints the output of foo() only if $GLOBALS['bar'] exists and has a non-empty value: -->
<xphp function="foo">
    <if var="bar"/>
</xphp>
	

In this case, the if statement is the equivalent of: if (isset($GLOBALS['bar']) && !empty($GLOBALS['bar'])). In most cases we will want to check for a GET or POST variable. If statements support the same scopes that XPHP variable tags do:

<xphp function="foo">
    <if var="bar" type="get"/>
</xphp>
	

XPHP also supports checking if a PHP variable is set to a specified value:

<!-- prints the output of foo() only if $_GET['bar']==3: -->
<xphp function="foo">
    <if var="bar" type="get" value="3"/>
</xphp>
	

If statements are applicable to any type of XPHP content, including user-defined types.

Else

XPHP also supports else cases. An <else> tag is parsed exactly as if it were another XPHP tag, but only if the original if case fails to be satisfied.

<xphp function="foo">
    <if var="foo"/>
    <else function="bar"/>
</xphp>
		

In the above example, if global var "foo" is set and not empty, function "foo" will be called, otherwise, the function "bar" will be called.

Note: The <else> tags can have exactly the same attributes and arguments as a normal XPHP tag.

Caching

Suppose you need to place the same XPHP content in your web page more than once. If that XPHP tag has to do a significant amount of work to determine its value, then your script would waste CPU cycles needlessly in order to construct the output twice. That is, only if we didn't use content caching.

Any XPHP tag can be assigned a unique cache id. If multiple XPHP tags with the same cache id are found, only the first instance will be parsed, and all subsequent such tags will return their content from an internal cache:

<!-- someComplexFunction() called: -->
<xphp function="someComplexFunction" cache="foo"/>
<!-- returns cached value of someComplexFunction() output: -->
<xphp function="someComplexFunction" cache="foo"/>
	

Note: A cache id will equate XPHP tags regardless of whether they contain different attributes or arguments.

Caching With APC

APC is free, popular opcode cache for PHP. One of the features of APC is the ability to store PHP variables in shared memory for fast retrieval, such that they persist between server requests and are shared between all users accessing the site.

There is built-in support to seamlessly store your XPHP content in APC's cache. This is implemented as an extension to the normal, internal caching that XPHP provides. To store your XPHP content with APC, just set the apc attribute to "true". By default, the content's TTL (time to live) is 0 (indefinitely). You can specify a TTL by setting the ttl attribute:

	
<xphp function="foo" cache="bar"/> <!-- uses internal cache -->
<xphp function="foo" cache="bar" apc="true"/> <!-- uses apc, ttl=0 -->
<xphp function="foo" cache="bar" apc="true" ttl="3600"/> <!-- uses apc, ttl=3600 -->
	

APC-stored content with a non-zero ttl will expire after ttl-seconds, at which time XPHP will regenerate the content and store it back in APC for the same period of time.

Using Eval

There may be a situation in which an XPHP tag returns content which, in turn, contains another XPHP tag. In this case you can use the eval attribute to tell the XPHP engine to re-parse the resulting content for any new XPHP tags that were generated:

<?php
require '/path/to/class.xphp.php';
$php=new XPHP();
$_GET['bar']='world';

function foo() {
return 'hello <xphp var="bar" type="get"/>';
}

?>

<xphp function="foo" eval="true"/> <!-- prints "hello world" -->
	

In the above example, foo() returns a string containing an XPHP tag, which is then re-parsed in order to construct the final output: "hello world".

Note/Security: Though eval may be useful in some circumstances, inappropriate use of eval in both XPHP and PHP (via the eval() function) is not considered best practice, for reasons of security, performance, and code clarity.

Nesting XPHP Tags

Nesting XPHP tags is similar to eval, in that it involves recursion, however instead of having an XPHP tag re-parsed after content generation, a nested XPHP tag is parsed before content generation. This may be critically useful if an argument in your XPHP tag must contain a GET or POST variable.

In order to nest an XPHP tag inside another, you must set the inner attribute to "true":

<xphp function="databaseRetrievalFunction">
    <arg id="query">SELECT title,author FROM books WHERE id=<xphp var="id" type="get" cast="int" inner="true"/></arg>
</>
	

Note: The XPHP engine only supports nesting one level deep for the same reasons given in the note about eval. Additionally, since an inner XPHP tag is parsed before the outer one, a cache id on the outer XPHP tag will not prevent the inner one from being processed.

Pushing Files

In section 1 it was mentioned that you can run XPHP in manual mode. One additional feature of manual mode is that the parseFile() function can be used to push static files to the server's file system. This is useful, for example, if you have a cron scheduled to routinely parse XPHP files and output their generated content as static html files.

To push a static page with transformed XPHP tags, use the optional second parameter for the parseFile() function:

$xphp=new XPHP(false);
$xphp->parseFile('/path/to/source/file','/path/to/output/file');
	

« Previous Section | Section 6 of 6: Final Thoughts »