This question already has answers here:
passing POST array to php function
(3 answers)
Closed 9 years ago.
I've been working on a project for a game (so you'll understand that I can't post the actual script), and I'm cleaning up the code and placing code into functions instead of just after the
if ($_POST['name'] { //code }
Is this the correct method of doing what I'm trying? (I tried, but it broke my system)
if ($_POST['action'] == "actionName") actionName($_POST); //calls function if the $_POST is present
function actionName($_POST) { //code }
Thanks in advance for correct answers!
$_POST is globally accessible. So you don't have to pass to your function:
if ($_POST['action'] == 'actionName') actionName();
function actionName() {
//code using $_POST
}
If you want your function to be able to do what it wants with any array (i.e. other than $_POST), then make the function take a parameter, but don't call it $_POST:
if ($_POST['action'] == 'actionName') actionName($_POST);
function actionName(parameters) {
//code using parameters
}
$_POST is a super-global. All PHP code, no matter the scope, automatically has access to this data structure.
Therefore, the following is fine:
if ($_POST['action'] == "actionName") {
actionName();
}
and then
function actionName() {
print_r($_POST);
// code
}
$_POST is already a superglobal variable so you do not need to pass it to a function. If the function needs the content of $_POST then make a copy and pass it to the function.
However, from your example, it seems to me that you need to pass $_POST['action'] to your function instead of $_POST.
Well in your example you need to have quotes around your string variables:
//calls function if the $_POST is present
if ($_POST['action'] == 'actionName') actionName($_POST);
function actionName($_POST) { /*code*/ }
Although $_POST is super-global, yes of course you can do that and is actually a good idea. This way you decouple your code and maybe you can reuse actionName in another part of the application.
However, don't name the parameter of the function $_POST (this is more confusing than helpful).
To avoid a bunch of if statements for every possible action, have a look at call_user_func [docs].
E.g. you could do:
$allowed_actions = array_fill_keys(array('actionName', ...), true);
if(isset($allowed_actions[$_POST['action']])) {
call_user_func($_POST['action'], $_POST);
}
You should move the function before the code that executes it along with what everyone else here is saying about the $_POST array. Try this if you want
function actionName($input) { // code and return }
if (isset($_POST['action'])) {
$action = $_POST['action'];
if ($action == 'actionName') {
$name = actionName($action);
}
}
$_POST is a super global (as other have mentioned), so you don't need to pass it in.
You can pass it in so that you decouple the function code from the environment in which it's running. For example, should you wish to initiate such an action as a result of something else in the code, you can pass in an array with the same key/values that $_POST would have to do so
If you do pass in $_POST to a function, name the function argument something else, hopefully something that indicates what the data represents
Consider that the function may not need all the key/values that $_POST normally contains, and if you might be better off defining a function that takes only the arguments it needs in order to function
If you are talking about dynamically calling a function, you could achieve it this way:
/*
Example Post
$_POST['functionName'] = 'doSomething';
$_POST['value'] = 'woot!';
*/
function doSomething($message) {
echo $message;
}
// Call the function if it exists
if (function_exists($_POST['functionName']) {
call_user_func($_POST['functionName'], $_POST['value']);
}
// The above would output "Woot!"
Related
This question already has answers here:
Are PHP Variables passed by value or by reference?
(16 answers)
How to declare a global variable in php?
(10 answers)
Closed 3 years ago.
I would like to be able to assign the name of a variable outside the function so that the function can assign the chosen variable. It does not seem to work. Anyone have any ideas?
Below is my attempt, however the $admin variable is empty after running the function.
function assign_check($variable, $check) {
if (empty($_POST[$check])) {
$variable = "no";
} else {
$variable = $_POST[$check];
}
}
assign_check('$admin', 'admin');
My question is not about the use of global variables.
You can request a reference in the function body.
function assign_check(&$variable, $check) {
$variable = 'hello';
}
And call passing a variable (reference).
assign_check($admin, 'admin');
$admin value is now 'hello';
Fitting that to your code would result in
function assign_check(&$variable, $check) {
$variable = empty($_POST[$check]) ? "no" : $_POST[$check];
}
assign_check($admin', 'admin');
But returning a proper value would be much cleaner code than using references. Using a ternary operator like presented above would it even simplify without need of a function at all.
A normal way to assign the result of a function to a variable name specified outside the function would be to have the function return the result and assign it directly to the variable when you call the function.
function assign_check($check) {
if (empty($_POST[$check])) {
return "no";
} else {
return $_POST[$check];
}
}
$admin = assign_check('admin');
I would do it this way unless there was a compelling reason to do it otherwise.
For the specific type of thing it looks like this function is intended to do, I would suggest looking at filter_input.
I have an interesting situation. I am using a form that is included on multiple pages (for simplicity and to reduce duplication) and this form in some areas is populated with values from a DB. However, not all of these values will always be present. For instance, I could be doing something to the effect of:
<?php echo set_value('first_name', $first_name); ?>
and this would work fine where the values exist, but $user is not always set, since they may be typing their name in for the first time. Yes you can do isset($first_name) && $first_name inside an if statement (shorthand or regular)
I am trying to write a helper function to check if a variable isset and if it's not null. I would ideally like to do something like varIsset('first_name'), where first_name is an actual variable name $first_name and the function would take in the string, turn it into the intended variable $first_name and check if it's set and not null. If it passes the requirements, then return that variables value (in this case 'test'). If it doesn't pass the requirements, meaining it's not set or is null, then the function would return '{blank}'.
I am using CodeIgniter if that helps, will be switching to Laravel in the somewhat near future. Any help is appreciated. Here is what I've put together so far, but to no avail.
function varIsset($var = '')
{
foreach (get_defined_vars() as $val) {
if ($val == $var) {
if (isset($val) && $val) {
echo $val;
}
break;
}
}
die;
}
Here is an example usage:
<?php
if (varIsset('user_id') == 100) {
// do something
}
?>
I would use arrays and check for array keys myself (or initialize all my variables...), but for your function you could use something like:
function varIsset($var)
{
global $$var;
return isset($$var) && !empty($$var);
}
Check out the manual on variable variables. You need to use global $$var; to get around the scope problem, so it's a bit of a nasty solution. See a working example here.
Edit: If you need the value returned, you could do something like:
function valueVar($var)
{
global $$var;
return (isset($$var) && !empty($$var)) ? $$var : NULL;
}
But to be honest, using variables like that when they might or might not exist seems a bit wrong to me.
It would be a better approach to introduce a context in which you want to search, e.g.:
function varIsset($name, array $context)
{
return !empty($context[$name]);
}
The context is then populated with your database results before rendering takes place. Btw, empty() has a small caveat with the string value "0"; in those cases it might be a better approach to use this logic:
return isset($context[$name]) && strlen($name);
Try:
<?php
function varIsset($string){
global $$string;
return empty($$string) ? 0 : 1;
}
$what = 'good';
echo 'what:'.varIsset('what').'; now:'.varIsset('now');
?>
i want to store function in array
send the array to another page
then execute it
i already read Can you store a function in a PHP array but still don't know what to do
here's what i try
control.php (it start here)
<?php
function getFirstFunction(){ echo "first function executed"; }
$data = array();
$data[0] = getFirstFunction();
$data[1] = function(){ echo "second function executed"; };
$data[2] = function(){ require_once "additional.php"; };
$data[3] = "my string";
header('Location: view.php?data='.$data);
?>
additional.php
<?php echo "additional included" ?>
view.php
<?php
if( isset($_GET['data']) ){
foreach( $_GET['data'] as $temp ){
if( is_callable($temp) ){
$temp;
}else{
"its not a function";
}
}
}
?>
my error =
Warning: Invalid argument supplied for foreach() in D:\Workspace\Web\latihanns\php\get\view.php on line 4
EDIT
thanks for notify that this code its dangerous.i'm not use this code in real live. i just try to learn store function in array then call it. then i just curious how if i call it on another page. i just simply curious... i make my code look clear and simple here because i afraid if i wrote complicated code, no one will be here or my post will closed as too localized...
If you want to pass anything than string into URL, only option is convert it to string form which is reversible to original types. PHP offers function called serialize() which converts anything to string. After that, you can call unserialize() to convert string back to original data. So you have to change one line in control.php to this:
header('Location: view.php?data='.serialize($data));
In file view.php you have to change one line to this:
foreach( unserialize($_GET['data']) as $temp ){
But you have to fix more things than this. If you have callable variable, you can't invoke function with $variable, but with $variable(). It is good to mention, that in PHP does not matter if you have real function (anonymous function, Closure etc.) in variable, or if variable is simple string with name of exists function.
However you have even another bug in control.php. Code $data[0] = getFirstFunction(); will not pass function getFirstFunction an make it callable, it just calls the function and put its return value to variable. You can define getFirstFunction as anonymouse function like function in $data[1] or just pass it as string like $data[0] = 'getFirstFunction' which will work.
At the end - as anyone mentioned here - IT IS VERY DANGEROUS ans you shouldn't use this on public server.
The code below is just a sample of the format I have
isset($_GET['ids'])?$ids=$_GET['ids']:null;
isset($_POST['idc'])?$idc=$_POST['idc']:null;
function ShowCart()
{
$que = "SELECT
FROM
cart
LEFT OUTER JOIN ...
ON ...
LEFT OUTER JOIN... ON...
WHERE ";
$result = mysql_query($que);
while(){
if (isset($ids)) {
display something
for (){
if(){
} // end of if inside the for loop
}// end of for loop
}
elseif($idc && $ids=null) {
display something different
}
else{
display nothing has passed
}
}//end of while loop
}//end of showcart(); function
that's the formatting above I wonder why the if and elseif are not getting the isset() as the if and elseif argument.
I have debug the through the whole code and the print_r of GET and POST has values through the whole code.
print_r($_POST);
print_r($_GET);
Jona, if you'd ever bother to properly format your code, you'd see that the 'else' in question is WITHIN A FUNCTION, and you're defining $ids and $idc OUTSIDE THE FUNCTION. Remember, in PHP, global variables (except the super-globals, such as $_GET, $_POST, etc...) are not visible within functions unless you explicity define them as globals within the function.
Add global $idc, $idc; as the first line in the function definition and your if() will start working correctly.
Followup:
Your code is still hideously formatted, and very wonky. Take this:
isset($_GET['ids'])?$ids=$_GET['ids']:null;
You're using a trinary operator, but not assigning its results anywhere, and using the 'true' condition to do an assignment. This is an ugly hack. It should be written like this:
$ids = isset($_GET['ids']) ? $_GET['ids'] : null;
This way $ids will be set to null if there is no $_GET['ids']. Which brings up the fact that you're assigning a null instead of some other default value. If there really was no $_GET['ids'], then this:
$idx = $_GET['ids'];
would work identically, as PHP will automatically assign a null in situations where the right-hand-side doesn't exist. Of course, you still have to sanitize this value, since you're using it in an SQL query later on. Leaving it like this will just invite SQL injection attacks and all kinds of other abuses.
Beyond that, you're still creating $ids and $idc OUTSIDE of your ShowCart() function. As such, $ids and $idc within the function will be automatically be created with null values, since you've not declared them to be global. I think by now it's obvious you have no idea what this means, so try out this piece of code:
<?php
$var = 'Here I am!';
function showVar() {
echo "Within showVar(), var is set to: $var\n";
}
function workingShowVar() {
global $var;
echo "Within workingShowVar(), var is equal to: $var\n";
}
showVar();
workingShowVar();
If you copy/paste this code, run it, you'll see the following output:
Within showVar(), var is set to:
Within workingShowVar(), var is set to: Here I am!
Notice that both functions are identical, except for the global declaration. If you can figure out the difference, then you'll realize you need to re-write your ShowCart() function as follows:
function ShowCart() {
global $ids, $idc;
// rest of your code here
}
Well the code you've posted is sound, so it's probably a problem with the variables getting to that script in the first place. Are you sure those variables are defined in the GET string?
Dump out the contents of it to make sure:
print_r($_GET);
Try this:
$ids= isset($_GET['ids'])?intval($_GET['ids']):null;
$idc= isset($_GET['idc'])?intval($_GET['idc']):null;
if (isset($ids)) {
//display something
}
elseif(isset($idc)) {
//display something different
}
else
{
//display nothing has passed
}
I tested your script above,it works as expected.Maybe you should check whether the link is correct or not.
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.