Return to Snippet

Revision: 62059
at January 31, 2013 10:42 by ryanve


Initial Code
/**
 * Parse an attributes string into an array. If the string starts with a tag,
 * then the attributes on the first tag are parsed. This parses via a manual
 * loop and is designed to be safer than using DOMDocument.
 *
 * @param    string|*   $attrs
 * @return   array
 *
 * @example  parse_attrs( 'src="example.jpg" alt="example"' )
 * @example  parse_attrs( '<img src="example.jpg" alt="example">' )
 * @example  parse_attrs( '<a href="example"></a>' )
 * @example  parse_attrs( '<a href="example">' )
 */
function parse_attrs ($attrs) {

    if ( ! \is_scalar($attrs) )
        return (array) $attrs;

    $attrs = \str_split( \trim($attrs) );
    
    if ( '<' === $attrs[0] ) # looks like a tag so strip the tagname
        while ( $attrs && ! \ctype_space($attrs[0]) && $attrs[0] !== '>' )
            \array_shift($attrs);

    $arr = array(); # output
    $name = '';     # for the current attr being parsed
    $value = '';    # for the current attr being parsed
    $mode = 0;      # whether current char is part of the name (-), the value (+), or neither (0)
    $stop = false;  # delimiter for the current $value being parsed
    $space = ' ';   # a single space

    foreach ( $attrs as $j => $curr ) {
        
        if ( $mode < 0 ) {# name
            if ( '=' === $curr ) {
                $mode = 1;
                $stop = false;
            } elseif ( '>' === $curr ) {
                '' === $name or $arr[ $name ] = $value;
                break; 
            } elseif ( ! \ctype_space($curr) ) {
                if ( \ctype_space( $attrs[ $j - 1 ] ) ) { # previous char
                    '' === $name or $arr[ $name ] = '';   # previous name
                    $name = $curr;                        # initiate new
                } else {
                    $name .= $curr;
                }
            }
        } elseif ( $mode > 0 ) {# value
            if ( $stop === false ) {
                if ( ! \ctype_space($curr) ) {
                    if ( '"' === $curr || "'" === $curr ) {
                        $value = '';
                        $stop = $curr;
                    } else {
                        $value = $curr;
                        $stop = $space;
                    }
                }
            } elseif ( $stop === $space ? \ctype_space($curr) : $curr === $stop ) {
                $arr[ $name ] = $value;
                $mode = 0;
                $name = $value = '';
            } else {
                $value .= $curr;
            }
        } else {# neither

            if ( '>' === $curr )
                break;
            if ( ! \ctype_space( $curr ) ) {
                # initiate 
                $name = $curr; 
                $mode = -1;
            }
        }
    }

    # incl the final pair if it was quoteless
    '' === $name or $arr[ $name ] = $value;

    return $arr;
}

Initial URL
http://dev.airve.com/demo/speed_tests/php/parse_attrs.php

Initial Description
Parse an attributes string into an array. If the string starts with a tag, then the attributes on the first tag are parsed. This parses via a manual loop and is designed to be safer than using DOMDocument.

Initial Title
Parse Attributes

Initial Tags


Initial Language
PHP