Как сопоставить ассоциативный массив с атрибутами элемента 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"`
'надеюсь, что это поможет кому-то!; -)