Simplifying PHP if's and arrays - php

I have a piece of code I just wrote that detects if there is a user logged in and if [1] and [2] have any specific text in the string and then will relocate that person to another page if the values are met.
But I think my code is a little long winded. Is there a way to simplify what I have or is this the best I'll get?
if (!isset($_SESSION['user_id'])){
$dir = dirname($_SERVER['PHP_SELF']);
$dirs = explode('/', $dir);
if(isset($dirs[1])){
if (($dirs[1] == "account") || ($dirs[1] == "admin")){
header('Location: /');
}
}
if(isset($dirs[2])){
if(($dirs[2] == "account")){
header('Location: /');
}
}
}
Thanks in advance

a simple way is to use a closure
$dir = explode('/', dirname($_SERVER['PHP_SELF']));
$is = function($pos, $check) use($dir) {
return array_key_exists($pos, $dir) && $dir[$pos] == $check;
};
if($is->__invoke(1, 'account')
|| $is->__invoke(1, 'admin')
|| $is->__invoke(2, 'account')) {
header('Location: /');
}

You could do that for instance:
$dir = dirname($_SERVER['PHP_SELF']);
$dirs = explode('/', $dir);
if(in_array('account',$dirs) || in_array('admin', $dirs)){
header('Location: /');
}

One of a few simpler solutions could be to use PHP's array_intersect($array1, $array2) function. This is well documented on the php.net website, but here's a little example:
// Define all the 'search' needles
$needles = array('account', 'admin');
// Get all the dirs
$dirs = explode('/', dirname( $_SERVER['PHP_SELF'] ));
// Check for needles in the hay
if( array_intersect($needles, $dirs) )
{
// Redirect
header('Location: /');
}
ADDED: You could of course make the above very simple by combining multiple lines into one, this would leave you with:
if( array_intersect(array('account', 'admin'), explode('/', dirname($_SERVER['PHP_SELF']))) )
{
header('Location: /');
}

Related

Combining multiple strpos() in an if () statement

I'm trying to make added user agent stay on a page. If user agent is not detected, then redirect.
This code works
$useragent = $_SERVER['HTTP_USER_AGENT'];
if (strpos($useragent, "useragent") === false) {
header("Location: http://google.com/");
}
So I tried to add multiple user agent like this but didn't work.
$useragent = $_SERVER['HTTP_USER_AGENT'];
if (
strpos($useragent, "agent1") === false ||
strpos($useragent, "agent2") === false ||
strpos($useragent, "agent2") === false
) {
header("Location: http://google.com/");
}
You may want a code that is simpler to update than your successive strpos(). Also, you should search case-insensitively. And firing the PCRE engine at each page access may not be optimal.
So I would keep the stripos() approach like this:
<?php
$partial_allowed_UA_names = ['mozilla', 'chrome', 'safari']; # <----- Config here.
$go_away = true;
foreach ($partial_allowed_UA_names as $v) {
if (stripos($_SERVER['HTTP_USER_AGENT'], $v) !== false) {
$go_away = false;
break;
}
}
if ($go_away) header('Location: https://www.google.com/');
?>
Best regards
You can use preg_match() instead.
$useragent = $_SERVER['HTTP_USER_AGENT'];
$agents = ['agent1', 'agent2', 'agent3']; //array of predefined names of agents
if (!preg_match('/' . implode('|', $agents) . '/i', $useragent)) { //check if current user agent is not enlisted
header("Location: http://google.com/");
}

memory exhausted on line 2860 with (if else)

