I have a function in CodeIgniter which populates a list of days. I called it init_days(). I call this function using ajax and output the returned values into a div using jQuery.
This function does not take any arguments; I load the default values in from a model and work from there. (This function loads a couple of days into a list, starting from the current day (today). I load the current day/month/year/.. in from my model).
However, since this list will have to be manipulated (to show, for example, the next month). In this case, I suppose I'd have to pass arguments to my function.
Now, I don't really want to have one function to initiate the list (init_days()), and then another function, lets call it populate_days(), which takes arguments but essentially does the same thing, just with manipulated values.
Is there a way to check whether or not I'm passing values to my function? That way I could just keep my function the way it is and add a check for arguments. Or perhaps I'm making this more difficult than it is (as usual :( ) and there's an easier way? Thanks a lot!
If you have a set amount of arguments, you could just give them default values
function init_days($start = '', $end = '') {
if (!empty($start) && !empty($end)) {
//got both vars. do something with it here
}
}
You could also use func_get_arg() if you're working with variable numbers of parameters. So your method will work with or without arguments
http://php.net/manual/en/function.func-get-arg.php
http://www.php.net/manual/en/function.func-num-args.php
Related
I was trying to find out how wordpress process each request and returns the result. I found wp() function calls $wp->main() which in turn calls $this->query_posts(); and which calls $wp_the_query->query($this->query_vars) function in query.php file. The query() function calls return $this->get_posts(); and return the result.
My question is didn't see any any variables receiving this returned value so why this function has return, even though the wordpress works if I remove the return from the code. so what is the purpose of this return, (I guess this code saves the contents (posts) to $this->posts variable). btw I am using wp 3.6
I believe this answer may provide what you're looking for:
https://wordpress.stackexchange.com/a/1755
Specifically this image (which I did not create myself):
The use of return is related to php (also used in other languages) not only WordPress. When execution reaches a return statement, the function stops and returns that value without processing any more of the function. A return with no value returns null and If there is no return keyword at the end of a function then, in this case too, a null value get returned.
Using a return statement at the end of a method/function is a good coding practice, it just returns the execution control back to the point, from where it started and it also Prevents Code Injection in PHP include files. Also, check this.
Short Answer:
There are other functions that make use of the returned value, mostly in themes and plugins, but also in WP core. examples are given below.
Long Answer:
In wordpress the WP_Query::query() method is used for getting posts from the DB.
This is done by providing certain criteria for selection, ie: the query_vars.
Based on which the posts are retrieved and made available.
now, in the case mentioned by you what is of important is the call stack, ie the path used to call the function.
ie:
wp() --->
[WP->main()]-->
WP->query_posts() {here the query is
called on the global
wp_query Object}
-->WP_Query->query()
In WP->main(), the parse_request methond is called, which creates the query_vars from the REQUEST_URI.
so whatever post is fectched depends on the requested pages URL. i.e the criteria for selection is provided by the requested page's url.
And since the query method is called on the global wp_query object, there is no need to return it.
This forms the main path, ie: global wp query, and request uri query vars.
But in cases, like in themes, plugin, when you need to fetch additional posts. you will create a new wp query object, and use the query method.
eg: to fetch all posts by 'john'. in these situation the value returned by the query method is used.
$wpquery = new Wp_query();
posts = $wpquery->query("author_name=john");
Some functions that uses it:
wp_nav_menu_item_post_type_meta_box /wp-admin/includes/nav-menu.php
wp_link_query /wp-includes/class-wp-editor.php
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);
Ideally what I want to have is a list of functions that can be run later. Depending on user input a function will then be chosen. The user will be then queried for parameters for that function. This will happen several times until the user inputs that they want all the functions to be run after each other.
I can't have a single form as there is not a fixed number of steps. The number of functions depends on the user. They will input the functions they want until they input that they want all functions to be run in the order they were inputed.
e.g. Input--Response
A user will provide an input. -- run....... Depending on their input they will be asked for parameters.How far and how fast? -- 100 and 10......The function becomes run(100,10)
Another input -- shout.........Shout what? -- Hi........The function becomes shout(hi)
Next input --- jump ...... How high? -- 8.........
Function would be jump(8)
After all that when the user gives the input "play", the following should be done in order:
run(100,10), shout(hi), jump(8)
Thanks in advance :)
You can in the first step store the function name in a variable, and then use call_user_func($funcName, $arg1, $arg2, ..) to call it with the arguments from the second step.
And if you try to call a method on a class and not global functions, you have to store it as array($instance, 'methodName'), or array('className', 'methodName') for static methods.
I'm looking for the "best practice" way to achieve a message / notification system. I'm using an OOP-based approach for the script and would like to do something along the lines of this:
if(!$something)
$messages->add('Something doesn\'t exist!');
The add() method in the messages class looks somewhat like this:
class messages {
public function add($new) {
$messages = $THIS_IS_WHAT_IM_LOOKING_FOR; //array
$messages[] = $new;
$THIS_IS_WHAT_IM_LOOKING_FOR = $messages;
}
}
In the end, there is a method in which reads out $messages and returns every message as nicely formatted HTML.
So the questions is - what type of variable should I be using for $THIS_IS_WHAT_IM_LOOKING_FOR?
I don't want to make this use the database. Querying the db every time just for some messages that occur at runtime and disappear after 5 seconds just seems like overkill.
Using global constants for this is apparently worst practice, since constants are not meant to be variables that change over time. I don't even know if it would work.
I don't want to always pass in and return the existing $messages array through the method every time I want to add a new message.
I even tried using a session var for this, but that is obviously not suited for this purpose at all (it will always be 1 pageload too late).
Any suggestions?
Thanks!
EDIT: Added after I caused some confusion with the above...
The $messages array should be global: I need to be able to add to it through various different classes as well as at the top-level of the whole script.
The best comparison that comes to mind is to use a database to store all the messages that occur at runtime, and when it's output-time, query the database and output every message. The exception to this comparison is just that the lifetime of the $messages array is the page load (they accumulate during page load, and vanish right after).
So, for example, say I have 10 different actions running one after the other in the script. Each one of these actions make use of a different class. Each one of these classes should be able to post to $messages->add(). After all 10 actions have run, it's "output time", and the $messages array can contain up to 10 different messages which were added via all the different classes.
I hope this clarifies it a bit.
I'm not exactly clear about what you want to do, but a good way would be to simply use a private variable:
class messages {
private $messages = array();
public function add($new) {
$this->messages[] = $new;
}
public function output() {
// Whatever; e.g. a foreach loop that echoes all the messages
}
}
I think you need either a instance field.
I'm writing a construct in PHP where a parser determins which function to call dynamically, kind of like this:
// The definition of what to call
$function_call_spec = array( "prototype" => "myFunction",
"parameters" => array( "first_par" => "Hello",
"second_par" => "World"));
// Dispatch
$funcPrototype = $function_call_spec["prototype"];
$funcPrototype(); // Here we call function 'myFunction'.
This is all fine and dandy. But now comes the next step, passing the parameters, which I don't really know if it's possible the way I want to do it. It never stops amazing me however what script languages can do these days, so here goes:
One could pass the parameters to the function like this:
// Here we call function 'myFunction' with the array of parameters.
$funcPrototype( $function_call_spec["parameters"] );
However, I want to declare 'myFunction' properly with clear arguments etc:
function myFunction( $first_par, $second_par )
{
}
The question then follows - Is there any way to pass parameters to a function dynamically simply by looping through the parameter array?
To clarify, I don't want to do it like this:
$funcPrototype( $function_call_spec["parameters"]["first_par"],
$function_call_spec["parameters"]["second_par"] );
Because this requires my code to statically know details about myFunction, which goes against the whole idea.
Instead I would want to do it in some way like this maybe:
// Special magic PHP function which can be used for invoking functions dynamically
InvokeFunction( $funcPrototype, $function_call_spec["parameters"] );
Which then results in myFunction being called and all parameters in the array gets passed to each individual parameter variable in the prototype.
Any comments are welcome.
Regards.
/R
PS: None of the code in this post has been tested for typos etc.
You should use call_user_func_array which can call any function or method and takes parameteres from an array.
Alternatively you can use ReflectionFunction::invokeArgs, but there's no benefit over call_user_func_array unless you already use this class for someting else (like checking whether function you call accepts appropriate number and types of arguments).
call_user_func_array($funcPrototype, $function_call_spec["parameters"]);
You might want to create a wrapper that names the function to your preference, such as:
function InvokeFunction($function, $args = array()) {
return call_user_func_array($function, (array)$args);
}
With this function you can call it in 3 different ways:
$return = InvokeFunction('doStuff');
$return = InvokeFunction('doStuff', $single_arg);
$return = InvokeFunction('doStuff', $multiple_args);
call_user_func_array() is the best choice if you don't need to enforce the contract, otherwise use ReflectionFunction.
http://us2.php.net/create_function
When you use create_function(), your arguments are not evaluated until runtime. Pretty sweet.