Could anyone tell me why I am not retrieving info from a form I have submited within a wordpress template? The variables are being passed but they have no values?!?
New answer to an age-old question!
I came across this post, which didn't help, and wrote my own utility (happily shared and feel free to improve)
/* Get Parameters from $_POST and $_GET (WordPress)
$param = string name of specific parameter requested (default to null, get all parameters
$null_return = what you want returned if the parameter is not set (null, false, array() etc
returns $params (string or array depending upon $param) of either parameter value or all parameters by key and value
Note: POST overrules GET (if both are set with a value and GET overrules POST if POST is not set or has a non-truthful value
All parameters are trimmed and sql escaped
*/
function wordpress_get_params($param = null,$null_return = null){
if ($param){
$value = (!empty($_POST[$param]) ? trim(esc_sql($_POST[$param])) : (!empty($_GET[$param]) ? trim(esc_sql($_GET[$param])) : $null_return ));
return $value;
} else {
$params = array();
foreach ($_POST as $key => $param) {
$params[trim(esc_sql($key))] = (!empty($_POST[$key]) ? trim(esc_sql($_POST[$key])) : $null_return );
}
foreach ($_GET as $key => $param) {
$key = trim(esc_sql($key));
if (!isset($params[$key])) { // if there is no key or it's a null value
$params[trim(esc_sql($key))] = (!empty($_GET[$key]) ? trim(esc_sql($_GET[$key])) : $null_return );
}
}
return $params;
}
}
Just came up against the same/similar issue; it is not ideal to use get variables on Wordpress as the URL is structured using mod_rewrite and has some reserved query parameters. The Wordpress Docs on query vars gives you a bit of a list, but it is not comprehensive.
In summary, the variables you were using may have been one of those reserved or modified or handled by Wordpress?
(I know this is an old question but it needs an answer or clarification.)
Please check form method
<form name="frmlist" method="post">
Try with this
print var_dump($_GET);
print var_dump($_POST);
Related
Hi so I want to know the easiest way to check if multiple POST parameters are set. Instead of doing a long if check with multiple "isset($_POST['example'])" linked together by "&&", I wanted to know if there was a cleaner way of doing it.
What I ended up doing was making an array and looping over it:
$params_needed = ["song_name", "artist_name", "song_release_date",
"song_genre", "song_medium"];
I would then call the function below, passing in $params_needed to check if the parameter names above are set:
function all_params_valid($params_needed) {
foreach ($params_needed as $param) {
if (!isset($_POST[$param])) {
error("Missing the " . $param . " variable in POST request.");
return false;
}
}
return true;
}
if (all_params_valid($params_needed)) {
$song_name = $_POST["song_name"];
$artist_name = $_POST["artist_name"];
$song_release_date = $_POST["song_release_date"];
$song_genre = $_POST["song_genre"];
$song_medium = $_POST["song_medium"];
...
}
However when I do this, it gets stuck on the first index and says "Missing the song_name variable..." despite actually including it in the POST request, and I'm not sure why this is happening. The expected behavior would be for it to move on and tell me the next parameter "artist_name" is not set, but this doesn't happen.
I personally like using array_diff for this issue.
PHP array_diff documentation
What you care about is your expected input is the same as the given input.
So you can use array_diff like this:
$params_needed = ["song_name", "artist_name", "song_release_date",
"song_genre", "song_medium"];
$given_params = array_keys($_POST);
$missing_params = array_diff($params_needed, $given_params);
if(!empty($missing_params)) {
// uh oh, someone didn't complete the form completely...
}
How I approach this is by using array_map() so I can return all the values in the array whilst checking if it isset()
PHP 5.6 >
$args = array_map(function($key) {
return isset($_POST[$key]) ? array($key => $_POST[$key]) : someErrorMethod($key);
}, ["song_name", "artist_name", "song_release_date", "song_genre", "song_medium"]);
PHP 7+
$args = array_map(function($key) {
return array($key => $_POST[$key] ?? someErrorMethod($key));
}, ["song_name", "artist_name", "song_release_date", "song_genre", "song_medium"]);
Your error method could look something like this:
function someErrorMethod($key) { die("$key cannot be empty."); }
Inside of your $args variable, you will have an array of key => value. For example,
echo $args['song_name'];
I have some legacy code which I want to update. In that version of the code ( which was a backend for jqGrid ), the search parameters where sent to the server in the POST variables. The POST key is the field name, and the value is the search value. Starting a few years ago I started only accessing POST variables via the filter_input function, which was suggested by my IDE. However I haven't found a recommended way to loop through the POST variables without accessing the POST variable directly.
The portion of the legacy code for search parameters is like this:
/*
* Search Filter
*/
if ($search){
$where_string = ' where ';
foreach ($_POST as $key => $value){
if (in_array($key,array('_search','nd','rows','page','sidx','sord','arg1','arg2'))==true){
continue;
}
//put in functionality to search for exact values
//to search for exact values, include a * character before the value you are searching for
if (strpos($value, "*") === 0){
//exact search
$value = substr($value,1);
}else{
//like search
$value = "%".$value."%";
}
$key = $mysqli->real_escape_string($key);
$value = $mysqli->real_escape_string($value);
$where_string .= '`'.$key.'` like "'.$value.'" AND ';
}
$where_string = rtrim($where_string,' AND ');
}
The warning that my IDE gives is: Do not Access Superglobal $_POST Array Directly.
on the foreach line. Just not sure if I am supposed to avoid this kind of loop completely, or if there is a way to use filter_input with that. It is kind of a generic code for any table. Thanks for the guidance.
First, I'm still fairly new to PHP, so please forgive my lack of understanding. I'm working on a form that takes in options from multiple selects, and provides the user results based on these options. This form also stores these search queries so that they can be exported later on.
Initially, the form only had four parameters needing to be stored, but now I've added a fifth which is making things not so cooperative. I've searched, and tried multiple different things but I've hit a wall and am seeking assistance.
What is intended to happen is the user selects one, or all, of the available options. The first four selects are simple Yes/No questions with values of 1 for Yes, 0 for No. The fifth is a series of county names with the values being set to their id in the database. The county select options are populated dynamically via Smarty.
Here's the PHP used to store these values.
public function recordFilter($args)
{
$db = DBManager::getConnection();
$_POST['type'] = 'f'; // type of search, find providers
foreach($args as $key => $a)
{
if(isset($_GET['county']) && is_numeric($_GET['county'])
{
$_POST[$key] = $a ? (int)$_GET['county'] : 0; // store value of last parameter, or 0 if not set
}
$_POST[$key] = $a ? "y" : "n"; // store 'y' if $a is set, 'n' if not
var_dump($_POST[$key]);
}
parent::save();
}
Currently what is happening is I'm able to get all the values into this function, and iterate through them. But since I've introduced this fifth field (and through the different approaches I've tried to piece this together) is either my fifth parameter gets set to 'y', which won't store in the database as it's field is an int(2), or the set values of the first four parameters take on the value of the fifth parameter, and wind up having the id associated with the county in their fields.
What I'm looking to learn is what better approach is there to handle this type of problem? I thought perhaps a while loop would be appropriate to iterate through the first four parameters and handle the fifth after those are complete, but figuring out the syntax for that is a bit beyond me. I also tried a switch statement but that simply didn't work. Having the if statement seems to be the big wrench in the situation, as it throws the whole loop off if 'county' is set. Any assistance will be greatly appreciated.
Since writing code doesn't look properly on comment, I post my guess here. If you describe more of your code, such as what $args is, or how you handle the request, it'll help people to understand your problem.
Treat the last request separately
Since it's a $_GET request, you can't iterate it with $_POST
foreach ($args as $key => $a) {
$_POST[$key] = $a ? "y" : "n"; // store 'y' if $a is set, 'n' if not
}
if (isset($_GET['county']) && is_numeric($_GET['county']) {
$_POST['county'] = $a ? (int)$_GET['county'] : 0; // store value of last parameter, or 0 if not set
}
And the second, I think this is better approach
Don't rely on super global variable
Assign them to another variable and don't forget to refactor the code on parent::save() method
public function recordFilter($args)
{
$db = DBManager::getConnection();
$request = [];
foreach ($args as $key => $a) {
//Sounds like you forgot to check if the $_POST[$key] is set
$request[$key] = isset($_POST[$key], $a) ? "y" : "n";
}
//You don't have to assign a value to super global $_POST with key of type
$request['type'] = 'f';
//Or you may need if statement if this field doesn't a required field
$request['county'] = (int) $_GET['county'];
parent::save($request);
}
And somewhere in your parent class
protected function save(array $request)
{
//this is your bussiness
}
Since I'm just guessing on what $args is, this is better than the better one
Assign it to local variable with filter_input() and filter_input_array()
public function recordFilter($args)
{
$db = DBManager::getConnection();
//This array will be used for validating the input $_POST.
//First, I grab the key of $args then assign the value
//to $validate with the same key to return it as bool
$validate = [];
foreach(array_keys($args) as $key) {
$validate[$key] = FILTER_VALIDATE_BOOLEAN;
}
//Get the post request value
$request = filter_input_array(INPUT_POST, $validate);
//You don't have to assign a value to super global $_POST with key of type
$request['type'] = 'f';
//Receive 'county' only if it's int and greater than 1 and lower than 99
$options = ['options' => ['min_range' => 1, 'max_range' => 99]];
$request['county'] = filter_input(INPUT_GET, 'county', FILTER_VALIDATE_INT, $options);
parent::save($request);
}
Again, the parent::save() method needs to be refactored.
<?php
module_load_include('inc', 'node', 'node.pages');
$node_form = node_add('post');
print drupal_render($node_form);
?>
This is my code snippet.
The problem is, that I want to pass several parameters for pre-selected default values:
/node/add/post?field_type=3&field_post_id=122
Like the example above.
How can I add parameters (such as "field_type=3" & "field_post_id=122") to my PHP code example above?
Don't use node_add here, there are several ways to do that (as usual):
Have a look at the prepopulate module
If the module does not fit, alter the node form by using hook_form_FORMID_alter as described in the API.
If you don't like McGo's answer (which is good) for some reason, here's an example of how to do that:
$node_form = node_add('post');
foreach ($_GET as $key => $value) {
// this query string is a field prepop.
if (strpos($key, 'field_') === 0) { // === to prevent a false negative.
// this field exists on the form
if (!empty($node_form[$key])) {
$node_form[$key]['#default_value'] = $value;
}
}
}
While untested, something like this should work.
I'm building a small abstract class that's supposed to make certain tasks easier.
For example:
$var = class::get('id');
would run check if there's pointer id in the $_GET, returning a string or array according to parameters. This should also work for post and request and maby more.
I'm doing it in the way there's function for all the superglobals. I'm using get as example:
get function gets a pointer as parameter, it calls fetchdata function and uses the pointer and "$_GET" as the parameters.
fetchdata is supposed to just blindly use the string it got as superglobal and point to it with the other param. Then check if it exists there and return either the value or false to get function, that returns the value/false to caller.
Only problem is to get the string work as superglobal when you don't know what it is. I did this before with a switch that checked the param and in case it was "get", it set $_GET to value of another variable. However I don't want to do it like that, I want it to be easy to add more functions without having to touch the fetchdata.
I tried $method = eval($method), but it didn't work. ($method = "$_GET"), any suggestions?
EDIT: Sorry if I didn't put it clear enough. I have a variable X with string value "$_GET", how can I make it so X gets values from the source described in the string?
So simply it's
$X = $_GET if X has value "$_GET"
$X = $_POST if X has value "$_POST"
I just don't know what value X has, but it needs to get data from superglobal with the same name than its value.
According to this page in the manual:
Note: Variable variables
Superglobals cannot be used as variable variables inside functions or class methods.
This means you can't do this inside a function or method (which you would be able to do with other variables) :
$var = '_GET';
${$var}[$key]
Instead of passing a string to fetchdata(), could you not pass $_GET itself? I think PHP will not copy a variable unless you modify it ('copy on write'), so this shouldn't use memory unnecessarily.
Otherwise there are only nine superglobals, so a switch-case as you have suggested isn't unreasonable.
You could do this with eval() if you really had to, something like:
eval('return $_GET;');
I think that would be unnecessary and a bad idea though; it is slow and you need to be extremely careful about letting untrusted strings anywhere near it.
Don't use eval. Just use reference.
//test value for cli
$_GET['test'] = 'test';
/**
* #link http://php.net/manual/en/filter.constants.php reuse the filter constants
*/
function superglobalValue($key, $input = null) {
if ($input === INPUT_POST)
$X = &$_POST;
else
$X = &$_GET;
return (isset($X[$key]) ? $X[$key] : false);
}
function getArrayValue(&$array, $key) {
return (array_key_exists($key, $array) ? $array[$key] : false);
}
//test dump
var_dump(
superglobalValue('test', INPUT_GET),
superglobalValue('test', INPUT_POST),
getArrayValue($_GET, 'test'),
getArrayValue($_POST, 'test')
);
$_GET, $_POST and $_REQUEST dont have any null values by default, only string or array. So I used isset there instead of array_key_exists.
Param order: I always put required params before optional when I can, and the data objects before the manipulation/subjective params. Thats why key is first param for superglobalValue and second param for getArrayValue.
I'm not quite sure what you're trying to achieve, but you could have a look at the __callStatic magic method
class example{
protected static $supers = array('GET', 'POST', 'SERVER', 'COOKIE');
public static function __callStatic($functionName, $arguments){
$index = arguments[0];
$desiredSuper = strtoupper($functionName);
if(in_array($desiredSuper, self::$supers)){
doStuff ( $_{$desiredSuper}[$index] );
}
else{
throw new Exception("$desiredSupper is not an allowed superGlobal");
}
}
}
you could then do:
example::get('id'); //wo do stuff to $_GET['id']
example::server('REQUEST_METHOD'); //Will do stuff to $_SERVER['REQUEST_METHOD']
example::foo('bar'); //throws Exception: 'FOO is not an allowed superGlobal'
Php manual on magic methods: http://ca.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods
Edit
I just noticed your edit, you could try:
$X = {$X};
You can use $_REQUEST["var"] instead of $_GET["var"] or $_POST["var"].
A more complicated way would be to test if the variable exists in the GET array, if it doesnt then its POST. If it does its GET.
$var = null;
if (isset($_GET["varname"]))
{
$var = $_GET["varname"];
}
else
{
$var = $_POST["varname"];
}
If you want a variable to be accessible globally, you can add it tot he $GLOBALS array.
$GLOBALS['test']='test';
Now you can fetch $GLOBALS['test'] anywhere.