Createelement() method in PHP

Asked

Viewed 1,058 times

5

In javascript, I can do:

var span = document.createElement('span');
span.innerHTML = 'foo';
span.className = 'bar';

Is there something similar for you to create a ElementNode in PHP, at least with the basic attributes (name, class, id, etc.)? Example:

$span = HTML::create('span');
$span->innerHtml = 'foo';
$span->className = 'bar';

echo $span->toString();

And the result be:

<span class="bar">foo</span>
  • 2

    Have you considered using a template engine? With one you inject variables directly into an html, dispensing with the type of function you’re looking to use.

  • I’ll look it up to see what it’s like.

3 answers

5

Directly there is no function for this, the closest thing is the DOMDocument::createElement, but is oriented to XML. However, it is relatively simple to implement a proper function for this.

Here’s a simple one to understand, coming of this website.:

class html_element
{
    /* vars */
    var $type;
    var $attributes;
    var $self_closers;

    /* constructor */
    function html_element($type,$self_closers = array('input','img','hr','br','meta','link'))
    {
        $this->type = strtolower($type);
        $this->self_closers = $self_closers;
    }

    /* get */
    function get($attribute)
    {
        return $this->attributes[$attribute];
    }

    /* set -- array or key,value */
    function set($attribute,$value = '')
    {
        if(!is_array($attribute))
        {
            $this->attributes[$attribute] = $value;
        }
        else
        {
            $this->attributes = array_merge($this->attributes,$attribute);
        }
    }

    /* remove an attribute */
    function remove($att)
    {
        if(isset($this->attributes[$att]))
        {
            unset($this->attributes[$att]);
        }
    }

    /* clear */
    function clear()
    {
        $this->attributes = array();
    }

    /* inject */
    function inject($object)
    {
        if(@get_class($object) == __class__)
        {
            $this->attributes['text'].= $object->build();
        }
    }

    /* build */
    function build()
    {
        //start
        $build = '<'.$this->type;

        //add attributes
        if(count($this->attributes))
        {
            foreach($this->attributes as $key=>$value)
            {
                if($key != 'text') { $build.= ' '.$key.'="'.$value.'"'; }
            }
        }

        //closing
        if(!in_array($this->type,$this->self_closers))
        {
            $build.= '>'.$this->attributes['text'].'</'.$this->type.'>';
        }
        else
        {
            $build.= ' />';
        }

        //return it
        return $build;
    }

    /* spit it out */
    function output()
    {
        echo $this->build();
    }
}

Example of use:

$my_anchor = new html_element('a');
$my_anchor->set('href','http://davidwalsh.name');
$my_anchor->set('title','David Walsh Blog');
$my_anchor->set('text','Click here!');
$my_anchor->output();
//<a href="http://davidwalsh.name" title="David Walsh Blog">Click here!</a>

Author: David Walsh

Follow the example adapted to the parameters given in the question:

$span = new html_element('span');
$span->set('text', 'foo');
$span->set('class', 'bar');
$span->output();
//<span class="bar">foo</span>
  • To make the appends? Yeah, apparently, I’m gonna have to "reinvent the wheel" one more time.

  • 3

    @Calebeoliveira added an example with the data of your question. Once implemented the function, it is very simple to use. Until reinventing the wheel sometimes isn’t so bad. Although I had an acquaintance who was against it, and today he has a Ferrari -> http://files.box.net.br/MinhaFerrari.jpg

3

Exists in PHP a domdocument class, which makes it possible to achieve the desired.

Example making use of the method createelement:

<?php
$domDocumento = new DOMDocument('1.0', "UTF-8");
$domElemento = $domDocument->createElement('field','conteudo');
$domAtributo = $domDocument->createAttribute('name');

// Setando valor para o atributo
$domAtributo->value = 'valor';

// Inserindo atributo no elemento
$domElemento->appendChild($domAtributo);

// Inserindo elemento no documento
$domDocumento->appendChild($domElemento);
?>

2


For the complete XML (or XHTML) creation the best solution is the DOMDocument, as mentioned in the other replies.

However, if your goal is simply to create an HTML tag in a simple way, I believe there are simpler ways.

Simple solution: a function

In a few minutes I drafted the following function:

function createElement($tag_name, array $attributes = array(), $content = null) {

    $attr_text = '';
    foreach ($attributes as $name => $value) {
        $attr_text .= ' ' . $name . '="' . $value . '"';
    }
    return '<' . $tag_name . $attr_text . 
            (is_null($content) ? '/>' : '>' . $content . '</' . $tag_name . '>');

}

Examples of use:

