As you know, the h开发者_StackOverflow中文版eaders_list()
-PHP-function returns an array like this:
Array
(
[0] => Content-type: text/html; charset=utf-8
[1] => key: value
[2] => key2: value2
)
In general (or with this example), how can you build a new array using the "key" in the arrays value? For example, the array above becomes:
Array
(
['Content-type'] => text/html; charset=utf-8
['key'] => value
['key2'] => value2
)
This is probably really basic, but I am still a beginner :)
This should work:
$headers = header_list();
foreach($headers as $header){
// split each header by ':' and assign them to $key and $value
list($key, $value) = explode(':', $header, 2); // limit the explode to 2 items.
// add trimed variables to the new array
$new_headers[trim($key)] = trim($value);
}
Probably trim for $key
is not really important, but for value it really is, because you will remove the space after the ':'.
You should use this function apache_response_headers instead , is return the header in array ...
however, the function name expose it works for apache only
updated: PHP need to compile with --with-apxs2
foreach($headers as $v) {
list($name,$val) = explode(': ',$v);
$newArray[$name] = $val;
}
// $newArray is your requested array.
The following function is be able to handle multiple header fields with the same field name and combines them as stipulated by the specification:
Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]. It MUST be possible to combine the multiple header fields into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field-value to the first, each separated by a comma.
function getHeaderFields() {
$fields = array();
$index = array();
foreach (headers_list() as $field) {
list($name, $value) = explode(':', $field, 2);
$name = trim($name);
if (isset($index[strtolower($name)])) {
$name = $index[strtolower($name)];
} else {
$index[strtolower($name)] = $name;
}
if (isset($fields[$name])) {
$fields[$name] .= ', '.trim($value);
} else {
$fields[$name] = trim($value);
}
}
return $fields;
}
This works in opposite to apache_response_headers
or the other mentioned solutions:
setcookie('foo', 'bar');
setcookie('bar', 'quux');
$headers = getHeaderFields();
var_dump($headers['Set-Cookie']); // string(17) "foo=bar, bar=quux"
$headers = apache_response_headers();
var_dump($headers['Set-Cookie']); // string(8) "bar=quux"
$headers = header_list();
$keyed_headers = array();
foreach ($headers as $header) {
$break = explode(': ', $header, 2);
$keyed_headers[$break[0]] = $break[1];
}
UPDATE
On a whim, I decided that it would be MoarAwesomeTM to solve this problem using a class. This was the result:
// definition
class HeaderArray extends ArrayObject {
static function init() {
return new self(header_list());
}
public function get_assoc() {
$result = new self();
foreach ($this as $v) {
$b = explode(': ', $v, 2);
$result[$b[0]] = $b[1];
}
return $result;
}
}
// implementation
$headers = HeaderArray::init()->get_assoc();
I think this is better: you should reimplode the remainder in case there was a ':' in a value
$hList = headers_list();
foreach ($hList as $header) {
$header = explode(":", $header);
$headers[ array_shift($header) ] = trim( implode(":", $header) );
}
My Solution:
/**
* Get HTTP Response Headers
*
* @param null|string $key
*
* @return array|mixed|string|null
*/
function get_response_headers( $key = null ) {
$headers = [];
if ( ! empty( $key ) ) {
$key = strtolower( $key );
}
foreach ( headers_list() as $header ) {
$header = explode( ":", $header );
$index = trim( array_shift( $header ) );
$value = trim( implode( ":", $header ) );
if (
! empty( $key ) &&
$key === strtolower( $index )
) {
return $value;
}
$headers[ $index ] = $value;
}
if ( ! empty( $key ) ) {
return null;
}
return $headers;
}
精彩评论