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.
Related
So I load all my budgets like so:
$budgets = auth()->user()->budgets()->get(); // With some eager loading and ordering, not needed for this example.
The problem lies in the way I perform some checks in my view. Take for example this snippet:
#foreach($budgets as $budget)
if($budget->getRemainingAmount() < 1) // getRemainingAmount() performs 6 queries
class="danger"
#endif
#endforeach
Now I have one main issue with the above approach. I don't mind the 6 queries, that's just how it works behind the scenes which is totally fine. The thing is, each time I call the method within the view, the 6 queries are run again, which means they are duplicated over and over.
What I want to do is, for example, is include that method in my query and just assign it to a variable.
$budgets = auth()->user()->budgets()->doSomethingToAssignThatMethodToSomeVariable()->get();
Let's just say for now the method does the following simple thing:
public function getRemainingAmount()
{
return 100;
}
Now, how can I assign the method getRemainingAmount() to a variable called $remaining while performing my query? Or, is there a better way to approach this perhaps? In my view, I just want to be able to change this:
if($budget->getRemainingAmount() < 1)
To this (for example):
if($remaining < 1)
So that I can perform the check multiple times without having to run 6 queries over and over, each time I call the method.
Any thoughts on how to achieve this in a simple manner? I actually have multiple methods that result in the same issue (right now my debugbar says: 66 statements were executed, 41 of which were duplicated, 25 unique). Obviously I want to remove the duplication.
You would probably be interested in using the cache for storing repetitive queries results.
You may even pass a Closure as the default value. The result of the
Closure will be returned if the specified item does not exist in the
cache. Passing a Closure allows you to defer the retrieval of default
values from a database or other external service:
$value = Cache::get('key', function () {
return DB::table(...)->get();
});
You have control over how long results are cached and it can drastically improve performance and reduce db load.
So for you, accessing some-budget-result
$result = Cache::get('some-budget-result', function () {
return auth()->user()->budgets()->doSomethingToAssignThatMethodToSomeVariable()->get();
});
would run the query once, and each subsequent time you access that cache item, same results, no additional queries.
https://laravel.com/docs/5.5/cache#retrieving-items-from-the-cache
I'm using the MVC pattern in a CodeIgniter PHP project and I'm wondering what's the best way to build methods of the models in order to ensure readability of the code and scalability.
In short, is this better to do this ? :
public function set_account_state($new_state) {
// UPDATE a database record state to $new_state [0, 1 or 2]
}
Or this ? :
public function reject_account() {
// UPDATE a database record state to 0
}
public function accept_account() {
// UPDATE a database record state to 1
}
public function pending_account() {
// UPDATE a database record state to 2
}
Or maybe another way ?
Also, is there a good practice for function naming in such cases ?
function set_account_state($state)
This is better when you have only one task and that is to change the state.
But if in future you might have to do different tasks before you change the account state then you need three different methods.
You can still have that original method to change the state of the account and call it from your three methods.
Function naming should include a verb with nouns to make it clearer.
function pending_account() is not that clear, function keep_account_pending() is I feel a better way to name it.
In my opinion, the second way is the better way.
Using names that indicate what will the method do can improve the readability of the code.
As your code grows bigger, it's easy to forget what number represents what state. That does not happen with names because a method called reject_account() will indicate that account will be rejected better then a number passed as argument to a function.
Also when other people work on your code, it will be easier for them to understand what is going on when a method is called. Having said that, it's better for one understand that the client account is accepted when one sees a method called accept_account() then when one sees set_account_state(1).
I have a members.php file that shows my websites members. I echo members name by using foreach method. A method of Members class returns an array, then I use foreach loop in the members.php file to echo the members. I am trying to aovid writing as less php code as possible in my members.php file where my html files are located. Is there a way to avoid using foreach inside members.php file?
For example, is it possible to return value from a method couple of times? (by only calling the object once). Just like how we normally call the functions? This question doesn't make sense, but I am just trying to see if there is a away around this issue?
You could write an intermediate function that caches whatever the Members-method returns and return just one index from the cache, specified by a parameter. But then you are back to using a some kind of loop.
There's nothing wrong with a loop in your view. After all, PHP is a templating language.
However, you could write an object method to return/print a formatted members list.
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
I am trying to pass parameters from one action (foo) to another (foobar).
In action foo, I set the arguments thus:
$request->getParameterHolder()->set('arg1', 'alice');
$request->getParameterHolder()->set('arg2', 'bob');
In action foobar, I try to retrieve the params thus:
$arg1 = $request->getParameter('arg1');
$arg2 = $request->getParameter('arg2');
$this->forward404Unless($arg1 && $arg2); //always forwarded
Note: I am aware that I can save the params into the user session variable - but I dont want to do that. I want to pass them as parameters - any ideas how to get this to work?
You can simply try this:
$this->redirect('module/action2?'.
http_build_query(array("arg1"=> "alice", "arg2"=>"bob")));
greg0ire's answer sounds like it's what you are asking for but there are a couple of other approaches that might be worth looking at if passing query string parameters isn't a hard requirement.
You could use a forward if you want the foobar action to execute after foo. Unlike a redirect this will live in the same request cycle so you can pass variables without touching the session.
You don't say why you don't want to use the session but there is a halfway house in Symfony: flash attributes. These are stored in the session but are guaranteed not to live beyond the next request which may be a suitable compromise.