Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
ad06b80e
Commit
ad06b80e
authored
Feb 26, 2014
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enhanced parsing the accept header.
parent
452c486f
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
122 additions
and
22 deletions
+122
-22
Request.php
framework/web/Request.php
+81
-22
RequestTest.php
tests/unit/framework/web/RequestTest.php
+41
-0
No files found.
framework/web/Request.php
View file @
ad06b80e
...
...
@@ -885,9 +885,23 @@ class Request extends \yii\base\Request
/**
* Returns the content types acceptable by the end user.
* This is determined by the `Accept` HTTP header.
* @return array the content types ordered by the preference level. The first element
* represents the most preferred content type.
* This is determined by the `Accept` HTTP header. For example,
*
* ```php
* $_SERVER['HTTP_ACCEPT'] = 'text/plain; q=0.5, application/json; version=1.0, application/xml; version=2.0;';
* $types = $request->getAcceptableContentTypes();
* print_r($types);
* // displays:
* // [
* // 'application/json' => ['q' => 1, 'version' => '1.0'],
* // 'application/xml' => ['q' => 1, 'version' => '2.0'],
* // 'text/plain' => ['q' => 0.5],
* // ]
* ```
*
* @return array the content types ordered by the quality score. Types with the highest scores
* will be returned first. The array keys are the content types, while the array values
* are the corresponding quality score and other parameters as given in the header.
*/
public
function
getAcceptableContentTypes
()
{
...
...
@@ -902,8 +916,12 @@ class Request extends \yii\base\Request
}
/**
* Sets the acceptable content types.
* Please refer to [[getAcceptableContentTypes()]] on the format of the parameter.
* @param array $value the content types that are acceptable by the end user. They should
* be ordered by the preference level.
* @see getAcceptableContentTypes()
* @see parseAcceptHeader()
*/
public
function
setAcceptableContentTypes
(
$value
)
{
...
...
@@ -937,7 +955,7 @@ class Request extends \yii\base\Request
{
if
(
$this
->
_languages
===
null
)
{
if
(
isset
(
$_SERVER
[
'HTTP_ACCEPT_LANGUAGE'
]))
{
$this
->
_languages
=
$this
->
parseAcceptHeader
(
$_SERVER
[
'HTTP_ACCEPT_LANGUAGE'
]
);
$this
->
_languages
=
array_keys
(
$this
->
parseAcceptHeader
(
$_SERVER
[
'HTTP_ACCEPT_LANGUAGE'
])
);
}
else
{
$this
->
_languages
=
[];
}
...
...
@@ -956,45 +974,86 @@ class Request extends \yii\base\Request
/**
* Parses the given `Accept` (or `Accept-Language`) header.
* This method will return the acceptable values ordered by their preference level.
*
* This method will return the acceptable values with their quality scores and the corresponding parameters
* as specified in the given `Accept` header. The array keys of the return value are the acceptable values,
* while the array values consisting of the corresponding quality scores and parameters. The acceptable
* values with the highest quality scores will be returned first. For example,
*
* ```php
* $header = 'text/plain; q=0.5, application/json; version=1.0, application/xml; version=2.0;';
* $accepts = $request->parseAcceptHeader($header);
* print_r($accepts);
* // displays:
* // [
* // 'application/json' => ['q' => 1, 'version' => '1.0'],
* // 'application/xml' => ['q' => 1, 'version' => '2.0'],
* // 'text/plain' => ['q' => 0.5],
* // ]
* ```
*
* @param string $header the header to be parsed
* @return array the accept values ordered by their preference level.
* @return array the acceptable values ordered by their quality score. The values with the highest scores
* will be returned first.
*/
p
rotected
function
parseAcceptHeader
(
$header
)
p
ublic
function
parseAcceptHeader
(
$header
)
{
$accepts
=
[];
$n
=
preg_match_all
(
'/\s*([\w\/\-\*]+)\s*(?:;\s*q\s*=\s*([\d\.]+))?[^,]*/'
,
$header
,
$matches
,
PREG_SET_ORDER
);
for
(
$i
=
0
;
$i
<
$n
;
++
$i
)
{
if
(
!
empty
(
$matches
[
$i
][
1
]))
{
$accepts
[]
=
[
$matches
[
$i
][
1
],
isset
(
$matches
[
$i
][
2
])
?
(
float
)
$matches
[
$i
][
2
]
:
1
,
$i
];
foreach
(
explode
(
','
,
$header
)
as
$i
=>
$part
)
{
$params
=
preg_split
(
'/\s*;\s*/'
,
trim
(
$part
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
if
(
empty
(
$params
))
{
continue
;
}
$values
=
[
'q'
=>
[
$i
,
array_shift
(
$params
),
1
],
];
foreach
(
$params
as
$param
)
{
if
(
strpos
(
$param
,
'='
)
!==
false
)
{
list
(
$key
,
$value
)
=
explode
(
'='
,
$param
,
2
);
if
(
$key
===
'q'
)
{
$values
[
'q'
][
2
]
=
(
double
)
$value
;
}
else
{
$values
[
$key
]
=
$value
;
}
}
else
{
$values
[]
=
$param
;
}
}
$accepts
[]
=
$values
;
}
usort
(
$accepts
,
function
(
$a
,
$b
)
{
if
(
$a
[
1
]
>
$b
[
1
])
{
$a
=
$a
[
'q'
];
// index, name, q
$b
=
$b
[
'q'
];
if
(
$a
[
2
]
>
$b
[
2
])
{
return
-
1
;
}
elseif
(
$a
[
1
]
<
$b
[
1
])
{
}
elseif
(
$a
[
2
]
<
$b
[
2
])
{
return
1
;
}
elseif
(
$a
[
0
]
===
$b
[
0
])
{
return
$a
[
2
]
>
$b
[
2
]
?
1
:
-
1
;
}
elseif
(
$a
[
0
]
===
'*/*'
)
{
}
elseif
(
$a
[
1
]
===
$b
[
1
])
{
return
$a
[
0
]
>
$b
[
0
]
?
1
:
-
1
;
}
elseif
(
$a
[
1
]
===
'*/*'
)
{
return
1
;
}
elseif
(
$b
[
0
]
===
'*/*'
)
{
}
elseif
(
$b
[
1
]
===
'*/*'
)
{
return
-
1
;
}
else
{
$wa
=
$a
[
0
][
strlen
(
$a
[
0
])
-
1
]
===
'*'
;
$wb
=
$b
[
0
][
strlen
(
$b
[
0
])
-
1
]
===
'*'
;
$wa
=
$a
[
1
][
strlen
(
$a
[
1
])
-
1
]
===
'*'
;
$wb
=
$b
[
1
][
strlen
(
$b
[
1
])
-
1
]
===
'*'
;
if
(
$wa
xor
$wb
)
{
return
$wa
?
1
:
-
1
;
}
else
{
return
$a
[
2
]
>
$b
[
2
]
?
1
:
-
1
;
return
$a
[
0
]
>
$b
[
0
]
?
1
:
-
1
;
}
}
});
$result
=
[];
foreach
(
$accepts
as
$accept
)
{
$result
[]
=
$accept
[
0
];
$name
=
$accept
[
'q'
][
1
];
$accept
[
'q'
]
=
$accept
[
'q'
][
2
];
$result
[
$name
]
=
$accept
;
}
return
array_unique
(
$result
);
return
$result
;
}
/**
...
...
tests/unit/framework/web/RequestTest.php
0 → 100644
View file @
ad06b80e
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yiiunit\framework\web
;
use
yii\web\Request
;
use
yiiunit\TestCase
;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
RequestTest
extends
TestCase
{
public
function
testParseAcceptHeader
()
{
$request
=
new
Request
;
$this
->
assertEquals
([],
$request
->
parseAcceptHeader
(
' '
));
$this
->
assertEquals
([
'audio/basic'
=>
[
'q'
=>
1
],
'audio/*'
=>
[
'q'
=>
0.2
],
],
$request
->
parseAcceptHeader
(
'audio/*; q=0.2, audio/basic'
));
$this
->
assertEquals
([
'application/json'
=>
[
'q'
=>
1
,
'version'
=>
'1.0'
],
'application/xml'
=>
[
'q'
=>
1
,
'version'
=>
'2.0'
,
'x'
],
'text/x-c'
=>
[
'q'
=>
1
],
'text/x-dvi'
=>
[
'q'
=>
0.8
],
'text/plain'
=>
[
'q'
=>
0.5
],
],
$request
->
parseAcceptHeader
(
'text/plain; q=0.5,
application/json; version=1.0,
application/xml; version=2.0; x,
text/x-dvi; q=0.8, text/x-c'
));
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment