Как сопоставить ассоциативный массив с атрибутами элемента html?

Я создаю базовый класс построения форм, чтобы ускорить мой рабочий процесс немного, и я хотел бы иметь массив таких атрибутов:

$attributes = array(
   "type"         => "text",
   "id"           => "contact-name",
   "name"         => "contact-name",
   "required"     => true
);

и сопоставьте это с атрибутами элемента html:

<input type="text" id="contact-name" name="contact-name" required />

EDIT:

Каков самый чистый способ достижения вышеуказанного? Я уверен, что смогу что-то спеть вместе с петлей и некоторой конкатенацией, но я чувствую, что printf или подобное могут сделать это более элегантно.

Ответ 1

Я думаю, что это должно сделать это:

$result = '<input '.join(' ', array_map(function($key) use ($attributes)
{
   if(is_bool($attributes[$key]))
   {
      return $attributes[$key]?$key:'';
   }
   return $key.'="'.$attributes[$key].'"';
}, array_keys($attributes))).' />';

Ответ 2

$attr = array(
    'type'     => 'text',
    'id'       => 'contact-name',
    'name'     => 'contact-name',
    'required' => true,
    'value'    => '" <b>html</b> \'test\''
);

echo '<input '. implode(' ', array_map(
    function ($k, $v) { return $k .'="'. htmlspecialchars($v) .'"'; },
    array_keys($attr), $attr
)) .' />';

Ответ 3

Что-то в этих строках (очень простой метод - конечно, вы можете расширить это, но это предоставит вам базовую функциональность):

$output = "<input ";
foreach($attributes as $key => $value){
    $output .= $key.'="'.$value.'" ';
}
$output .= "/>";

Ответ 4

$output = '<input ';

foreach ($attributes as $name => $value) {
    if (is_bool($value)) {
        if ($value) $output .= $name . ' ';
    } else {
        $output .= sprintf('%s="%s"', $name, $value);
    }
}

$output .= '>';

Для изменения XHTML

    if ($value) $output .= $name . ' ';

to

    if ($value) $output .= sprintf('%s="%s"', $name, $name);

и

    $output .= '>';

к

    $output .= '/>';

Ответ 5

Поскольку http_build_query предназначен для создания ассоциативного массива, я надеялся наткнуться на такое решение здесь. Не нашел, так вот мой "однострочный":

$output = '<input ' . str_replace( '=', '="', http_build_query( $attributes, null, '" ') ) . '" />';

К сожалению:

  • он преобразует значения boolean-values ​​в 1/0 (вместо того, чтобы обмануть их, если false, что может быть достигнуто с помощью array_filter, но приводит к двойным функциональным вызовам);
  • не обрабатывает массив желаемым образом;
  • Требуется urldecode после http_build_query, чтобы вернуть закодированные пробелы (например, при наличии нескольких html-классов в атрибуте).

Итак, подходит только в определенных ситуациях!

Ответ 6

Старая школа PHP 4 - версия 5.2. Это также позволяет использовать массив для атрибута class.

$attributes = array(
    "type"         => "text",
    "class"        => array("one", "two"),
    "id"           => "contact-name",
    "name"         => "contact-name",
    "required"     => true
);

printf(
    '<input %s />', 
    join(' ', array_map('mapAttr', array_keys($attr), array_values($attr)))
);

function mapAttr($key, $value) {
   if (is_array($value)) {
      return mapAttr($key, join(' ', $value));
   }
   if (is_bool($value)) {
      return $value ? $key : '';
   }
   return sprintf('%s="%s"', $key, $value);
}

Ответ 7

Это решение, которое я использую в своих проектах:

function html_attributes($attributes)
{
    if(!$attributes) return '';

    $compiled = join('="%s" ', array_keys($attributes)).'="%s" ';

    return rtrim(vsprintf($compiled, array_map('htmlspecialchars', array_values($attributes))));
}

Ответ 8

Я использую этот:

function html_attributes(array $array) {
    return implode(' ', array_map(function ($key, $value) {
        if (is_array($value)) {
            $value = implode(' ', $value);
        }

        return $key . '="' . htmlspecialchars($value) . '"';
    }, array_keys($array), $array));
}

Это позволяет использовать массив значения атрибута. Пример.

$attrs = [
    'class' => ['foo', 'bar'],
    'id' => 'baz',
];

echo html_attributes($attrs);
// -> `class="foo bar" id="baz"`

'надеюсь, что это поможет кому-то!; -)