PHP: pregmatch input field - php

I have a html form with text input field. I'm wondering how to recognize specific input from the form. Example input commands:
<input type="text" name="action" value="bookmark http://google.com" />
<?php
if ($command == "goto"):
// go to website X
elseif ($command == "bookmark"):
// bookmark website X
else:
// something else
endif;
?>

I think the easiest way is to split the string on the first space to separate it into a command and the parameter for that command. The "2" parameter to explode() allows spaces to be used in $param, if necessary.
$input = explode(' ', $_POST['action'], 2);
$command = $input[0];
$param = $input[1];
switch ($command) {
case 'goto':
// go to website $param
break;
case 'bookmark':
// bookmark website $param
break;
default:
// unknown command
}

$aAct = explode(' ', $_POST['action');
if(is_array($aAct)) {
switch($aAct[0]) {
case 'bookmark':
/* do action e.g. header('Location: ' . $aAct[1]); */
break;
}
}
Make a case/break combination for every action you intend to specify..

Something like this?:
//get the command from your value
$command = current(explode(" ", $_POST['action']));
//get the url from your value
$url = next(explode(" ", $_POST['action']));
And as stated by karim79, a switch to handle the input would more appropriate.
switch($command) {
case 'goto':
// do stuff with $url;
break;
case 'bookmark':
// do stuff with $url;
break;
default: // do something default;
}
hope it helps

Try this:
$request = $_POST['action'];
$split = explode(' ',$request,2);
$command = $split[0];
if(!isset($split[1])){
//no url
die;
}
$url = $split[1];
if($command == "goto"){
header('location: '.$url);
die;
}elseif($command == "bookmark"){
header('location: '.$url);
die;
}else{
echo 'No Commands :(';
}
Use $_POST or $_GET to retrive the request data. ie: $_GET['action']
Set the header location to redirect the browser. die; or exit; is used to terminate and output the current script

Related

how to secure $_GET

I'm trying to secure my $_GET inputs everything are working the problem is $_GET['action'] can't pass preg_match() and always resulta in:
"action is not valid"
I don't know why it's happening, the action can have only two values like or hate which both are in lowercase but still can't pass it.
if(isset($_GET['username']) && isset($_GET['action']))
{
$username = $_GET['username'];
$action = $_GET['action'];
$user_filter_a = mysqli_real_escape_string($username);
$user_filter_b = mysqli_real_escape_string($user_filter_a);
$user_filter_c = strip_tags($user_filter_b);
$action_filter_a = mysqli_real_escape_string($action);
$action_filter_b = mysqli_real_escape_string($action_filter_a);
$action_filter_c = strip_tags($action_filter_b);
$action_filter_c_lower = strip_tags($action_filter_b);
if(preg_match('%^[a-z0-9\.]{4,69}$%',$user_filter_c))
{
if(preg_match('%^[a-z]$%',$action_filter_c_lower))
{
if($action_filter_c_lower=='like')
{
echo 'you have liked this post';
}elseif(action_filter_c_lower=='hate')
{
echo 'you have hated this post';
}
}else
{
echo 'action is not valid';
}
}else
{
echo 'username is not valid';
}
When you need to validate that a string is completely comprised of letters, you can use ctype_alpha().
Code: (Demo)
$string = 'asdgadsfg';
if (ctype_alpha($string)) {
echo "all alphabetical";
} else {
echo "not entirely alphabetical";
}
Output:
all alphabetical
If you need to check if a submitted value is like, hate, or [something else]; create a "whitelist" array to look up the value.
Code: (Demo)
$string = 'like';
$whitelist = ['like', 'hate'];
if (in_array($string, $whitelist)) {
echo "valid: $string";
} else {
echo "invalid: $string";
}
Output:
valid: like
Additional tips:
if(isset($_GET['username']) && isset($_GET['action']))
can be written more simply as:
if (isset($_GET['username'], $_GET['action'])) {
You shouldn't be performing escaping until just before applying the data to the query, this way you don't accidentally mangle your data or confuse yourself. Honest, I always use prepared statements to build a query with user-submitted data, so I'll recommend that you research that topic.
In your regular expression, you don't need to escape a dot inside of a character class so the character class can look like this: [a-z0-9.] If you also wish to allow capital letters, you can add i after the end pattern delimiter (%) so that it looks like %^[a-z0-9.]{4,69}$%i or %^[a-z\d.]{4,69}$%i.
_lower is a strange thing to append to your variable name, because you aren't calling any functions that force the string to lowercase.
The total number of actions is limited. It is more secure to not use the user input at all. Instead, use a switch statement with a default action:
$userAction = strtolower($_GET['action']);
switch($userAction) {
case "like":
$action = "like";
break;
case "hate":
$action = "hate";
break;
default:
$action = "default-action";
}
Or, you can have the list of valid actions in an array:
$validAction = ["like","hate","other"];
$action = "";
if (in_array($_GET["action"],$validAction)){
$action = $_GET["action"];
}
Here you have the guarantee that the action is valid.

Detect if URL equals to value and preforme action

I want to make action if the current url only equals to this: https://www.example.co.il/index.php?id=1000&2222
$url = 'https://www.example.co.il/index.php?id=1000';
if(strpos($url,'&2222'))
{
// Do something
echo "2222";
}
else
{
// Do Nothing
}
To exactly do what you are asked, try this
//actual link (http or https)
$actualUrl = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$url = 'https://www.example.co.il/index.php?id=1000';
if($actualUrl === $url) {
//do something
}
But if you just want to retrieve the id :
$id = $_GET('id');
//return 1000 in your case
You're able to read the parameters in the URL using the $_GET object. It lists the keys and values in the querystring, i.e. in your example,
https://www.example.co.il/index.php?id=1000
if you use:
print $_GET['id'];
you'll see 100.
so you could simply check for the existence of the key 2222:
if (isset($_GET['2222'])) { /** do something **/ }
bear in mind, this is only the case if you're actually reading a URL the script is running on.
your method of searching for a string within the URL is appropriate if you simply want to match a value in a string, whether its a URL or not.
USE THIS
// Assign your parameters here for restricted access
$valid_url = new stdClass();
$valid_url->scheme = 'https';
$valid_url->host = 'www.example.co.il';
$valid_url->ids = array(1000,2222);
$url = 'https://www.example.co.il/index.php?id=1000&2222';
$urlinfo = parse_url($url); // pass url here
$ids = [];
parse_str(str_replace('&', '&id1=', $urlinfo['query']), $ids);
if($urlinfo['scheme'] == $valid_url->scheme && $urlinfo['host'] == $valid_url->host && count(array_intersect($valid_url->ids, $ids)) == count($valid_url->ids)){
echo 'valid';
// Do something
}else{
echo 'in valid';
// error page
}

switch-case with preg_match (+ starts with / strpos)

I wanna accomplish something like this:
!say some message
which then is taken to a function, which proceeds with the content. As you can imagine, I'm listening on some text-inputs. Right now I'm facing the problem, that strings like this also trigger the case:
this is !say some text
Code:
$prefix = "!";
switch ($message->content) {
case preg_match("/[^.*]$prefix . 'say' (.*) /", $message->content):
_say($message);
break;
}
function _say($message)
{
$parts = explode("!say", $message->content);
return $message->channel->sendMessage(trim($parts[1]), true);
}
From my understanding, the regexp is correct (also confirmed on a regexp-tester).
Tested with substr as well, but that doesn't do it either.
case substr($message->content, 0, 3) == $prefix . 'say' :
What am I doing wrong?
A command is a command, it should not be something to be fooled around with. So instead of using regex I suggest a simple string comparison:
$prefix = "!";
function _say($message){
return $message->channel->sendMessage(trim($message), true);
}
if($message->content[0] == $prefix){
if($p = strpos($message->content, ' ') !== false){
$cmd = substr($message->content, 1, $p);
switch($cmd){
case 'say':
_say(substr($message->content, $p));
break;
default:
die('unknown command');
}
} else {
die('empty cmd');
}
} else {
die('no command');
}

Geo redirect user just once using php

i can use this script easily when users land on site.com/redirect.php
they get redirected to appropriate TLD according to geo IP
but when i add this code in 'index.php' it creates a redirect loop.
Can you help me modify it so that it doesn't create loop. right now this 'break' is not helping..
<?php
// Next two lines are for Beyond Hosting
// Don't forget to change your-domain
require_once '/home/your-domain/php/Net/GeoIP.php';
$geoip = Net_GeoIP::getInstance('/home/your-domain/php/Net/GeoIP.dat');
// Next two lines are for HostGator
require_once 'Net/GeoIP.php';
$geoip = Net_GeoIP::getInstance('GeoIP.dat');
try {
$country = $geoip->lookupCountryCode($_SERVER['REMOTE_ADDR']);
switch((string)$country) {
case 'AU':
$url = "http://www.site.au";
break;
case 'CA':
$url = "http://www.site.ca";
break;
default:
$url = "http://site.com";
}
header('Location: '.$url);
} catch (Exception $e) {
// Handle exception
}
?>
You should check if the user is visiting the site via the localised URL before forwarding:
<?php
// Next two lines are for Beyond Hosting
// Don't forget to change your-domain
require_once '/home/your-domain/php/Net/GeoIP.php';
$geoip = Net_GeoIP::getInstance('/home/your-domain/php/Net/GeoIP.dat');
// Next two lines are for HostGator
require_once 'Net/GeoIP.php';
$geoip = Net_GeoIP::getInstance('GeoIP.dat');
try {
$country = $geoip->lookupCountryCode($_SERVER['REMOTE_ADDR']);
switch((string)$country) {
case 'AU':
$url = "http://www.site.au";
break;
case 'CA':
$url = "http://www.site.ca";
break;
default:
$url = "http://site.com";
}
if (strpos("http://$_SERVER[HTTP_HOST]", $url) === false)
{
header('Location: '.$url);
}
} catch (Exception $e) {
// Handle exception
}
?>
use this
header("Location:".$url);
can you do something like: (WARNING, i haven't tested this code, but the logic should be like this)
//Inside your try:
$country = $geoip->lookupCountryCode($_SERVER['REMOTE_ADDR']);
$serverName = explode('.', $_SERVER['SERVER_NAME']);
$serverCountryCode = $serverName[count($serverName)-1];
if (strtoupper ($serverCountryCode) != $country)) {
$shouldRedirect = true;
switch((string)$country) {
case 'AU':
$url = "http://www.site.au";
break;
case 'CA':
$url = "http://www.site.ca";
break;
default:
if ($serverCountryCode == 'com') {
$shouldRedirect = false;
}
$url = "http://site.com";
}
if ($shouldRedirect) {
header('Location: '.$url);
}
}

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
}

Categories