I'm creating a website and somewhere in the code I need to query for a user attribute (ex:account state) and in the same row I have the reason, case is account state is "suspended".
I'm trying to minimize the requests to the database, so I created a function to verify account state.
function getAccountState($userid,$reason){}
What I am trying to do is if account state is "suspended" I would change the $reason to "the database reason".
I've already done that but if I change the $reason inside the function, outside the function it will not change.
I searched for "php pointers" on google but I think there is not such thing.
Is there a way to do this? Other way I'll just make another database request...
You could of course pass the variable by reference but as you don't seem to need it, I would just return it from the function:
function getAccountState($userid){
// your code
return $reason;
}
and call it like:
$reason = getAccountState($userid);
If you want to stay your code as it is now, you could pass the variable by reference:
function getAccountState($userid,&$reason){}
^ like so
You could consider passing it in by reference. Or perhaps just changing the function to return the correct information.
In the definition of functions you can tell that $reason argument is passed by reference, not value. To do so, use & in front of variable:
function getAccountState($userid,& $reason){}
You are looking for references, in PHP terminology, not pointers.
They work this way :
function getAccountState($userid, &$reason){ // Notice the &
$reason = "database locked"; // Use it as a regular variable
}
getAccountState(12345, $reason); // Here, it is written as a regular variable, but it is a ref.
echo $reason; // echoes "database locked"
Related
I have perhaps the most perplexing issue I've ever had with PHP. Please see the following code:
public $profile;
public $account;
function __construct(){
if(isset($_SESSION['uid'])){
$this->$profile = $_SESSION['user_profile'];
$this->$account = $_SESSION['user_account'];
echo "<script> alert('".$this->$profile->forename."'); </script>"; //Shows nothing
}else{
unset($_SESSION['user_profile']);
unset($_SESSION['user_account']);
}
}
For some reason, it seems that either $this->$profile will be written or $this->$account will be written, but only if it is the last one. In the situation above, if I moved the profile line to be after the account line, it would be written. However, in this case it is not.
Both $_SESSION variables are objects retrieved from an SQL statement, and their assignments are valid as accessing either of the variables directly (eg. $_SESSION['user_profile']->forename) works fine.
Any ideas? Thank you.
You are using variable variables, but your code looks like you are trying to access a member variable.
Replace this:
$this->$profile
$this->$account
With this
$this->profile
$this->account
add_filter('wp_list_pages_excludes', 'gr_wp_list_pages_excludes');
function gr_wp_list_pages_excludes($exclude_array) {
$id_array=$array('22');
$exclude_array=array_merge($id_array, $exclude_array);
return $exclude_array;
}
I'm a newbie to wordpress. The above code works fine. But I need to pass additional argument, say $mu_cust_arg to the function gr_wp_list_pages_excludes. How can I make use of it via apply_filters, or any other methods?
Any help is appreciated.
Thanks in advance.
You can indeed add multiple arguments to a filter/action, you just need to tell WordPress how many arguments to expect
Example, which won't work:
add_filter('some_filter', function($argument_one, $argument_two) {
// won't work
});
apply_filters('some_filter', 'foo', 'bar'); // won't work
It will fail with an error that too many arguments was provided.
Instead, you need to add this:
add_filter('some_filter', function($argument_one, $argument_two) {
// works!
$arugment_one; // foo
$arugment_two; // bar
}, 10, 2); // 2 == amount of arguments expected
apply_filters('some_filter', 'foo', 'bar');
Because WP doesn't accept closures as callbacks (at least, certainly not for add_filter()) the short answer is "you can't". At least, not in a tidy way.
There are a couple of options here, depending on what you are doing. The first is the best, but you may not be able to use it:
Write a wrapper function that calls your function:
function gr_wp_list_pages_excludes_1 ($exclude_array) {
$custom_arg = 'whatever';
gr_wp_list_pages_excludes_1($exclude_array, $custom_arg)
}
This will only work if you are always passing the same custom argument in a given situation - you would write one of these wrapper functions for each different situation, and pass the name of the wrapper function to add_filter(). Alternatively, if you want it to be truly dynamic, you would need to...
Use a global variable: (Ref: Variable scope, $GLOBALS)
function gr_wp_list_pages_excludes($exclude_array) {
global $gr_wp_list_pages_excludes_custom_arg;
$id_array=$array('22');
$exclude_array=array_merge($id_array, $exclude_array);
return $exclude_array;
}
Using this approach means that you can pass any data you like into the function by assigning it to $gr_wp_list_pages_excludes_custom_arg in the global scope. This is generally regarded as bad practice and heavily frowned upon, because it makes for messy and unreadable code and leaves the memory space littered with extra variables. Note that I have made the variable name very long and specific to the function to avoid collisions - another problem with using global variables. While this will work, only use it if you absolutely have to.
Very simple!
add_filter('filter_name','my_func',10,3); //three parameters lets say..
my_func($first,$second,$third){
//............
}
then
echo apply_filters('filter_name',$a,$b,$c);
I have a page named ChangeApprovalInfo.php - It has a function called Row_Rendered as follows;
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$RecordOwner = $this->RequestUser->CurrentValue;
echo $RecordOwner;
}
Echoing $RecordOwner gets me the data I will need for a sql query on another page....
I have another page called ChangeApprovalEdit.php - This page has
<?php include_once "ChangeApprovalinfo.php" ?>
at the top of the file.
ChangeApprovalEdit.php has a function where I need the $RecordOwner variable as defined in ChangedApprovalInfo.php
If I add "echo $RecordOwner" on the ChangeApprovalEdit.php page, I get an error saying it's an unknown variable. My understanding is that I need to "make it global" or some such business. I know very little about PHP and the pages I am editing are long and complex. (to me, at least)
What do I need to do? I know that the information I have provided might not be enough to answer the question. I don't know enough to even know exactly what I need to ask. If more information is needed, I will edit and follow up.
pastebin of the files
ChangeApprovalInfo.php = http://pastebin.com/bSRM1wwN
ChangeApprovalEdit.php = http://pastebin.com/AStG9pqb
EDIT:
Changing Row_Rendered to this seems to be more effective. I'm having trouble seeing WHERE I can later echo this variable... but I'm getting somewhere with this...
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
}
Don't echo variables from functions, which just outputs them to the standard output. return them from the function so you can use the value elsewhere as well.
function Row_Rendered() {
$RecordOwner = $this->RequestUser->CurrentValue;
return $RecordOwner;
}
Then instead of
$obj->Row_Rendered();
use
echo $obj->Row_Rendered();
and if you want to use the value elsewhere, use
$value = $obj->Row_Rendered();
You can do a couple of things:
First, you can return $RecordOwner from the function, and store its value in a variable. This method is usually preferred.
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$RecordOwner = $this->RequestUser->CurrentValue;
echo $RecordOwner;
return $RecordOwner;
}
// Store it in a variable when calling the function.
$RecordOwner = Row_Rendered();
Or, you can make it global inside the function:
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
echo $GLOBALS['RecordOwner'];
}
You can use the $GLOBALS superglobals array, like this:
function Row_Rendered() {
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
}
However, you should not do that. Instead, refactor your application so that the view in ChangeApprovalinfo.php just contains a function, which is then called with the appropriate parameters.
EDIT: Chaning Row_Rendered to this seems to be more effective. I'm having trouble seeing WHERE I can later echo this variable... but I'm getting somewhere with this...
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
}
I feel compelled to write another answer to this update. Let me demonstrate the use of globals as seen from outside that function:
$obj->Row_Rendered();
$obj->foobar();
echo $GLOBALS['RecordOwner'];
Quick, what will be echoed and where does that value come from? Well, it depends on what $obj-foobar() does. Maybe it changes the global variable. Maybe it doesn't. Who knows if the variable has been set at all? How would you trace back what happened exactly without adding a debug line after every single function call?
And that's just three lines of code. Imagine that in an application of any complexity.
Now, the same thing if I return the value from Row_Rendered:
$owner = $obj->Row_Rendered();
$obj->foobar();
echo $owner;
If the Row_Rendered method is behaving as it should (returning the owner), this code is very predictable. If you do not follow this pattern, you'll have a hell of a time getting anything done when the application grows to any halfway complex size.
Set the variable as global from within the function
$my_global_var = "old value";
function doing_stuff(){
global $my_global_var; //this will use the global variable instead of creating a local one
$my_global_var = "new value";
}
echo $my_global_var;//returns "new value"
I have the same question but...I'm redirecting the user depending on an if statement using headers to a dynamic page that is constructed through a function. For that function to work properly, it needs the parameters passed in the GET portion of the headers.
According to what to the answers provided, this is a bad practice. What way should I be doing it?
function page($title,$msg){
$title = $_GET['title'];
$msg = $_GET['msg'];
echo '<h1>'.$title.'</h1>';
echo '<p>';
switch($msg){
case 1:
echo 'dwasdwadawdwadwa';
break;
case 2:
echo 'wasdadwadwdad';
break;
default:
echo 'wadasdasd';
break;
}
echo '</p>';
}
ps: feel free to point out anything else you see wrong.
I found this but it doesn't really help me.
Although you aren't necessarily using the $_GET input for something that requires security considerations (in this case), it's a bad practice not to be sanitizing values from the URL.
Not only should you be checking for malicious input (especially if you are using the input to query a database), but you should be validating that expected integer values are indeed integers, and required strings are not empty.
Also, your page($title, $msg) function accepts $title and $msg and sets them, even though they are not passed by reference.
If you expect to modify the input parameters, pass them by reference.
If you need to use the input parameters, don't overwrite them immediately.
If you don't need input parameters and only use values from $_GET locally to your function, declare page() without any arguments.
The answer to the question you linked suggests that functions should not rely on any external (e.g. global) variables. $_GET and $_POST (amongst others) are 'super globals', a language feature of PHP that makes them available in any scope. This means they may be unexpectedly modified from anywhere in your scripts.
One way to help avoid this is to avoid using super globals in methods and instead - as the answer to the other question suggests - is to instead require parameters for the variables you would otherwise get from the super globals.
E.g., instead of:
function add_user() {
$user = $_GET['user'];
// ...
}
add_user();
You would use:
function add_user($user) {
// ...
}
add_user($_GET['user']);
In your situation, what you would want is:
function page($title, $msg){
echo '<h1>'.$title.'</h1>';
echo '<p>';
switch($msg){
case 1:
echo 'dwasdwadawdwadwa';
break;
case 2:
echo 'wasdadwadwdad';
break;
default:
echo 'wadasdasd';
break;
}
echo '</p>';
}
Then, when you call page you would call it as:
page($_GET['title'], $_GET['msg']);
Why do you need to use GET? you can access all the same properties if you use POST which is also more safe
Not sure if i understand your question, but here is some code i use handle my ajax calls with:
$mc = new MyClass();
echo $mc->{$_GET["operation"]}($_GET);
This means "operation" refers to your method name inside MyClass and i dont have to add a new switch statement for each method. Now i can just add a function "addRecord($args)" to MyClass, and my ajax call would look like this:
ajax_users.php?operation=addRecord&name=testuser&dob=1980-01-01
your php function receives the arguments in an array, so inside function addRecord() you have to access the variables like $args['name'] and $args['dob'], and it dosnt matter how many parameters you have to pass on to your method.
Make sure you use prepared statements here or proper escaping to prevent sql injections.
I've got a project that passes JSON between the frontend and the backend. So, the frontend PHP would generate the statement { "command" : "getuser", "parameters" : { "userid" : 1 } } and send it to the backend. The backend then executes
if ($command == 'getuser') {
validate($parameters['userid']);
if ($this->valid) { <<get the user>> }
}
Validate checks the variable and sets $this->valid. It creates an error message if necessary. I want to create an error message in case the front end passes in { "command" : "getuser", "parameters" : "" }. In this case, $parameters['userid'] is never set, and validate() will complain that it was passed an unset variable.
I've come up with two solutions. The first solution is to set $parameters['userid'] = "unset" before loading in the JSON, and then check for it in the validator. The other solution is to use
if (isset($parameters['userid'])) {
validate($parameters['userid']);
}
else {
echo("Error"); }
It'd be nice if validate() could figure out on its own whether or not the variable is there. Is there a more elegant way I should be doing things?
In short, no. The error happens as, rather than after, validate() is called so there is no way for it to intercept that.
It sounds like a better solution would be to have a validateUser() function that is passed in the whole $parameters variable then does the check you're looking for against the 'user_id'. This allows you to to further separate your concerns (validation, versus response).
If you want this style of code, you could pass arg to function by reference
If not, try to use this validate($parameters, 'userid');
You would have to pass $parameters into validate and let it check if userid was there and if not create the error message.