Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Memoy usage issue with some loops

Posted on 2007-12-02
30
Medium Priority
?
256 Views
Last Modified: 2008-02-01
I am receiving an error whenever I run a certain loop. The error is this:

PHP Fatal error:  Allowed memory size of 16777216 bytes exhausted

The line that this error refers to contains a loop:

$a4=0;
$b4=0;
$c4=1;
$mincextstatus='no';
$firstrun='yes';

while ($mincsidstatus=='yes') //<------begin minclude extension loop
{

if ($firstrun=='yes')
{

$result9=mysql_query("SELECT * FROM services WHERE extensionof='$mincsid[$a4]'") or die(mysql_error());
$firstrun='no';

}

$row9=mysql_fetch_array($result9);
$mincextsid[$b4]=$row9['sid'];
$b4++;
$c4++;

if ($c4==sizeof($row9['sid']))
{

$a4++;
$c4=1;
$firstrun='yes';

}

if ($a4==sizeof($mincsid))
{

$mincsidstatus='no';

}

} //<------end minclude extension loop


This loop is designed to loop through all the results in the $mincsid array. This loop picks up all the the unique ID numbers of this main array. After that, this loop is run to check to see if any of those ID's is equal to an ID....

for ($a6=1;$a6<=$mincrunlength;$a6++) //<------begin minclude extension loop part 2
{

if ($sid==$mincextsid[$b6])
{

if ($amassages>=$clcapacity) //<------begin amassages>=clcapacity in primary sid extensions conditional
{

$extprice=number_format(($pupgrade*$clcapacity)*$extinterval,2);
$price='Price: $'.$extprice;

if ($mstanding=='late')
{

$lp=$lp.'<br><font style="color:#FF0000;">Your Membership payment is late. '.$custommmessage.'</font>';

}

elseif ($mstanding=='overdue')
{

$price='Price: $'.$row['price'];
$lp=$lp.'<br><font style="color:#FF0000;">Your Membership payment is overdue. '.$custommmessage.'</font>';

}

elseif ($mstanding=='good')
{

$lp=$lp.'<br>This service was successfully modified to suit your Membership.';

}


} //<------end amassages>=clcapacity in primary sid extensions conditional

elseif ($amassages<$clcapacity) //<------begin amassages<clcapacity in primary sid extensions conditional
{

$chargeup=$clcapacity-$amassages;
$extprice=number_format((($clcapacity*$dupgrade)*$extinterval)+($dfloorprice*$chargeup),2);
$price='Price: $'.$extprice;

if ($mstanding=='late')
{

$lp=$lp.'<br><font style="color:#FF0000;">Your Membership payment is late. '.$custommmessage.'</font>';

}

elseif ($mstanding=='overdue')
{

$price='Price: $'.$row['price'];
$lp=$lp.'<br><font style="color:#FF0000;">Your Membership payment is overdue. '.$custommmessage.'</font>';

}

elseif ($mstanding=='good')
{

$lp=$lp.'<br>This service was successfully modified to suit your Membership.';

}

} //<------end amassages<clcapacity in primary sid extensions conditional

}

$b6++;

} //<------end minclude extension loop part 2
0
Comment
Question by:jcbodyworks
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 9
  • 5
  • +2
30 Comments
 
LVL 36

Expert Comment

by:Loganathan Natarajan
ID: 20394287
what is the size of your php memory limit?
0
 
LVL 36

Expert Comment

by:Loganathan Natarajan
ID: 20394293
it might be there in php.ini ... just check it.,
0
 
LVL 21

Expert Comment

by:nizsmo
ID: 20394358
Look for this line in php.ini:
memory_limit

and change it to a bigger value, something like:
memory_limit = 250M
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 36

Expert Comment

by:Loganathan Natarajan
ID: 20394424
it is enough to have 24MB to 32MB ..
0
 
LVL 20

Expert Comment

by:steelseth12
ID: 20394452
You should really have a look at the loop ... not increase memory limit ... the only time i had to move memory limit up from 8Mb was when trying to resize really large image (2000x1500) pixels ... so you can imagine what is going on in the loop.

as a first step i would suggest echoing something to see which part of the loop gives you the problem.

i.e
$mincsidstatus='no';

}

} //<------end minclude extension loop

print "PART 1 ENDED";

etc ...
0
 

Author Comment

by:jcbodyworks
ID: 20394526
my php limit is 16 MB.
0
 
LVL 36

Expert Comment

