I have a list of variables which I am using for some PHP functions. I know I can simplify this code but I am not really sure how. I have tried for(){} loops but haven't figured out how to make the result usable.
HERE ARE MY VARIABLES
$saveData_1 = post_data($url_1);
$saveData_2 = post_data($url_2);
$saveData_3 = post_data($url_3);
$saveData_4 = post_data($url_4);
$saveData_5 = post_data($url_5);
$saveData_6 = post_data($url_6);
$saveData_7 = post_data($url_7);
$saveData_8 = post_data($url_8);
$saveData_9 = post_data($url_9);
$saveData_10 = post_data($url_10);
$saveData_11 = post_data($url_11);
$saveData_12 = post_data($url_12);
$saveData_13 = post_data($url_13);
$saveData_14 = post_data($url_14);
$saveData_15 = post_data($url_15);
$saveData_16 = post_data($url_16);
$saveData_17 = post_data($url_17);
$saveData_18 = post_data($url_18);
$saveData_19 = post_data($url_19);
$saveData_20 = post_data($url_20);
HERE IS WHAT I HAVE TRIED
for($i = 0; $i<20; $i++) {
$saveData = '$saveData_'.$i;
$postData = 'post_data($url_'.$i.')';
print($saveData. '=' .$postData. ';');
}
This works for the most part, it prints out my list of variables. But what I don't know, is how to make this usable so instead of printing them to the page being displayed in the browser they will be instead be "printed" to my php script.
Basically my goal is to write the Variables of above without having to actually write a new variable each time.
If I understand what you're asking correctly, you want to have actual "variables" that you can use, such as $saveData_16, but don't want to type each one out?
If that's the case, you can what's called a variable-variable:
$varName = 'saveData_16';
$postName = 'url_16';
$$varName = post_data($$postName);
Note the double $$ prefixing the variable's name.
This can be dropped into a loop with:
for ($i = 0; $i < 20; $i++) {
$varName = 'saveData_' . $i;
$postName = 'url_' . $i;
$$varName = post_data($$postName);
}
Variable-variables can be tricky to remember and a nuisance to keep up with, especially if they contain similar names/values as existing variables. If they do, they can easily overwrite an important variable in your code. If this is a potential issue, you should probably avoid them.
An alternative to variable-variables, but on the same topic, if your values really do come from $_POST (based on the function-name post_data()), you can look into PHP's extract() function which performs the same "extraction" for you:
extract($_POST);
I would recommend against using extract() unless you're very clear on what's needed though. It can easily overwrite other variables that use the same name as a posted field. It does provide an optional second-parameter named $extract_type that is a flag specifying the behavior of the extract and, through this, you can tell it to not overwrite existing variables:
extract($_POST, EXTR_SKIP);
Again though, this can cause headaches by simply forgetting the optional flag - so I would avoid this function if this is a risk.
As an additional alternative, you could store the results into an array and use the array as-is. I personally support this method and, if you use strings as your array indexes, it can be just-as-readable as using a variable (and more-readable than a variable-variable).
If you're currently using $_POST, well, you should be all set - it's already in array form. However, if you're obtaining your data in a different method you can always build your own array with:
// build your array
$saveData = array();
for ($i = 0; $i < 20; $i++) {
$urlName = 'url_' . $i;
$saveData['url_' . $i] = post_data($$urlName);
}
// access a value
echo $saveData['url_4'];
I'm not 100% sure what your $url_# variables are, so I've kept that as a variable-variable in the array example; if it's just a string, you could replace it with the string instead.
You need to use arrays. I will type up an example and add it to this comment. But what you want to use is an array variable. One array can hold all this and you can iterate (loop) through it easily.
Here ya go:
<?php
/* what the heck? You need arrays ;-)
$saveData_1 = post_data($url_1);
$saveData_2 = post_data($url_2);
$saveData_3 = post_data($url_3);
$saveData_4 = post_data($url_4);
$saveData_5 = post_data($url_5);
$saveData_6 = post_data($url_6);
$saveData_7 = post_data($url_7);
$saveData_8 = post_data($url_8);
$saveData_9 = post_data($url_9);
$saveData_10 = post_data($url_10);
$saveData_11 = post_data($url_11);
$saveData_12 = post_data($url_12);
$saveData_13 = post_data($url_13);
$saveData_14 = post_data($url_14);
$saveData_15 = post_data($url_15);
$saveData_16 = post_data($url_16);
$saveData_17 = post_data($url_17);
$saveData_18 = post_data($url_18);
$saveData_19 = post_data($url_19);
$saveData_20 = post_data($url_20);
*/
$saveData = array(); // just a formality. You don't need to delcare variable types in PHP.
for ($i = 1; $i < 21; $i++) {
$var = 'url_'.$i;
$saveData[$i] = post_data($$var);
}
// now all your stuff is in $saveData
// what's in savedata 20? this is:
echo $saveData[20];
// you could skip all of this and just use the $_POST superglobal
$_POST[$url_20]
// I'm curious to see what you are doing, because this process should be re-thought.
Related
Say I have $exampleVariable, which I want to print. $exampleVariable may be an array, in which case I have this set up to get the right array element, which I can then print with print $exampleVariable[$i].
if ($_GET) {
$i = array_search($_GET["exampleQueryString"], $exampleVariable);
} elseif (is_array($exampleVariable)) {
$i = 0;
} else {
$i = "";
}
My problem is that last else, if $exampleVariable is NOT an array, because then I get print $exampleVariable[] which doesn't work. So is there something I can put as $i to print the whole variable?
Alternatively, I considered including the brackets in $i, so I'd have for example $i = [0];, but in that case I don't know how I'd print it. $exampleVariable$i certainly won't work.
I have a good number of variables besides $exampleVariable I'll need to print, all with the same $i or lack thereof, so I'd like to not have to do anything longwinded to set each of them up individually.
This sounds way more complicated than I feel like it should, so hopefully it makes sense!
You can always do a nifty thing that is called type casting. That means, that you can always make a variable an array even if it is not, by prepending its name by (array):
$exampleVariable = (array)$exampleVariable;
So you don't need three if branches at all:
if ($_GET) {
$i = array_search($_GET["exampleQueryString"], $exampleVariable);
} else {
$i = 0;
$exampleVariable = (array)$exampleVariable;
}
You could apply the (array) cast, which will have no effect if the target is already an array:
$i = array_search($_GET["exampleQueryString"], (array)$exampleVariable);
How can I build a composed variable while creating a variable in PHP?
(Sorry I'm not sure how to call the different elements)
This is what I'm trying to do:
$language = 'name_'.$this->session->userdata('site_lang');
for ($i=1;$i<=3;$i++) {
$data = $arraydata->$language_.$i; // problem is here
}
I would like $language_.$i to be equivalent to name_english_1, next loop name_english_2... The same way I built $language
If you want to use an expression in a computed property, you have to put the expression in braces. Also, you need to put the underscore in quotes.
$data = $arraydata->{$language."_".$i};
However, I suggest you redesign your data structure. Instead of having separate name_LANG_i properties, make a single name property whose value is a multi-dimensional array.
$lang = $this->session->userdata('site_lang');
for ($i=1;$i<=3;$i++) {
$data = $arraydata->name[$lang][$i];
// do something with $data
}
Whenever you find yourself using variable variables or variable properties, it's almost always a sign that you should be using an array instead.
First construct the field name and then use it for accessing the field value from the object $arraydata. So your code should be like this:
$language = 'name_'.$this->session->userdata('site_lang');
for ($i = 1; $i <= 3; $i++) {
$var = "{$language}_{$i}";
$data = $arraydata->$var;
// echo $data;
}
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 got a code of 100-200 rules for making a table. but the whole time is happening the same.
i got a variable $xm3, then i make a column . next row, i got $xm2 and make column. next row, i got $xm1 and make column.
so my variables are going to $xm3, $xm2, $xm1, $xm0, $xp1, $xp2, $xp3.
is there a way to make a forloop so i can fill $xm and after that a value from the for loop?
In this kind of structure you'd be better off using an array for these kinds of values, but if you want to make a loop to go through them:
for($i = 0; $i <= 3; $i++) {
$var = 'xm' . $i
$$var; //make column stuff, first time this will be xm0, then xm1, etc.
}
It is not fully clear what you are asking, but you can do
$xm = 'xm3';
$$xm // same as $xm3
in PHP, so you can loop through variables with similar names. (Which does not mean you should. Using an array is usually a superior alternative.)
As far as I am aware using different variable names is not possible.
However if you uses arrays so as below
$xm[3] = "";
$xm[2] = "";
$xm[1] = "";
$xm[0] = "";
or just $xm[] = "";
Then you can use a for each loop:
foreach($xm as $v) { echo $v; }
Edit: Just Googled and this is possible using variable names but is considered poor practice. Learn and use arrays!
You can do this using variable variables, but usually you're better off doing this sort of thing in an array instead.
If you're positive you want to do it this way, and if 'y' is the value of your counter in the for loop:
${'xm' . $y} = $someValue;
You can easily do something like this:
$base_variable = 'xm';
and then you can make a loop creating on the fly the variables;
for example:
for ($i=0; $i<10; $i++)
{
$def_variable = $base_variable . $i;
$$def_variable = 'value'; //this is equivalent to $xm0 = 'value'
}
I have a situation where I require to consult different objects in PHP via different methods to find some data.
The question regards more about formatting the code than an actual programming issue. What I am trying to do is not using several if's to gather this data like:
$data = obj->getData();
if (!isset($data)) $data = othObj->getThisData();
if (!isset($data)) $data = anothObj->getTheData();
if (!isset($data)) $data = anothOne->getAData();
...
process($data)
I was wondering what are the best practices in this case, if there is a better way using another procedures, like foreach or switch/case.
Thanks!
You can make an array of the possible objects you want to try, then run a loop. Might be more maintainable. This code can be modified to include parameters and use call_user_func_array instead.
$dataCallback = array(
array($othObj, 'getData'),
array($othObj, 'getThisData'),
array($anothObj, 'getTheData'),
array($anothOne, 'getAData'),
);
for($i = 0, $t = count($dataCallback); !isset($data) && $i < $t; $i++) {
$callback = $dataCallback[$i];
$data = call_user_func($callback);
}
if (isset($data))
process($data);
else
//no valid data returned at all ...
It doesn't look too bad the way it is.
It could be a bit more efficient if the if's were nested. e.g.
if (!isset($data = othObj->getData()))
if (!isset($data = othObj->getThisData()))
if (!isset($data = anothObj->getTheData()))
$data = anothOne->getAData()))
// ...
process($data)
Since there are less calls to isset (though they're pretty cheap anyway, so I wouldn't worry about it).
Personally I'd do something like this:
$data = null;
if (isset($obj->getData()) $data = $obj->getData();
else if (isset($othObj->getThisData()) $data = $othObj->getThisData();
else if (isset($anothObj->getTheData()) $data = $anothObj->getTheData();
else if (isset($anothOne->getAData()) $data = $anothOne->getAData();
process($data)
This saves processing time if the earlier objects actually return something. Since it is an elseif setup once it finds data it'll stop processing the other if clauses.
I don't think a switch statement would be appropriate in this case. Switches tend to be testing the value of one variable (is $a = 1, 2, 3 or 4).
($data = $ob1->get()) || ($data = $ob2->get()) || ($data = $ob3->get());
Would work, but if you're get function returns an empty array or false or empty string instead of NULL, it's going to continue looking for data...
I'd probably group the objects to ask for data into an array:
$objArray = array($obj, $othObj, $anothObj, ... );
Then run through a while loop until I had data:
$i = 0;
do {
$data = $objArray[$i]->getData();
$i++;
} while(!isset($data) && $i < count($objArray));