php if $_GET equals a certain array - php

I'm trying to use the break concept, but I am also am using some built in PHP functions to only allow certain values into the get function.
$allowedKeys = array(
'route'
);
$options = array(
'chapter_1' => 'chapter_1',
'chapter_2' => 'chapter_2',
'chapter_3' => 'chapter_3'
);
$_GET = array_intersect_key($_GET, array_flip($allowedKeys));
if($_GET[$allowedKeys[0]] && array_key_exists($_GET[$allowedKeys[0]], $options)) {
if($_GET[$allowedKeys[0]] == $options[0]) {
/* This is where I'm trying to see if route=chapter_1 then do something.
The logic I'm trying to write is if the route is chapter_1 then print
out the content from chapter 1 How can determine this? */
echo "Hello";
}
}
Why isn't this code echoing "hello"?

Why make it more complex than it needs to be?
//check you have a route
$route = isset( $_GET['route'] ) ? $_GET['route'] : '';
switch( $route ) {
case 'chapter_1':
//do chapter one stuff
echo 'Chapter 1';
break;
case 'chapter_2':
//do chapter two stuff
echo 'Chapter 2';
break;
default:
echo 'Intro';
}

I'll answer your question directly for you. 'Hello' isn't showing because it is inside an if statement that isn't being triggered because either "if($_GET[$allowedKeys[0]] && array_key_exists($_GET[$allowedKeys[0]], $options))" or "if($_GET[$allowedKeys[0]] == $options[0])" is returning false.

Related

How can I add this dynamically constructed URL to a PHP variable?

I have a feeling I'm being very silly, but go easy on me as I'm very new to PHP.
So as part of an application, I'm building, I allow users to generate a URL that can be used to access some of their data from outside the platform. The URL is constructed by the PHP script based on URL parameters in the users browser (fear not, the parameters only allow the passing of integers to prevent abuse).
So to create the URL that will be shared, the script does this:
https://example.com/shared.php?function=form&account=<?php echo $userid; ?>&form=<?php echo $myform; ?><?php if (isset($_GET['ref'])) { echo '&ref='.$ref; } ?><?php if (isset($_GET['upload'])) { echo '&upload='.$upload; } ?>&key=<?php echo $key; ?><?php if (isset($_GET['saving'])) { echo '&saving='.$_GET['saving']; } ?><?php if (isset($_GET['expdate'])) { echo '&expdate='.$expdate; } ?><?php if (isset($_GET['enc'])) { echo '&enc='.$enc; } ?>
I know I don't need to keep opening and closing the PHP tag, but it was just easier visually when I was putting everything together.
Anyway, the above does a good job at spitting out the URL, but if I want to add the final URL to a variable, how can I do it?
Obviously, normally it would be trivial:
$whatever = 'https://example.com/shared.php?function=form&account='.$variable.'&something='.$variable2.'etc etc
But because I've got if statements that check for URL parameters, I'm not sure how to accomplish it.
You can concatenate strings with the . operator, you don't need to build the URL at once. However, in this case, it'd be easier to just use the builtin http_build_query() function. Populate an array as you validate parameters and feed it to the function when done.
P.S. Don't trust client-side validations. People may not care to enforce them when they type in the browser location bar.
Big thanks to everyone that made suggestions. In the end I went with the following:
$array = array(
'account' => $userid,
'form' => $myform,
'key' => $key,
);
if (isset($_GET['ref'])) {
$array['ref'] = $ref;
}
if (isset($_GET['upload'])) {
$array['upload'] = $upload;
}
if (isset($_GET['saving'])) {
$array['saving'] = $_GET['saving'];
}
if (isset($_GET['expdate'])) {
$array['expdate'] = $expdate;
}
if (isset($_GET['enc'])) {
$array['enc'] = $enc;
}
$finalURL = http_build_query($array);
Works perfectly.
You can always prepare parameters before putting into string. Or there is ternary operator ?:
$ref = $_GET['ref'] ? '&ref=' . $_GET['ref'] : '';
$upload = $_GET['upload'] ? '&upload=' . $_GET['upload'] : '';
$saving = $_GET['saving'] ? '&saving=' . $_GET['saving'] : '';
$expdate = $_GET['expdate'] ? '&expdate=' . $_GET['expdate'] : '';
$enc = $_GET['enc'] ? '&enc=' . $_GET['enc'] : '';
$whatever = "https://example.com/shared.php?function=form&account={$userid}&form={$myform}{$ref}{$upload}&key={key}{$saving}{$expdate}{$enc}";
Or make it dynamic using http_build_query():
$params = [
'function' => 'form',
'account' => $userid,
'form' => $myform,
'key' => $key,
'ref' => $_GET['ref'] ?? null,
'upload' => $_GET['upload'] ?? null,
...
];
$url = 'https://example.com/shared.php?';
// array_filter will remove any empty value
$url .= http_build_query(array_filter($params));

problem with else if statement not working