by:Loganathan Natarajan
ID: 20394534
trying to increase 32MB... it should work., (don't forget to restart the apache)
0
 
LVL 20

Expert Comment

by:steelseth12
ID: 20394556
I used to play duke nukem with 16mb of ram. :P

ok now seriously try and fix the loop. Im at work at the moment so i cant spent too much time looking at it.
At a first glance i would suggest doing.

$result9=mysql_query("SELECT sid FROM services WHERE extensionof='$mincsid[$a4]'") or die(mysql_error());


while ($row9=mysql_fetch_array($result9)) {

$mincextsid[] = $row9['sid'];

}

$mincextsid = array_unique($mincextsid);


I will have a closer look once i get home.
0
 
LVL 20

Expert Comment

by:steelseth12
ID: 20394563
also change mysql_fetch_array to mysql_fetch_assoc in my example above.
0
 
LVL 17

Expert Comment

by:nplib
ID: 20396075
That error usually occurs when there is an infinite loop, in most some cases increasing the memory limit can be a resolution if in fact the loop is just taking up too much memory, in cases of an infinite loop, it will eventually take up all the available memory anyway.

I would check to make sure that this will eventually become true.
0
 
LVL 17

Expert Comment

by:nplib
ID: 20396080
if ($a4==sizeof($mincsid))
{

$mincsidstatus='no';

}
0
 

Author Comment

by:jcbodyworks
ID: 20396785
i was thinking it may have become an infinite loop. i noticed that the sizeof function really does not bring up sizeof($row9['sid'] . Should I do this another way?
0
 
LVL 20

Expert Comment

by:steelseth12
ID: 20396883
jcbodyworks please give  the code below a try
$mincsid_str = implode(",",$mincsid);
 
$result9 = mysql_query("SELECT sid FROM services WHERE extensionof IN (".$mincsid_str.") GROUP BY sid") or die(mysql_error());
 
while($row9 = mysql_fetch_assoc($result9)) {
 
	$mincextsid[]=$row9['sid'];
 
}	

Open in new window

0
 
LVL 17

Expert Comment

by:nplib
ID: 20396891
sizeof() gives you the number of elements in an array,

what are you wanting from the $mincsid variable?
0
 

Author Comment

by:jcbodyworks
ID: 20397160
while ($mincsidstatus=='no') //<------begin minclude extension loop
{

if ($firstrun=='yes')
{

$result9=mysql_query("SELECT sid,duration FROM services WHERE extensionof='$mincsid[$a4]'") or die(mysql_error());
$firstrun='no';

}

$row9=mysql_fetch_array($result9);

$mincdurrt[$b4]=$mincdurr344[$e4];
$mincextsid[$b4]=$row9['sid'];
$mincextdur[$b4]=$row9['duration'];
$b4++;
$c4++;
$d4++;

if ($d4==sizeof($result9))
{

$a4++;
$c4=1;
$d4=0;
$e4++;
$firstrun='yes';

}

if ($a4==sizeof($mincsid))
{

$mincsidstatus='yes';
$firstrun='no';

}

} //<------end minclude extension loop


Here is the version of the loop I have so far, and I will explain my reason behind it. Before this loop, an array named $mincsid is produced, looking for all services that have the minclude attribute attached to them. The only filter is that the minclude cannot be equivalent to the SID of the Membership's Primary SID. The SID is a unique auto_incrememed ID number for each service. Each membership is bound by a Primary SID, which applies a special price to that Primary SID, but also to any service with an minclude attribute.

After all the minclude attributes are sought after, it checks to see if any of those SID's are the current SID that was pulled up. The idea is that when a person clicks on a service, that it would automatically run a check on the database. These are the checks performed:

1. To see if the service is the primary SID of the Membership
2. To see if the service is a branch of the Primary SID (every service has an 'extensionof' attribute, where the main root of the service is tied into the service. An example would be the Hour and a Half service being an extension of the hour service. Thus, the hour and a half service would have the hour's sid in its extensionof column.
3. Check to see if the service is an minclude service. The minclude services receive treatment as if they were the Primary SID of the service, but must be run seperately to insure that the Primary SID is always prioritized over minclude searches.
4. Check to see if the service is an extension of the minclude service. Pretty much the same as the extension of the Primary SID, the extensions of the minclude are about the same. An example of this would be the Couple's Hour and half massage is an extension of the couple's hour massage. the couple's hour massage has an minclude attribute of yes.

I need to be able to modify the above loop to the amount of results pulled. Lets say for example the first minclude pulls above 2 results, then the second minclude pulls up 4....I need this loop to run 2 times with the first minclude results, sticking them into a variable that is always increading, namely $mincextsid and
$mincextdur (which contain the SID and duration), then move on to minclude number 2, run that search, and run according to the results of that search. Once all possible results have been scanned, I need the loop to stop of course. I was hoping to accomplish this with the sizeof() function, but Im afraid its not working properly. hope this helps!
0
 
LVL 17

Expert Comment

by:nplib
ID: 20397196
before your loop add this

echo sizeof($mincsid);

and see what the results are,
make sure your array is being populated properly.
0
 

Author Comment

by:jcbodyworks
ID: 20397223
I should thought of something....since the $mincsid variable is an array, should I just try to create 1 search query depending on that array. I have an instance of that with a previous function I did:

elseif (sizeof($attachers)>1)
{

$aquery='SELECT * FROM services WHERE location="'.$loid.'" and (form="'.$attachers[0].'"';
$runlength4=sizeof($attachers)-1;
$aa=1;

for ($iii=1;$iii<=$runlength4;$iii++)
{

$aquery=$aquery.' or form="'.$attachers[$aa].'"';
$aa++;

}

$aquery=$aquery.')';
$result2=mysql_query("$aquery") or die(mysql_error());

}

With this loop, I produce all the in between filters in the search.
0
 

Author Comment

by:jcbodyworks
ID: 20397231
the size of $mincsid is 1, which is correctly. there is only 1 minclude in the phoenix location.
0
 
LVL 17

Expert Comment

by:nplib
ID: 20397275
see if it became true;
cause it should. by the logic given.
and since it's value is 1, then it should only take 1 pass for the loop to end.
if ($a4==sizeof($mincsid))
{
echo "true";
$mincsidstatus='yes';
$firstrun='no';

}
0
 

Author Comment

by:jcbodyworks
ID: 20397307
the first run works like a charm. however, when this loop starts running multiple times, it malfunctions. The only way this loop would run more than once if either or both of these is true:

1. The $mincsid has more than 1 result.
2. The result of the $mincsid search has more than 1 result.

Like I said, although the $mincsid has 1 value, this loop needs to run not so much according to the value $mincsid, but according to the amount of results pulled up from $mincsid. In this case, there are 2 extensions of this minclude in the phoenix location. This loop is not pulling up the second result of that search.
0
 
LVL 20

Expert Comment

by:steelseth12
ID: 20397355
Ok ... just to make things clear ...
Te result of the loop ... should be all unique sid from table services that have extensionof = to some value in the $mincsid array ? or something else ?
0
 

Author Comment

by:jcbodyworks
ID: 20397389
yes. all the results have a unique ID, so there would be no possibility of a duplicate.
0
 

Author Comment

by:jcbodyworks
ID: 20397409
so technically speaking, 1 minclude should pop up, which is the couple's hour massage. if the selected SID is not equal to that, then the next search is run. the array should search in the extensionof column to see if any services has the SID of the couple's hour massage in their extensionof column. This search should pull up 2 results...the hour and half couple's massage, and the two hour couple's massage...each with a unique SID. then afterwards I do a check to see if any of those is equal to the selected SID. do u get the drift now? Thanks.
0
 
LVL 20

Expert Comment

by:steelseth12
ID: 20397425
this line will create a comma separated value for array $mincsid
$mincsid_str = implode(",",$mincsid);

23,45,56 etc

since you say its a unique id then we dont need GROUP BY sid

then the query below would select all sid  values from table services that have extensionof = to a value in $mincsid array.

$result9 = mysql_query("SELECT sid FROM services WHERE extensionof IN (".$mincsid_str.") ") or die(mysql_error());

what im i missing ???
0
 

Author Comment

by:jcbodyworks
ID: 20397427
I know, it seems confusing, even after I read what I wrote, lol. Its hard to explain, but I know the concept works, because it worked on the extensions of the Primary SID. I just have to get the loops correctly aligned for this. Obviously, with the search on the extensions of the primary SID, it was easy because there is always only 1 primary SID, but here, I have to be prepared to handle multiple minclude services and all the extensions thereafter.
0
 
LVL 20

Expert Comment

by:steelseth12
ID: 20397569
can you post the latest version of your script ...
0
 

Author Comment

by:jcbodyworks
ID: 20397699
YAY, i got it to work. here is the script:

$aquery='SELECT sid,duration,extensionof FROM services WHERE extensionof="'.$mincsid[0].'"';
$runlength4=sizeof($mincsid);
$aa=1;

for ($iii=1;$iii<$runlength4;$iii++)
{

$aquery=$aquery.' or extensionof="'.$mincsid[$aa].'"';
$aa++;

}

$aquery=$aquery.'';
$result9=mysql_query("$aquery") or die(mysql_error());
$b4=0;

while ($row9=mysql_fetch_array($result9)) //<------begin minclude extension loop
{

$mincextsid[$b4]=$row9['sid'];
$mincextdur[$b4]=$row9['duration'];
$mincextext2[$b4]=$row9['extensionof'];
$b4++;

} //<------end minclude extension loop

It works perfect. obviously theres more to it than this before and after it, but i hope u get the idea of how this works. thanks for the suggestions guys!
0
 
LVL 20

Accepted Solution

by:
steelseth12 earned 2000 total points
ID: 20397729
You are basically adding or  extensionof="'.$mincsid[$aa].'"' or  extensionof="'.$mincsid[$aa].'"' etc to the query ...

Thats what

$mincsid_str = implode(",",$mincsid);
 
$result9 = mysql_query("SELECT sid FROM services WHERE extensionof IN (".$mincsid_str.") ") or die(mysql_error());
 
while($row9 = mysql_fetch_assoc($result9)) {
 
        $mincextsid[]=$row9['sid'];
 
}  

would do .. only the IN statement is alot faster than the OR statement.

0
 

Author Comment

by:jcbodyworks
ID: 20397736
Well, i dont know who to give the points to since you all were very helpful, but here, the first person to give me a tip on what I can do better next time will get all the points. thanks guys and there will be plenty more questions from me to come!
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
This article discusses four methods for overlaying images in a container on a web page
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

670 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question