Checking if the referer is empty or if it is in an array
I am trying to write an if statement that basically checks if the users referrer is in a list of allowed referrers and if not fails.
I have two variables controlling this $this->allowAllReferer
and $this->allowEmptyReferer
, which as per their name decide whether every referrer should be allowed access and whether empty referrers are allowed, respectively. As well as $this->allowedReferers
which is an array of allowed referrers.
I have this function below which I am pretty sure isn't working properly but I have been staring at and tweaking it for half an hour and i've got to the point where I can't tell if it's working or not.
//If the referee is empty and allow empty referrer is false
//or
//If it is not in the allowed list and allow all referer is false
if(!(empty($_SERVER['HTTP_REFERER']) && $this->allowEmptyReferer)
&&
!(!$this->allowAllReferer && in_array(
strtolower(empty($_SERVER['HTTP_REFERER']) ? null : $_SERVER['HTTP_REFERER']), //Silly php access null variable
$this->allowedReferers)
)) {
throw new sfException("Internal server error. Please contact system administrator. File download disabled.");
开发者_JAVA技巧}
Do you know the correct or a better way to do this/can you confirm the above works?
Cases, hope this makes it more clear
empty_referrer | allowEmpty | in_array | allReferer | result
----------------------------------------------------------------
true | true | false | false | false - no error - empty allowed
false | true | false | false | true - error - not in array
false | true | false | true | false - no error - not in array but allowed
false | false | false | false | true - error - empty and now allowed
If you would like to keep the logic within one huge if block, then try the following:
if (
// throw an error if it's empty and it's not allowed to be
(empty($_SERVER['HTTP_REFERER']) && !$this->allowEmptyReferer)
|| (
// don't bother throwing an error if all are allowed or empty is allowed
(!empty($_SERVER['HTTP_REFERER']) && !$this->allowAllReferer)
// throw an error if it's not in the array
&& !in_array((empty($_SERVER['HTTP_REFERER']) ? null : strtolower($_SERVER['HTTP_REFERER'])), $this->allowedReferers)
)
)
{
throw new sfException("Internal server error. Please contact system administrator. File download disabled.");
}
The second check for empty will now skip the in_array if it's empty.
How about this:
$ref = &$_SERVER['HTTP_REFERER'];
if($allowAll) {
// allowed
} else if($allowEmpty && empty($ref)) {
// allowed
} else if(!empty($ref) && in_array($ref, $allowedReferers)) {
// allowed
} else {
// fail
}
If you want to have all checks in a single if
, you can simply chain together the conditions using or
/||
. Short-circuit evaluation ensures proper variable values and immediate termination of the condition check:
$ref = &$_SERVER['HTTP_REFERER'];
if($allowAll
|| ($allowEmpty && empty($ref))
|| (!empty($ref) && in_array($ref, $allowedReferers))) {
// allowed
} else {
// fail
}
If I've understood your requirements correctly, then this is most in keeping with your original code
if( (!$this->allowEmptyReferer && empty($_SERVER['HTTP_REFERER'])
|| (!$this->allowAllReferer && !in_array(
strtolower(empty($_SERVER['HTTP_REFERER']) ? null : $_SERVER['HTTP_REFERER']),
$this->allowedReferers)
) { // throw your exception }
I would simplify your logic, something like this:
if (!$this->allowAllReferer)
{
if (empty($_SERVER['HTTP_REFERER']) && !$this->allowEmptyReferer)
{
// emtpy referer - not allowed. handle as you wish (throw exception?)
}
else if (!empty($_SERVER['HTTP_REFERER']) &&
!in_array(strtolower($_SERVER['HTTP_REFERER'])), $this->allowedReferers)
{
// referer supplied is not approved/allowed. - handle appropriately.
}
else
{
// referer should be ok if we get here.
}
}
ie. First of all if you are allowing all referers, then you don't need to do any processing - just skip this (if (!this->allowAllReferer)
).
Second, break up your logic checks into management chunks it makes it easier to write, read and maintain.
if(isset($_SERVER['HTTP_REFERER'])) {
echo $_SERVER['HTTP_REFERER'];
}
精彩评论