I have created a custom WordPress filter. I am importing api data to a form. My first IF statement works (when district not empty). But I can't get the else if working to populate the 2nd field. The 2nd result in the JSON has no value for district. What I am trying to do is separate the results to display House rep in one field and Senators in another. (There are actually two Senate results but I don't now how to separate the results). Each result needs to be in different form fields.
add_filter('frm_pre_create_entry', 'import_fields');
function import_fields($values){
if ( $values['form_id'] == 12 ) {
$zipcode = $values['item_meta'][71];
$api_request = 'http://whoismyrepresentative.com/getall_mems.php?zip='.$zipcode.'&output=json';
$api_response = wp_remote_get( $api_request );
$api_data = json_decode( wp_remote_retrieve_body( $api_response ), true );
foreach ( $api_data["results"] as $member ) {
if ( $member["district"] != '' ) {
$values['item_meta'][72] = $member['name'];
$values['item_meta'][73] = $member['phone'];
$values['item_meta'][74] = $member['office'];
} else if ( $member["district"] == '' ) {
$values['item_meta'][75] = $member['name'];
$values['item_meta'][76] = $member['phone'];
$values['item_meta'][77] = $member['office'];
}
break;
}
}
return $values;
}
I am new here, please go easy on me.
just like #billyonecan said, that break looks weird.
PS: You don't even need to specify the 'else if' condition... simply replace the 'else if' by 'else'
...
} else if ( $member["district"] == '' ) {
...
becomes
...
} else {
...
In your case it won't make any difference, it's just good practices

PHP improve my show message function

I'd like some help please, if its possible.
I have created two functions in order to display some messages when is set a $_GET after a redirect.Here's the code:
function display(){
if(isset($_GET['cnf_upd']) && $_GET['cnf_upd'] == '1'){
$value = "The update was successful!";
$type = "confirm";
construct_the_div($value, $type);
}
if(isset($_GET['err_upd']) && $_GET['err_upd'] == '1'){
$value = "The Update failed.";
$type = "error";
construct_the_div($value, $type);
}
if(isset($_GET['cnf_del']) && $_GET['cnf_del'] == '1'){
$value = "Deleted completely.";
$type = "confirm";
construct_the_div($value, $type);
}
if(isset($_GET['err_del']) && $_GET['err_del'] == '1'){
$value = "Unable to delete.";
$type = "error";
construct_the_div($value, $type);
}
}
function construct_the_div($value, $type){
// creating a div to display the message results
$div = "<div class=\"{$type}Msg\">\n";
$div .= "<p>{$value}</p>\n";
$div .= "</div><!-- end of {$type}Msg -->\n";
echo $div;
}
What I'd like to make is to try to improve the display function, as it gets longer and longer, so that there whould be only one (or two at most) if statement(s) if possible. So the value of the GET will be dynamicly inside the if condition and also if it has the preffix 'cnf_' it wil be a 'confirmMsg' and if it has the preffix 'err_' it wil be a 'errorMsg'.
Is it possible to make something like this???
function display() {
$messages = array(
'cnf_upd' => 'The update was successful!',
'cnf_err' => 'The Update failed.!',
// ...
// add all error and confirm there
// ...
);
foreach($_GET as $key => $value) {
if(strpos($key, 'cnf_')===0) {
$type = 'confirm';
$value = isset($messages[$key])
? $messages[$key]
: $key;
construct_the_div($value, $type);
}
if(strpos($key, 'err_')===0) {
$type = 'error';
$value = isset($messages[$key])
? $messages[$key]
: $key;
construct_the_div($value, $type);
}
}
}
The approach is not correct, it seems that only one message should occur at once (there cannot be "deleted completely" and "unable to delete" at once).
Try construct the parameters this way: ?msg=upd&msgType=cnf
function display(){
if (isset($_GET['msg']) && isset($_GET['msgType']))
{
$messages = array('cnf_upd'=>'The update was successful!',
'err_upd'=>'The update failed!',
'cnf_del'=>'The deletion was successful!',
'cnf_upd'=>'The deletion failed!',
);
if (isset($messages[$_GET['msgType'].'_'.$_GET['msg']))
construct_the_div($messages[$_GET['msgType'].'_'.$_GET['msg']], htmlspecialchars($_GET['msgType']));
}
there is still much to improve, but for start this is cleaner and safer.
I'm going to propose a different solution. Instead of setting different parameters in $_GET based on the message to be sent, set one parameter and parse its value.
// Start by setting integer constants:
define(CNF_UPD, 1);
define(ERR_UPD, 2);
define(CNF_DEL, 3);
define(ERR_DEL, 4);
Then when you set the value un $_GET, use the constant:
// Build the URL with a deletion error...
header("Location: http://example.com/script.php?msg=" . ERR_DEL);
Finally, use a switch to parse them
if (isset($_GET['msg'])) {
switch ($_GET['msg']) {
case CNF_UPD:
// Updated...
break;
case ERR_UPD:
// failed...
break;
// etc...
default:
// invalid code.
}
}
If you use a pattern of confirm/error/confirm/error for your integer constants, you can determine which it is by taking $_GET['msg'] % 2. Odd numbers are confirmations, evens are errors. There are of course many other ways you could lay this out, I just happen to have typed them in the alternating order you used. You could also do positive integers for confirmations and negatives for errors, for example.
$type = $_GET['msg'] % 2 == 1 ? $confirm : $error;
This is easily expanded to use multiple messages as well. Since they are integer values, you can safely construct a comma-separated list and explode() them when received.
$messages = implode(array(ERR_DEL,CNF_UPD));
header("Location: http://example.com/script.php?msg=$messages");
Unless you can somehow generate $value and $type based on the $_GET parameter (which I can't see how you would do), you could do something like:
$messages = array();
$messages[] = array('id' => 'cnf_upd', 'value' => 'The update was successful!', 'type' => 'Confirm');
$messages[] = array('id' => 'err_upd', 'value' => 'The Update failed.', 'type' => 'error');
...
foreach ($messages as $message) {
if(isset($_GET[$message['id']]) && $_GET[$message['id']] == '1'){
construct_the_div($message['value'], $message['type']);
}
}

PHP Function parameters - problem with var not being set

So I am obviously not a very good programmer. I have written this small function:
function dispAdjuggler($atts) {
extract(shortcode_atts(array(
'slot' => ''
), $atts));
$adspot = '';
$adtype = '';
// Get blog # we're on
global $blog_id;
switch ($blog_id) {
case 1:
// root blog HOME page
if (is_home()) {
switch ($slot) {
case 'top_leaderboard':
$adspot = '855525';
$adtype = '608934';
break;
case 'right_halfpage':
$adspot = '855216';
$adtype = '855220';
break;
case 'right_med-rectangle':
$adspot = '858222';
$adtype = '613526';
break;
default:
throw new Exception("Ad slot is not defined");
break;
}
When I reference the function on a page like so:
<?php dispAdjuggler("top_leaderboard"); ?>
The switch is throwing the default exception. What am I doing wrong here?
Thanks!!
Without know what the shortcode_atts() function does, it looks like you're passing in array to set default values ('slot' = empty string), which extract() then converts into $short = ''
extract(shortcode_atts(array(
'slot' => ''
), $atts));
right? Now that $slot is the empty string, it won't match any of the cases in your switch, and therefore the default case gets triggered, which throws the "Ad slot is not defined" exception.
Aren't you missing the extract type parameter?
http://us.php.net/manual/en/function.extract.php

Dynamic include

<?php
// Default page
if (!$_SERVER['QUERY_STRING']) $Page = "news";
// View
elseif (isset($_GET['newsID'])) $Page = "newsView";
elseif (isset($_GET['userID'])) $Page = "profile";
elseif (isset($_GET['messageID'])) $Page = "message";
elseif (isset($_GET['threadID'])) $Page = "thread";
elseif (isset($_GET['forumID'])) $Page = "forum";
elseif (isset($_GET['imgID'])) $Page = "imageView";
// Pages
elseif ($_GET['content'] == "search") $Page = "search";
elseif ($_GET['content'] == "gallery") $Page = "gallery";
elseif ($_GET['content'] == "forums") $Page = "forums";
elseif ($_GET['content'] == "messages") $Page = "messages";
many more...
// If page don't exist
else $Page = "error";
// Output page
include($config['PAGE_PATH'].$Page.'.php');
include($config['TEMPLATE_PATH'].$Page.'.html');
?>
This is some code my friend wrote years ago...
I'm wondering how safe this is and if I could make it a little cleaner?
Thanks.
As it is you who defines what pages are allowed to be included (white list), I cannot see any way to poison the $Page variable. So this seems pretty safe.
But you could clean it up using arrays such as:
$argToPage = array(
'newsID' => 'newsView',
'userID' => 'profile',
'messageID' => 'message',
'threadID' => 'thread',
'forumID' => 'forum',
'imgID' => 'imageView'
);
$contents = array(
'search',
'gallery',
'forums',
'messages'
);
$Page = null;
if (trim($_SERVER['QUERY_STRING']) == '') {
$Page = 'news';
} else {
foreach ($_GET as $key => $val) {
if (isset($argToPage[$key])) {
$Page = $argToPage[$key];
break;
}
}
}
if (is_null($Page) && isset($_GET['content']) && in_array($_GET['content'], $contents)) {
$Page = $contents[$_GET['content']];
} else {
$Page = 'error';
}
But that’s not much cleaner.
Well it's safe in the sense that the code sanitizes the parameter. People often do that (to disastrous results usually).
I'm not a big fan of this pattern however. By that I mean a single controller that includes files passed on a parameter. I much prefer to have a script per page and just include what's needed. Structurally I think it's better.
That being said, there's nothing fundamentally wrong with the above approach.
Just make sure you treat any data that comes from the user with extreme paranoia.
I'd be very cautious about cleaning this up any more than it is. Using a variable provided by user input in an include is a major security flaw. I would leave this as it is.
You could make an array with GET options as key and pages as values.. then use switch() statement. This should make the code cleaner. But as Cletus said, this isn't the best way to make a controller.

Categories