Solved

Memoy usage issue with some loops

Posted on 2007-12-02
30
233 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
  • 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
 
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
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 500 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
 
LVL 20

Expert Comment

by:steelseth12
ID: 20397767
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

This article will explain how to display the first page of your Microsoft Word documents (e.g. .doc, .docx, etc...) as images in a web page programatically. I have scoured the web on a way to do this unsuccessfully. The goal is to produce something …
This article discusses how to create an extensible mechanism for linked drop downs.
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 and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

744 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now