createElement('br');
createElement('button', array(), '');
createElement('input', array('type' => 'submit', 'id' => 'enviar'));
createElement('textarea', array('id' => 'caixa-de-texto'), 'Contéudo da textarea');

Callback above in order:

<br/>
<button></button>
<input type="submit" id="enviar"/>
<textarea id="caixa-de-texto">Contéudo da textarea</textarea>

See the functional example in http://codepad.org/a4qLJZq8.

If you find a different case, you can simply improve the function.

A little more complete solution: a class

I found at this link a class created exactly for the same purpose as this question. The implementation is not complicated and allows an object-oriented approach.

Follows the code:

/* creates an html element, like in js */
class html_element
{
    /* vars */
    var $type;
    var $attributes;
    var $self_closers;

    /* constructor */
    function html_element($type,$self_closers = array('input','img','hr','br','meta','link'))
    {
        $this->type = strtolower($type);
        $this->self_closers = $self_closers;
    }

    /* get */
    function get($attribute)
    {
        return $this->attributes[$attribute];
    }

    /* set -- array or key,value */
    function set($attribute,$value = '')
    {
        if(!is_array($attribute))
        {
            $this->attributes[$attribute] = $value;
        }
        else
        {
            $this->attributes = array_merge($this->attributes,$attribute);
        }
    }

    /* remove an attribute */
    function remove($att)
    {
        if(isset($this->attributes[$att]))
        {
            unset($this->attributes[$att]);
        }
    }

    /* clear */
    function clear()
    {
        $this->attributes = array();
    }

    /* inject */
    function inject($object)
    {
        if(@get_class($object) == __class__)
        {
            $this->attributes['text'].= $object->build();
        }
    }

    /* build */
    function build()
    {
        //start
        $build = '<'.$this->type;

        //add attributes
        if(count($this->attributes))
        {
            foreach($this->attributes as $key=>$value)
            {
                if($key != 'text') { $build.= ' '.$key.'="'.$value.'"'; }
            }
        }

        //closing
        if(!in_array($this->type,$this->self_closers))
        {
            $build.= '>'.$this->attributes['text'].'</'.$this->type.'>';
        }
        else
        {
            $build.= ' />';
        }

        //return it
        return $build;
    }

    /* spit it out */
    function output()
    {
        echo $this->build();
    }
}

Example of use:

$my_anchor = new html_element('a');
$my_anchor->set('href','http://davidwalsh.name');
$my_anchor->set('title','David Walsh Blog');
$my_anchor->set('text','Click here!');
$my_anchor->output();

This generates the output:

<a href="http://davidwalsh.name" title="David Walsh Blog">Click here!</a>

This basic implementation does almost the same thing as the function presented in the previous topic, but allows you to easily extend the functionalities.

Reading the comments of the site where I found the class is possible to find several improvement posts for the class, for example the possibility to include child elements or a function to set CSS styles individually.

Personally, I would include setters to receive both attribute and style associative array.

Complete solution: a library

After looking at all the comments from the previous link, I saw that someone took the same idea and wrote a small library called phpcreatehtml to make creating HTML easier.

See an example of use:

$php=create('html',
  $head = head(title('My Page')),
  body(
    $header = div('class','header'),
    $body = div('class','main'),
    $footer = div('class','footer')
  )
);
$body->append(h1('This example'));
$body->append(
  h2('is more convenient!'),
  div('class','main')->append(
    p('It uses less confusing technics to code.')
  )
);
echo $php;

This generates the following output:

<html>
  <head>
    <title>My Page</title>
  </head>
  <body>
    <div class="header"></div>
    <div class="main">
      <h1>This example</h1>
      <h2>is more convenient!</h2>
      <div class="main">
        <p>It uses less confusing technics to code.</p>
      </div>
    </div>
    <div class="footer"></div>
  </body>
</html>

Conclusions

I don’t think you’ll need to "reinvent the wheel one more time" because several people have done.

Just define the level of complexity you will need. If it’s just to print simple elements, I’d go for the simplest solution (function) and so on.

  • To each element, I want to add a list of elements (Childs), as well as the DOM. What do you think? So I can easily access elements within other elements.

  • @Calebeoliveira I don’t quite understand your goal. Besides generating, do you want to access/manipulate in memory yet? Can you tell what your ultimate goal is with this implementation?

  • It is part of a framework that I build, this will manipulate the html of some views.

  • 1

    @Calebeoliveira In this case it is better to use the DOM of PHP. The methods I posted here are for creating simple elements. With the DOM you can load the HTML and manipulate the content programmatically.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.