Can PHP include work for only a specified portion

2019-01-20 17:34发布

I have a PHP include that inserts an html form into another html form. When the form gets included I now have two form headers. Is there a php tag I could use that would allow me to...

<form id="orderform">

<!-- <?php for the include FROM here?> -->

PROD:<input class="ProductName" type="text" size="75">|
Discount:<input class="Discount" type="text" size="3">|
QTY:<input class="qty" type="text" size="6">|
Line/Total:<input class="LineTotal" type="text" size="9" disabled>

<!-- <?php for the include TO here?> -->

</form>

So the include would go into that file with the form in it and get the specified HTML?

Is this possible?

EDIT

<?php 
$dom = new DOMDocument();
$html = 'phptest3.php';
$dom->loadHTMLFile($html);
$div = $dom->getElementById("divtagid");
echo $div->nodeValue;
?>

This only returns the text. How do I get the HTML form elements in the divtagid?

标签: php include
3条回答
成全新的幸福
2楼-- · 2019-01-20 18:02

You can structure your include file like an XML file with processing instructions­XML (DOMProcessingInstruction­Docs). Such a file would only miss the XML root element, which could be added on the fly.

The benefit of this is, that it is compatible with both XHTML and PHP as long as you write PHP with the standard tags like <?php ... ?> because those are a valid XML processing instruction. Let's start with a simple, XHTML only example, the principle with PHP code is actually the same, but why make it complicated?

include.php:

<form id="orderform">

    Text: <input name="element" />

</form>

To create an include function that can deal with this, it only needs to parse the XML file and return the fragment in question, e.g. everything inside the <form> tag. XML parsing ships with PHP, so everything is already ready to action.

function incXML($file, $id = NULL)
{
    if (!($xml = file_get_contents($file)))
        throw new Exception('File IO error.');

    $xml = '<template>' . $xml . '</template>';

    $doc = new DOMDocument();
    if (!$doc->loadXML($xml))
        throw new InvalidArgumentException('Invalid file.');

    // @todo add HTML namespace if you want to support it

    // fetch the contents of the file however you need to,
    // e.g. with an xpath query, I leave this for a training
    // and just do a plastic getElementById here which does NOT
    // work w/o proper DTD support, it's just for illustration.

    if (NULL === $id)
    {
        $part = $doc;
    }
    else
    {
        if (!$part = $doc->getElementById($id))
            throw new InvalidArgumentException('Invalid ID.');
    }

    $buffer = '';
    foreach($part->childNodes as $node)
    {
        $buffer .= $doc->saveXML($node);
    }

    return 'data:text/html;base64,' . base64_encode($buffer);
}

Usage:

<?php
    include(incXML('include.php', 'orderform'))
?>

You don't need to change any of your template files as long as they contain XHTML/PHP in the end with such a method.

查看更多
ら.Afraid
3楼-- · 2019-01-20 18:03

You should best look into php functions for this.

<?php
function form_tag_wrapper($form) {
  return '<form id="orderform">'. $form .'</form>';
}

function form_contents() {
  return 'PROD:<input class="ProductName" type="text" size="75">
          ...
          Line/Total:<input class="LineTotal" type="text" size="9" disabled>';
}
?>

You will use this as:

$form = form_contents();
print form_tag_wrapper($form);

Or, as a oneliner:

print form_tag_wrapper(form_contents());
查看更多
看我几分像从前
4楼-- · 2019-01-20 18:20

No, there isn't an alternate way to include a portion of a file. Consider: how would you describe to such a function where to start and end inclusion? How would the function know what you want?

As suggested, the best approach would be to refactor the included file. If that isn't an option (I can't imagine why it wouldn't be), another route is to use variables or constants in the included file to denote which portions should be output. Something like this:

#File: form_template.php
<?php if (!isset($include_form_header) || $include_form_header == true) { ?>
<form id="orderform">
<?php } ?>

PROD:<input class="ProductName" type="text" size="75">|
Discount:<input class="Discount" type="text" size="3">|
QTY:<input class="qty" type="text" size="6">|
Line/Total:<input class="LineTotal" type="text" size="9" disabled>

<?php if (!isset($include_form_header) || $include_form_header == true) { ?>
</form>
<?php } ?>

Now, when you want to stop the form header from being output:

$include_form_header = false;
include('form_template.php');

This is nasty, IMO. When someone else (or the future you) edits form_template.php, it may not be apparent when or why $include_form_header would be set. This kind of reliance on variables declared in external files can lead to spaghetti code.

You're far better building separate templates for different purposes (or directly echoing trivial output, like one line of html to open or close a form), for instance:

<?php
    #File: order_form_wrapper.php
    echo '<form id="orderform">';
?>

<?php
    #File: product_fields.php
    echo 'PROD:<input class="ProductName" type="text" size="75">';
    echo 'Discount:<input class="Discount" type="text" size="3">';
    echo 'QTY:<input class="qty" type="text" size="6">|';
    echo 'Line/Total:<input class="LineTotal" type="text" size="9" disabled>';
?>

// form with wrapper
include 'order_form_wrapper.php';
include 'product_fields.php';
echo '</form>';

// different form with wrapper
include 'some_other_form_wrapper.php';
include 'product_fields.php';
include 'some_other_fields.php';
echo '</form>';

Last option, if you have absolutely no access to the template, can't modify it, can only include it, then you could use output buffering to include the file, load the resulting HTML into DOMDocument, then peal off the wrapping form tags. Take a look at the code... this isn't exactly "neat" either:

function extract_form_contents($template)
    // enable output buffer, include file, get buffer contents & turn off buffer
    ob_start();
    include $template;
    $form = ob_get_clean();
    ob_end_clean();

    // create a new DOMDocument & load the form HTML 
    $doc = new DOMDocument();
    $doc->loadHTML($form);

    // since we are working with an HTML fragment here, remove <!DOCTYPE, likewise remove <html><body></body></html> 
    $doc->removeChild($doc->firstChild);            
    $doc->replaceChild($doc->firstChild->firstChild->firstChild, $doc->firstChild);

    // make a container for the extracted elements
    $div = $doc->createElement('div');

    // grab the form    
    $form = $doc->getElementsByTagName('form');
    if ($form->length < 1)
        return '';
    $form = $form->item(0);

    // loop the elements, clone, place in div
    $nb = $form->childNodes->length;
    if ($nb == 0)
        return '';
    for($pos=0; $pos<$nb; $pos++) {
        $node = $form->childNodes->item($pos);
        $div->appendChild($node->cloneNode(true));
    }
    // swap form for div
    $doc->replaceChild($div, $form);
    return $doc->saveHTML();
}
$contents = extract_form_contents('my_form_template.php');
查看更多
登录 后发表回答