2013-08-06 15 views
10

buduję podstawową klasę forma budynku, aby przyspieszyć mój workflow się trochę i chciałbym być w stanie podjąć szereg atrybutów tak:Jak odwzorować tablicę asocjacyjną na atrybuty elementu html?

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

i map, które z atrybutów Element HTML:

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

EDIT:

Co jest najczystszym sposobem osiągnięcia powyższych? Jestem pewien, że mógłbym spleść coś razem z pętlą i jakąś łącznością, ale mam wrażenie, że printf lub podobny mógłby to zrobić w bardziej elegancki sposób.

+0

Więc jakie jest pytanie? –

+0

Więc jeśli zbudowałeś taką klasę, prawdopodobnie spróbowałeś czegoś? I co powiedział @nostrzak;) – dbf

+0

Nie dostałem tego, gdzie jest problem, albo co właściwie chcesz zrobić:] –

Odpowiedz

17

myślę, że to powinno wystarczyć:

$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))).' />'; 
+0

Chciałbym również zauważyć, że wartości atrybutów powinny zostać zmienione przed wyprowadzeniem, jeśli pochodzą z niezaufanego źródła (tj. Danych wejściowych użytkownika). – e1v

3

Coś wzdłuż tych linii (bardzo prosty sposób - oczywiście można przedłużyć, ale ten dostarczy Ci podstawowej funkcjonalności):

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

Przesłałem edycję, która dodaje obsługę elementów logicznych, jak pokazuje to jego pytanie. – Robadob

+0

Dzięki, element boolowski jest szczególnie interesujący. – hamishtaplin

+0

W zależności od tego, jakiego kodu HTML potrzebujesz, booleans może nie być wymagany. HTML5 jest jak twój przykład, XHTML musi jednak być 'wymagany =" wymagany "'. –

3
$output = '<input '; 

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

$output .= '>'; 

Dla zmiany XHTML

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

do

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

i

$output .= '>'; 

do

$output .= '/>'; 
4
$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 
)) .' />'; 
+0

Tak wiele półdziałających rozwiązań, tak bardzo przewijających ... Dzięki w końcu! – DomQ

0

Old school PHP 4 - wersja 5.2. Umożliwia to również utworzenie tablicy dla atrybutu 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); 
} 
2

jako http_build_query jest przeznaczona do stringify asocjacyjna'S, że nadzieję natknąć takiego rozwiązania tutaj. Nie znajdziesz, więc oto moja „jedno-liner”:

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

Niestety:

  1. konwertuje logicznych-wartości 1/0 (zamiast ommiting ich, czy fałszywe, które mogą być osiągnięte przy użyciu array_filter, ale skutkuje podwójnymi wywołaniami funkcji);
  2. nie obsługuje tablic w pożądany sposób;
  3. Wymaga urldecode po http_build_query, aby odzyskać zakodowane spacje (na przykład, gdy ma wiele atrybutów html w atrybucie).

Tak, nadaje się tylko w niektórych sytuacjach!

0

Jest to rozwiązanie używam w moich projektach:

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

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

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

Używam tego:

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)); 
} 

Ten pozwalają wykorzystać tablicę wartości atrybutu. Dawny.

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

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

"mam nadzieję, że komuś pomaga! ;-)

Powiązane problemy