2013-08-06 64 views
10

我建立一個基本形式的建築類,以加快我的工作流了一點,我想能夠採取的屬性的數組,像這樣:如何將關聯數組映射到html元素屬性?

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

和地圖,爲的屬性html元素:

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

編輯:

什麼是實現上述的清潔方法是什麼?我確信我可以用一個循環和一些連接拼湊一些東西,但是我感覺printf或類似的東西可以以更優雅的方式做到這一點。

+0

那麼問題是什麼? –

+0

所以,如果你建立了這樣一個班級,你可能試過一些東西?和@nostrzak說什麼;) – dbf

+0

我沒有得到它,問題在哪裏,或者你想要做什麼:] –

回答

17

我想這應該這樣做:

$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

另外我想注意的是,如果屬性值取自不可信源(即用戶輸入),則應在輸出之前將屬性值轉義。 – e1v

3

東西沿着這些路線(一個非常簡單的方法 - 當然,你可以擴展這一點,但是這會爲您提供的基本功能):

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

我已經提交了一個編輯,添加了對布爾元素的支持,如他的問題所示。 – Robadob

+0

謝謝,布爾元素是特別感興趣的。 – hamishtaplin

+0

根據你想要的HTML,布爾可能不是必需的。 HTML5就像你的例子,但是XHTML必須是'required ='required''。 –

3
$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 . ' '; 

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

$output .= '>'; 

$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

如此多的半工作解決方案,如此之多的向下滾動......最後感謝! – DomQ

0

老同學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); 
} 
2

由於http_build_query是爲字符串化關聯數組的,我希望在這裏這樣的解決方案絆倒。一個也沒找到,所以這裏是我的「一班輪」:

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

不幸的是:

  1. 它布爾值轉換爲1/0(而不是虛假的,如果他們ommiting,它可以是通過使用array_filter實現,但導致雙重函數調用);
  2. 不以所需的方式處理數組;
  3. 需要urldecodehttp_build_query之後找回編碼空間(例如,在屬性中有多個html類時)。

所以,只適用於某些情況!

0

這是一個解決方案,我在我的項目中使用:

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

我用這一個:

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"` 

'希望它可以幫助別人! ;-)

相關問題