Let me know if you want more details but:
I have an different number of inserts I need to make based on a POST form data that I created in a loop.
If I were to write it all out it would look like this:
$Scout1=$_POST['ScoutID1'];
$Scout2=$_POST['ScoutID2'];
and it keeps going until it reaches "x" I do have that number stored as
$ScoutCount
(so if the above code would post all the variables I brought over {$ScoutCount=2}
I can't find a way to do:
while (X>0){
$ScoutX=$_POST['ScoutIDX'];
X--;
}
how can I do this?
You might be looking for variable variables
But rather, I would recommend storing the data in an array, as opposed to individual variables. Then in a for loop, it could look like:
$scouts = array();
for ($i = 0; $i < 10; $i++)
{
$scouts[$i] = $_POST['ScoutID' . $i];
}
or something.
instead of having form fields called ScoutID1, ScoutID2 wtc name them
name="ScoutID[]"
then you will have a nice array with work with
//put scoutIDs into Array
$scouts = array();
for ($i = 1; $i <= $ScoutCount; $i++)
{
$scouts[$i] = $_POST['ScoutID' . $i];
}
Thanks - that may have seemed easy but I wasted a day trying to figure it out. thanks from the newbie to Php....
Related
I am looking for a way to create new arrays in a loop. Not the values, but the array variables. So far, it looks like it's impossible or complicated, or maybe I just haven't found the right way to do it.
For example, I have a dynamic amount of values I need to append to arrays. Let's say it will be 200 000 values. I cannot assign all of these values to one array, for memory reasons on server, just skip this part.
I can assign a maximum amount of 50 000 values per one array. This means, I will need to create 4 arrays to fit all the values in different arrays. But next time, I will not know how many values I need to process.
Is there a way to generate a required amount of arrays based on fixed capacity of each array and an amount of values? Or an array must be declared manually and there is no workaround?
What I am trying to achieve is this:
$required_number_of_arrays = ceil(count($data)/50000);
for ($i = 1;$i <= $required_number_of_arrays;$i++) {
$new_array$i = array();
foreach ($data as $val) {
$new_array$i[] = $val;
}
}
// Created arrays: $new_array1, $new_array2, $new_array3
A possible way to do is to extend ArrayObject. You can build in limitation of how many values may be assigned, this means you need to build a class instead of $new_array$i = array();
However it might be better to look into generators, but Scuzzy beat me to that punchline.
The concept of generators is that with each yield, the previous reference is inaccessible unless you loop over it again. It will be in a way, overwritten unlike in arrays, where you can always traverse over previous indexes using $data[4].
This means you need to process the data directly. Storing the yielded data into a new array will negate its effects.
Fetching huge amounts of data is no issue with generators but one should know the concept of them before using them.
Based on your comments, it sounds like you don't need separate array variables. You can reuse the same one. When it gets to the max size, do your processing and reinitialize it:
$max_array_size = 50000;
$n = 1;
$new_array = [];
foreach ($data as $val) {
$new_array[] = $val;
if ($max_array_size == $n++) {
// process $new_array however you need to, then empty it
$new_array = [];
$n = 1;
}
}
if ($new_array) {
// process the remainder if the last bit is less than max size
}
You could create an array and use extract() to get variables from this array:
$required_number_of_arrays = ceil($data/50000);
$new_arrays = array();
for ($i = 1;$i <= $required_number_of_arrays;$i++) {
$new_arrays["new_array$i"] = $data;
}
extract($new_arrays);
print_r($new_array1);
print_r($new_array2);
//...
I think in your case you have to create an array that holds all your generated arrays insight.
so first declare a variable before the loop.
$global_array = [];
insight the loop you can generate the name and fill that array.
$global_array["new_array$i"] = $val;
After the loop you can work with that array. But i think in the end that won't fix your memory limit problem. If fill 5 array with 200k entries it should be the same as filling one array of 200k the amount of data is the same. So it's possible that you run in both ways over the memory limit. If you can't define the limit it could be a problem.
ini_set('memory_limit', '-1');
So you can only prevent that problem in processing your values directly without saving something in an array. For example if you run a db query and process the values directly and save only the result.
You can try something like this:
foreach ($data as $key => $val) {
$new_array$i[] = $val;
unset($data[$key]);
}
Then your value is stored in a new array and you delete the value of the original data array. After 50k you have to create a new one.
Easier way use array_chunk to split your array into parts.
https://secure.php.net/manual/en/function.array-chunk.php
There's non need for multiple variables. If you want to process your data in chunks, so that you don't fill up memory, reuse the same variable. The previous contents of the variable will be garbage collected when you reassign it.
$chunk_size = 50000;
$number_of_chunks = ceil($data_size/$chunk_size);
for ($i = 0; $i < $data_size; $i += $chunk_size) {
$new_array = array();
foreach ($j = $i * $chunk_size; $j < min($j + chunk_size, $data_size); $j++) {
$new_array[] = get_data_item($j);
}
}
$new_array[$i] serves the same purpose as your proposed $new_array$i.
You could do something like this:
$required_number_of_arrays = ceil(count($data)/50000);
for ($i = 1;$i <= $required_number_of_arrays;$i++) {
$array_name = "new_array_$i";
$$array_name = [];
foreach ($data as $val) {
${$array_name}[] = $val;
}
}
I have a piece of code that iterates over all the related profile records (HAS_MANY) of a team record.
It looks like this:
$team = Team::model()->findByPk(1);
$score = 0;
foreach ($team->profiles as $profile) {
$score += $profile->getScore();
}
Now I need to keep the $team variable, but because of the loop all the profiles will be kept in the profiles property, and use up a ton of memory.
Is there a way to safely clean this up?
I thought about setting profiles to null, but then it obviously remains null (and I don't know if another piece of code needs to access profiles later on)
Like I said, it seems to me you want to keep the $team variable and at the same time you don't, because it uses a lot of memory...
In that case I would unset them one by one:
for ($i=0;for ($i=0, $j = count($team->profiles); $i < $j ; ++$i ){
$score += $team->profiles[$i]->getScore();
unset($team->profiles[$i]);
}
// OR
foreach ($team->profiles as $key => $profile) {
$score += $profile->getScore();
unset($team->profiles[$key]);
}
And just get them from the database again if you need them. Or store them in some kind of temporary file. Don't think there is another way in my opinion.
When I try to get data from multiple collections code it is giving me data only from the first collection
i.e collections are project_0, project_1, project_2, project_3
for($i = 0; $i <= 3; $i++){
$dm->getClassMetadata('\Application\Document\Product')->setCollection('product_'. $i);
$record = $dm->getRepository('\Application\Document\Product')->findOneBy($condition);
print_r($record);
}
I tried to clear flush but noting is working. Please let me know the right way to do it?
Executing the code above will save the information only from the last collection in $record as you are overwriting the data in it with every iteration.
To fix it, you can create an array, let's say $records = array(); and then in each iteration you can do something like this:
array_push($records, $dm->getRepository('\Application\Document\Product')->findOneBy($condition));
After you're done, you'll have all the data in $records. I hope that helps.
Is there a better/shorter way to do this?
Each variable is a MySQL table value that is called. I have a main table and an override table, so call the first table, extract the resulting array, then call the override table and extract those results to override the first extract.
if (isset($Price1)){
$AllPrices[] = $Price1;}
if (isset($Price2)){
$AllPrices[] = $Price2;}
if (isset($Price3)){
$AllPrices[] = $Price3;}
if (isset($Price4)){
$AllPrices[] = $Price4;}
if (isset($SPrice1)){
$AllPrices[] = $SPrice1;}
if (isset($SPrice2)){
$AllPrices[] = $SPrice2;}
if (isset($SPrice3)){
$AllPrices[] = $SPrice3;}
I've done things like this in the past, but I wouldn't recommend it:
$variables = array("Price1", "Price2", "Price3", "Price4", "SPrice1", "SPrice2", "SPrice3");
$AllPrices = array();
foreach ($variables as $variable)
{
if (isset($$variable))
$AllPrices[] = $$variable;
}
See here for more information on how the $$ syntax works in PHP.
But I do agree with the comments to your post... You really should take another look at how you're getting this data. This solution is not ideal in the least.
You can also do like this:
for($i = 1; $i < 4; $i++){
$current = ${'AllPrices'.$i};
isset($current) && array_push($AllPrices, $current);
}
As also posted in above answer, using array of variable names is more efficient.
This structure is not recommended.
Instead of using $price1, $price2, ... use an array - $price[1], $price[2], ... (Do the same for $SPrice).
Then you could use a simple array_merge:
$AllPrices = array_merge($price, $SPrice);
I am having the worst time trying to get this to work. In the following code, I am gathering data from a database query and trying to build a muti-dimensional array object that will keep totals and tally up some information in a specific way. The problem is that instead of getting a value that is incrementing as it should, the value seems to be suffering from the last value it was assigned problem. Here is the code:
$REVIEWS = array();
$USER_REVIEWS = array();
$USER_IMGREVS = array();
pseudo-code: loop here which iterates over the DB results creating
$date - which is into this function as its called for each day of month
$p1user - which is one of the users (there are 3) 'levels' of users
$hr - is the hour which is built from the transaction's timestamp
$hr = date('H', $row['P1TIMESTAMP']);
$p1user = $row['P1USER'];
$REVIEWS[$date] += 1;
$USER_REVIEWS[$date][$p1user][$hr] += 1;
$USER_IMGREVS[$date][$p1user][$hr] += $row['F5'];
print "PASS1<br/>\n";
print "Value of Total Reviews: [".$REVIEWS[$date]."]<br/>\n";
print "Value of User Reviews: [".$USER_REVIEWS[$date][$p1user][$hr]."]<br/>\n";
print "Value of Reviewed Images: [".$USER_IMGREVS[$date][$p1user][$hr]."]<br/>\n";
print "<br/><br/>\n";
So - the 'total reviews' increments by one, as it should, for each time i print this. SO far so good. The next two arrays will only print the last values they were assigned, and will not be added together like they should. Why not? I have attempted to do this another way by literally creating the arrays one by one and assigning them in whole to the array containing them - but that also does not seem to work. Any insights?
i don't know how you initilize your array, maybe this will help:
// replace this 2 lines:
$USER_REVIEWS[$date][$p1user][$hr] += 1;
$USER_IMGREVS[$date][$p1user][$hr] += $row['F5'];
// with this code:
if (!isset($USER_REVIEWS[$date]))
$USER_REVIEWS[$date] = array();
if (!isset($USER_REVIEWS[$date][$p1user]))
$USER_REVIEWS[$date][$p1user] = array();
if (!isset($USER_REVIEWS[$date][$p1user][$hr]))
$USER_REVIEWS[$date][$p1user][$hr] = 0;
$USER_REVIEWS[$date][$p1user][$hr] += 1;
if (!isset($USER_IMGREVS[$date]))
$USER_IMGREVS[$date] = array();
if (!isset($USER_IMGREVS[$date][$p1user]))
$USER_IMGREVS[$date][$p1user] = array();
if (!isset($USER_IMGREVS[$date][$p1user][$hr]))
$USER_IMGREVS[$date][$p1user][$hr] = 0;
$USER_IMGREVS[$date][$p1user][$hr] += $row['F5'];
Sir, I dont understand very well why your coed is not working, but in my first test, I would change these lines:
$count = 1;
$USER_REVIEWS[$count][$p1user][$hr] += 1;
$USER_IMGREVS[$count][$p1user][$hr] += $row['F5'];
$count++;
Please, check if this code helps you anyway.
Your print statements for those values rely on the value of $p1user:
print "Value of User Reviews: [".$USER_REVIEWS[$date][$p1user][$hr]."]<br/>\n";
print "Value of Reviewed Images: [".$USER_IMGREVS[$date][$p1user][$hr]."]<br/>\n";
If you want to print it for all users you should loop over all possible users rather than just using $p1user. Either that or add them up if you want their sum.
Edit: Something that was bugging me was your data structure. It doesn't seem to represent your data very well. In your loop why don't you build up useful information that you store at the base of the review array?