How can I let a user (e.g. admin), by text input, choose which function to use?
I have really tried to think of a solution for this, and I really don't want to use eval, I can't even use it anyways because it is disabled (which is good), but I need the user to be able to specify what function the program needs to perform for a couple of times.
It is a general function that allows you to choose which function you want to perform, and then performs the function a lot of times.
Let me give an example that should work: (but I don't want to do this, because it uses eval, and eval is also disabled)
function generate_random_integer($a, $b) {
...
}
function rinse_and_repeat($array, $count) {
$function_name = $array[0];
$params = $array[1];
$param_string = implode(",", $params);
$query= '$function_name($param_string);';
$total = 0;
for($i = 0; $i < $count; $i++) {
$value = eval($query);
if($verbose) { print($value); }
$total += $value;
}
$ratio = $total/$count;
return($total);
}
$input = array("generate_random_integer", array(1, 10));
$total = rinse_and_repeat($input, 100);
Don't stare blind on the "generate_random_integer", I know I can do that with other functions, but I want a general solution for letting the user choose which function to perform.
How do I make something similar to this, without using eval?
Can you only do this with eval or similar functions?
If you are using OOPs, you can probably make use of strategy design pattern, which is a good practice. Using this pattern you can create object of a class based on user input
Create different class for each user input, so that you can create object of that particular class. All methods that depend on user input can go into that class.
https://refactoring.guru/design-patterns/strategy/php/example
Related
My problem is that I have lots of functions with VERY long lists of function parameters such as this one:
function select_items($con,$type,$id_item,$item_timestamp,$item_source_url,$item_type,$item_status,$item_blogged_status,$item_viewcount,$item_language,$item_difficulty,$item_sharecount,$item_pincount,$item_commentcount,$item_mainpage,$item_image_width,$item_image_height,$item_image_color,$item_modtime,$order,$start,$limit,$keyword,$language,$id_author,$id_sub_category,$id_category,$id_tag,$id_user){ ... }
As you can see its super long and (of course) very hard to maintain. Sometimes I need all of the variables to construct a super complex sql query, but sometimes I just use 1 or 2 of them. Is there a way to avoid this colossal list of parameters? For example with some strict / special naming convention ?
So basically I need something like this:
$strictly_the_same_param_name="It's working!";
echo hello($strictly_the_same_param_name);
function hello() //<- no, or flexible list of variables
{
return $strictly_the_same_param_name; // but still able to recognize the incoming value
}
// outputs: It's working!
I thought about using $_GLOBALs / global or $_SESSIONs to solve this problem but it doesn't seems really professional to me. Or is it?
For a first step, as you said, sometimes you need to call the function with only 2 args, you can set default values to your arguments in the declaration of your function. This will allow you to call your function with only 2 args out of 25.
For example:
function foo($mandatory_arg1, $optional_arg = null, $opt_arg2 = "blog_post") {
// do something
}
In a second step, you can use, and especially for that case, arrays, it will be way more simple:
function foo(Array $params) {
// then here test your keys / values
}
In a third step, you can also use Variable-length argument lists (search in the page "..."):
function sum(...$numbers) {
$acc = 0;
foreach ($numbers as $n) {
$acc += $n;
}
return $acc;
}
But ultimately, I think you should use objects to handle such things ;)
You can try use ... token:
$strictly_the_same_param_name= ["It's working!"];
echo hello($strictly_the_same_param_name);
function hello(...$args) //<- no, or flexible list of variables
{
if ( is_array( $args ) {
$key = array_search( 'What you need', $args );
if ( $key !== false ) {
return $args[$key];
}
}
return 'Default value or something else';
}
This might be a very dumb question but it still bugs me. I tend to use this:
$variable = $someObject->getSomeValue();
for ($i = 0; $i < $x; $i++) {
performSomeFunction($variable);
}
I have seen people do the following & some of my co-workers are arguing with me that there is no difference in performance if I use function calls within a loop & that it will save 1 line of code.
for ($i = 0; $i < $x; $i++) {
performSomeFunction($someObject->getSomeValue());
}
Now for $x = 10 this might not have impact on performance but what if $x = 10000 ? Which one is the preferred way or best practice in PHP and in Programming general?
Example of function getSomeValue
// just a getter method for the class
function getSomeValue() {
return $this->userFirstName;
}
Highly depends on your function. For example this
function() {
return 2;
}
It won't matter.
For this:
function() {
$pdo->query('SELECT ....');
// more db stuff
return $someDbStuff;
}
It will matter extremely!
Depends on what you do on $someObject->getSomeValue();. If just returns a variable, it doesn't have any impact on performance, if, on the other hand, you are retrieving the data from a database, its very important to avoid it.
However, its always a good policy to avoid unnecessary iterations and do like this
$variable = $someObject->getSomeValue();
for ($i = 0; $i < $x; $i++) {
performSomeFunction($variable);
}
Yeah, sure there's an impact in the performance.
If you are about to use the same value over iterated loops, why would you go get it every time?
It's better getting it before the loop (if there's no chance of changing this value while in the loop) and then reusing it.
Imagine this getSomeValue() needs to access a database or a webservice, would you rather do it 1 time or $x times for the same effect?
Basic question really, I know I can do this in some other languages but I dont know PHP that well, hoping someone can help.
So I have the following.
$holyToT *=100;
$coldToT *=100;
$fireToT *=100;
$poisonToT *=100;
$lightningToT *=100;
And I want to be able to just condense it down to something like:
$holyToT, $coldToT, $fireToT, $poisonToT, $lightningToT *= 100;
Does PHP have an internal way of doing something similar?
I agree with the others, but if you really want to have it in one line, you could do something like this:
list($holyToT, $coldToT, $fireToT, $poisonToT, $lightningToT) = array_map(function($x) { return $x*100;}, array($holyToT, $coldToT, $fireToT, $poisonToT, $lightningToT));
There is no syntax that allows you to do exactly this in a single statement.
You could cook up ways of doing this (by pushing everything inside an array), but the result would be much less clear and performant than a group of assignments.
Something like this comes to mind, but if they catch you doing this don't say you heard it from me:
extract(array_map(
function($i) { return $i * 100; },
compact('holyToT', 'coldToT', 'fireToT' /*, ... */ )
));
There is ni build in functionality. Depending on the PHP Version you could pass an array and a lambda function to a custom function.
function performOnAll(array $a, $fct) {
foreach($a as $v) $fct(&$a);
}
performOnAll(array($a, $b, ...), function(&$a) { $a *= 100; });
That's it basically (not syntax checked).
I have an object with lots of properties. Some of the properties have their names start with the same string of text (in my example to come "bullet"), followed by an integer.
I can fetch the property values as follows:
echo $objectName->bullet1;
echo $objectName->bullet2;
echo $objectName->bullet3;
and so on.
I'm trying to write a for loop to get the first 20 of these, and at the moment it looks a bit like:
for ($i = 1; $i <= 20; $i++){
if ($objectName->bullet$i){
echo $objectName->bullet$i;
}
}
But this isn't working. I know I could write something like
$bulletsArray[1] = $objectName->bullet1;
$bulletsArray[2] = $objectName->bullet2;
$bulletsArray[3] = $objectName->bullet3;
all the way through to 20, then put a for loop on that, but I'm sure there must be a cleaner way. Can someone point me in the right direction?
This is how you can do it:
for ($i = 1; $i <= 20; $i++){
$propertyName = "bullet$i";
if ($objectName->$propertyName){
echo $info->$propertyName;
}
}
Though I think using an array instead of the object would be a better solution.
$var = 'myVariable';
$value = $object->$var;
is the correct syntax for accessing a field by name in PHP.
In your case it would look something like this:
for ($i = 1; $i <= 20; $i++)
{
$var = 'bullet'.$i;
if ($objectName->$var)
{
echo $info->$var;
}
}
Both previous answers have the "try it, if it doesn't work, move on" and are working for a very specific situation. Let me give you a more generic approach, which, sadly, requires PHP 5.
A bit about Reflection
Reflection allows you to reflect on an object or class to extract useful information about it. In particular, you can use Reflection to get all the properties set in a class, whether static, at run-time, or generated on the go.
To do this, start by initiating your Reflection object (assuming your class object is $object) as follows:
$refObj = new ReflectionObject($object);
This will now give you a reflection interface. Notice the useful ReflectionObject::getProperties() method - it allows you to get all properties set in a class (and you can filter by public, protected, private etc... if needed). We'll use exactly this:
$yourNewArray = array();
$PropertyArray = $refObj->getProperties();
$pCount = count($PropertyArray);
for ($i = 0; $i < $pCount; $i++) {
$yourNewArray[$PropertyArray[$i]->getName()] = $PropertyArray[$i]->getValue($object);
}
Done. Completely generic, works anywhere.
in my system, which doesn't allow me to do
$myPropertyValue = $object->$property;
I still can get to the value of the 'variable' property name with the function below; you can set $property without php complaining about syntax or throwing errors.
<?php
class MyClass{
public function getProperty($propertyName){
$props=get_object_vars($this);
if (array_key_exists($propertyName,$props)){
return $props[$propertyName];
}else{
return FALSE;
}
}
}
?>
I have this function that I wrote that is abysmally slow since php does not handle recursion well. I am trying to convert it to a while loop, but am having trouble wrapping my head around how to do it.
Can anyone give me some tips?
public function findRoute($curLoc, $distanceSoFar, $expectedValue) {
$this->locationsVisited[$curLoc] = true;
$expectedValue += $this->locationsArray[$curLoc]*$distanceSoFar;
$at_end = true;
for($i = 1; $i < $this->numLocations; $i++) {
if($this->locationsVisited[$i] == false) {
$at_end = false;
if($expectedValue < $this->bestEV)
$this->findRoute($i, $distanceSoFar + $this->distanceArray[$curLoc][$i], $expectedValue);
}
}
$this->locationsVisited[$curLoc] = false;
if($at_end) {
if($expectedValue < $this->bestEV) {
$this->bestEV = $expectedValue;
}
}
}
I'm not going to convert your code, but you can convert a recusive function into an iterative one by creating a stack:
$stack= array();
And instead of invoking $this->findroute(), push your parameters onto this stack:
$stack[] = array($i, $distanceSoFar + $this->distanceArray[$curLoc][$i], $expectedValue);
Now surround basically everything in your function into a while loop draining the stack after having primed it:
while ($stack) {
// Do stuff you already do in your function here
You can convert a recursive function into an iterative function by using a stack to store the current state. Look into array_push() and array_pop().
At a glance I don't think recursion is your problem, yes it's slow in PHP, but It looks like your going over values more than you need to, putting the values in a stack, or several stacks and handling them, may be nice.
custom sort functions have always helped me with problems of this sort.
function sort_by_visited($x,$y)
{
return ($this->locationsVisited[$x] > $this->locationsVisited[$y]) ? -1 : 1;
}
uasort($locationsVisited,'sort_by_visited');
This will prioritize all not visited locations at the top of the stack.
This looks like your trying to find the optimal route for traversal of a series of nodes in a graph.
I'm guessing that you've not studied Computer Science as the "Travelling Salesman" problem is an archetype of Artificial Intelligence. Of course, as such, it has its own Wikipedia page:
http://en.wikipedia.org/wiki/Travelling_salesman_problem
Sorry - but just swapping from a recursive to an iterative function isn't going to make it go any faster ("php does not handle recursion well." - can you provide reference for this assertion). If you need a faster solution then you'll need to look at non-exhaustive/fuzzy methods.
C.