I've searched in various places for this solution, but have not been able to solve the problem that happened to me. What happens is actually in the following code:
[21-Jul-2017 23:35:30 UTC] PHP Parse error: memory exhausted in
/home/.../public_html/folder/index.php on line 2860
Chronologically, I want to create many options if one of the options is met. Here's the problem code:
<?php
if(isset($_GET['url'])) {
$u = $_GET['url'];
if($u == 'old/page1.html') {
header('Location: /new/page1.htm');
} if($u == 'old/page2.html') {
header('Location: /new/page2.htm');
} if($u == 'old/page3.html') {
header('Location: /new/page3.htm');
} if($u == 'old/page4.html') {
header('Location: /new/page4.htm');
}
//.....
//.....(line 5691)
}
?>
If I only use the above code, then it can run normally. But if I use my code number of 5691 lines, then the warning starts to appear and the site can not be opened.
I suspect there is a problem on the maximum amount of memory used, but do not know exactly.
If you really need to sort it out this way, then this would probably be better:
<?php
if (isset($_GET['url'])) {
$u = $_GET['url'];
$redirects = [
'old/page1.html' => '/new/page1.htm',
// ...
];
if (array_key_exists($u, $redirects)) {
$redirect = $redirects[$u];
header(sprintf(
'Location: %s',
$redirect
));
}
}
This way at least you can manage the redirect mapping separately, without the need to add a bunch of conditions.
You could also put the mapping into a separate file:
<?php
return [
'old/page1.html' => '/new/page1.htm',
// ...
];
and then adjust your script:
<?php
if (isset($_GET['url'])) {
$u = $_GET['url'];
$redirects = require __DIR__ . '/redirects.php';
if (array_key_exists($u, $redirects)) {
$redirect = $redirects[$u];
header(sprintf(
'Location: %s',
$redirect
));
}
}
This way you don't need to modify your script if the mapping changes.
Alternatively, use elseif:
<?php
if (isset($_GET['url'])) {
$u = $_GET['url'];
if ($u == 'old/page1.html') {
header('Location: /new/page1.htm');
} elseif ($u == 'old/page2.html') {
header('Location: /new/page2.htm');
} elseif ($u == 'old/page3.html') {
header('Location: /new/page3.htm');
} elseif ($u == 'old/page4.html') {
header('Location: /new/page4.htm');
}
}
You can replace those 5691 lines of code with this
if(isset($_GET['url'])) {
$u = $_GET['url'];
if(substr($u, 3) === 'old'){
$new = str_replace('old', 'new', $u);
header("Location: $new");
}

Detecting browser language in PHP and redirect

I want to write a simple if statement using HTTP_ACCEPT_LANGUAGE function that redirects based on result of what the users browser language is. I am still a beginner so am obviously keeping it as simple as possible. This is what I have so far but the "if" statement needs work. Can anyone help me with a fix?
<?php
$lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
if ($lang=german) {
header("Location: http://www.example.com/german/index.html");
} else if ($lang=spanish) {
header("Location: http://www.example.com/spanish/index.html");
}
else if ($lang=french) {
header("Location: http://www.example.com/french/index.html");
}
else if ($lang=chinese) {
header("Location: http://www.example.com/chinese /index.html");
} else {
echo "<html>english content</html>";
}
?>
I don't know what your language literals are, so I'd say make them ISO language codes.
Use a switch statement, this is more readable and smaller:
$lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
switch($lang) {
case "de-DE":
case "es-ES":
case "cn-CN":
case "fr-FR":
header("Location: http://www.example.com/$lang/index.html");
break;
default:
header("Location: http://www.example.com/en-US/index.html");
break;
}
Further, you are assigning, not comparing. You compare with ==:
if ($lang == "de-DE")
Assuming you always redirect to /language/, you could do it this way:
<?php
$lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
if ( in_array( $lang,array("german","spanish","french","chinese") ) ) {
header("Location: http://www.example.com/$lang/index.html");
} else {
echo "<html>english content</html>";
}
?>
Also, the comparisons in your if need to be done with ==, it's assignment otherwise!
Try this:
<?php
$path = array(
'en-US' => 'english',
// etc
);
$accepts = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
if (in_array($accepts[0], $path)) { // if path exists for language then redirect to path, else redirect to default path (english)
header('Location: http://www.example.com/' . $path[$accepts[0]] . '/index.html');
} else {
header('Location: http://www.example.com/english/index.html');
}
?>
HTTP_ACCEPT_LANGUAGE returns not "english", but two signs symbol like "en", or region and language symbol like "en_us". You shouldn't use if statement it's hard to read. You should use array (in future you can simple write it to config files, or move to databases).
The proper code should look that:
$default_lang = 'en';
$lang_redirectors = array('de' => 'http://www.example.com/german/index.html',
'en' => 'http://www.example.com/english/index.html');
function redirect($url){
header("Location: " . $url);
}
$hal = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$langs = explode($hal, ',');
foreach($langs as $lang){
$lang_prefix = substr($lang, 0, 2);
if(in_array($lang_prefix, $lang_redirectors)){
redirect($lang_redirectors[$lang_prefix]);
break;
}
redirect($lang_redirectors[$default_lang]);
}
<?php
$browserlang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$lang = $browserlang[0] . $browserlang[1] . $browserlang[2] . $browserlang[3] . $browserlang[4];
if (($lang=="sk_SK") OR ($lang=="sk-SK")) {
header("Location: https://www.example.sk/sk");
}
else if (($lang=="en_EN") OR ($lang=="en-EN") OR ($lang=="en_GB") OR ($lang=="en_US") OR ($lang=="en-GB") OR ($lang=="en-US")) {
header("Location: https://www.example.sk/en");
}
else {
header("Location: https://www.example.sk/en");
}
?>

PHP GET String with explode and if statements

I am writing what I thought would be a simple script but I am stuck.
The scenario is that I want to create 2 strings from the GET request.
eg: domain.com/script.php?Client=A12345
In script.php it needs to grab the "Client" and create 2 variables. One is $brand and needs to grab the A or B from the URL. The Other is $id which needs to grab the 12345 from the URL.
Now, after it has these 2 variables $brand and $id it needs to have an if statement to redirect based on the brand like below
if ($brand=="A") {
header('Location: http://a.com');
}
if ($brand=="B") {
header('Location: http://b.com');
At the end of each URL I want to apend the $id though and I am unsure on how to do this.
So for example I would access the script at domain.com/script?Client=A1234 and it needs to redirect me to a.com/12345
Thanks in advance!
$fullCode = $_REQUEST['Client'];
if(strpos($fullCode, 'A') !== false) {
$exp = explode('A',$fullcode);
header('Location: http://a.com/' . $exp[1]);
}
else if(strpos($fullCode, 'B') !== false) {
$exp = explode('B',$fullcode);
header('Location: http://b.com/' . $exp[1]);
}
else {
die('No letter occurence');
}
You can easily do,
$value = $_GET['Client'];
$brand = substr($value, 0, 1);
$rest = substr($value, 1, strlen($brand)-1);
now you have the first character in $brand string and you can do the if statement and redirect the way you want...
You mean like this?
Notice: this will only work if brand is just 1 character long. If that's not the case, please give better examples.
<?php
$client = $_GET['Client'];
$brand = strtolower(substr($client, 0, 1));
$id = substr($client, 1);
if ($brand == 'a')
{
header("Location: http://a.com/$id");
}
elseif ($brand == 'b')
{
header("Location: http://b.com/$id");
}
?>
Try using:
preg_match("/([A-Z])(\d*)/",$_GET['Client'],$matches);
$matches[1] will contain the letter and $matches[2] will contain your id.
Then you can use:
if ($matches[1]=="A")
{
header('Location: http://a.com/{$matches[2]}');
}
if ($matches[1]=="B")
{
header('Location: http://b.com/{$matches[2]}');
}
suggest you could also try
$requested = $_GET["Client"];
$domain = trim(preg_replace('/[^a-zA-Z]/',' ', $requested)); // replace non-alphabets with space
$brand = trim(preg_replace('/[a-zA-Z]/',' ', $requested)); // replace non-numerics with space
$redirect_url = 'http://' . $domain . '/' . $brand;
header('Location:' . $redirect_url);
but it'd be better if you could get the domain name and brand as two individual parameters and sanitize them individually before redirecting them to prevent the overhead of extracting them from a single parameter.
Note: this expression might be useless when the domain name itself has numerics and because the Client is obtained through get a good deal of validation and sanitation would be required in reality.
$brand = strtolower($_GET['Client'][0]);
$id = substr($_GET['Client'], 1);
header("Location: http://{$brand}.com/{$id}");
If for some purpose you want to use explode, then you need to have a separator.
Let's take '_' as the separator, so your example would be something like this: domain.com/script.php?Client=A_12345
$yourstring = explode("_",$_GET["Client"]);
echo $yourstring[0];
//will output A
echo $yourstring[1];
//will output 12345
//your simple controller could be something like this
switch($yourstring[0]){
case: 'A':
header('Location: http://a.com?id='.$yourstring[1]);
exit();
break;
case: 'B':
header('Location: http://b.com?id='.$yourstring[1]);
exit();
break;
default:
//etc
}

Convert URI to URL

How to convert an URI to URL if I know the current site path?
Consider these examples:
Current path is: `http://www.site.com/aa/folder/page1.php
Uri: folder2/page.php
Uri: /folder2/page.php
And what if the current path is:
`http://www.site.com/aa/folder/
or
`http://www.site.com/aa/folder
What the URLs will look like then?
I know this should be easy and obvious, but I can't find anywhere the complete answer (and yes, I did searched on Google)
Here is a block of code that has the function that you need:
http://ca.php.net/manual/en/function.parse-url.php#76682
Edit: The above linked function modified with an example
<?php
var_dump(resolve_url('http://www.site.com/aa/folder/page1.php','folder2/page.php?x=y&z=a'));
var_dump(resolve_url('http://www.site.com/aa/folder/page1.php','/folder2/page2.php'));
function unparse_url($components) {
return $components['scheme'].'://'.$components['host'].$components['path'];
}
/**
* Resolve a URL relative to a base path. This happens to work with POSIX
* filenames as well. This is based on RFC 2396 section 5.2.
*/
function resolve_url($base, $url) {
if (!strlen($base)) return $url;
// Step 2
if (!strlen($url)) return $base;
// Step 3
if (preg_match('!^[a-z]+:!i', $url)) return $url;
$base = parse_url($base);
if ($url{0} == "#") {
// Step 2 (fragment)
$base['fragment'] = substr($url, 1);
return unparse_url($base);
}
unset($base['fragment']);
unset($base['query']);
if (substr($url, 0, 2) == "//") {
// Step 4
return unparse_url(array(
'scheme'=>$base['scheme'],
'path'=>$url,
));
} else if ($url{0} == "/") {
// Step 5
$base['path'] = $url;
} else {
// Step 6
$path = explode('/', $base['path']);
$url_path = explode('/', $url);
// Step 6a: drop file from base
array_pop($path);
// Step 6b, 6c, 6e: append url while removing "." and ".." from
// the directory portion
$end = array_pop($url_path);
foreach ($url_path as $segment) {
if ($segment == '.') {
// skip
} else if ($segment == '..' && $path && $path[sizeof($path)-1] != '..') {
array_pop($path);
} else {
$path[] = $segment;
}
}
// Step 6d, 6f: remove "." and ".." from file portion
if ($end == '.') {
$path[] = '';
} else if ($end == '..' && $path && $path[sizeof($path)-1] != '..') {
$path[sizeof($path)-1] = '';
} else {
$path[] = $end;
}
// Step 6h
$base['path'] = join('/', $path);
}
// Step 7
return unparse_url($base);
}
?>
The $_SERVER superglobal will have the information you're looking for, namely $_SERVER['REQUEST_URI'] and $_SERVER['SERVER_NAME']. $_SERVER['QUERY_STRING'] might also be useful.
Please see:
http://php.net/manual/en/reserved.variables.server.php
php has pathinfo(), realpath() and parseurl() and other filesystem and url path functions. Used together with info from the $_SERVER superglobal (as mentioned by andre), you should be able to do what you need.
$uri = "http://www.site.com/aa/folder/";
$url = explode("/", $uri);
$url = $url[2];
echo $url; //www.site.com
Is this what you are looking for?
If you install PECL pecl_http, you can make use of http_build_url:
http_build_url("http://www.site.com/aa/folder/page1.php",
array("path" => "folder2/page.php"));
and you pass any of your relative URI(L)s as path. The function will make sure to build the correct one.

Categories