Log in

View Full Version : Index Being Recalculated



marain
11-05-2015, 12:26 AM
I define $menuLabelIndex and then use it as an index item in the (highly excerpted) array that then follows:


$lemma = rand (0, count($quotations) -1);
$menuLabelIndex = $lemma;
unset ($lemma);

$menuItems = array(
'Wire Fraud',
'Case Review',
'Super Links',

$quotations [$menuLabelIndex],

'Directions',
'Parking',
'PGP Public Key',
'The Bottom Line',
);

Later in the script, I loop through the $menuItems table on two different occasions. On the second occasion, [$menuLabelIndex] is recalculated, so that $quotations [$menuLabelIndex] yields a different result from the $quotations array than from the first looping. You can see the disparate results in the left-hand and bottom menus on any page of www.MarainLaw.com. (It's the entry towards the bottom of the menue that immediately follows the "Super Links" item.)

Is there a straightforward way to keep [$menuLabelIndex] from being recalculated?

A.

jscheuer1
05-27-2016, 01:11 PM
Is this the post you're talking about? If so, I would need to see the full code, or at least the fuller code. I would need enough to both run these two loops that you are talking about and in such a way that I could repeat the error/problem on a scratch page I could setup and run on wamp.

What exactly is the problem? Is it that you get a different random item each time? First time I got the same one. Second time I got two different ones.

I can tell you this, if you keep going:


$lemma = rand (0, count($quotations) -1);
$menuLabelIndex = $lemma;
unset ($lemma);

each time, the likelihood of getting a different result is high, because each time you do this, you potentially get a different random number.

marain
05-27-2016, 01:48 PM
That IS the post in question. I can provide the full code if you like, although it exceeds 500 lines. (A fair number of those lines are comments.) I could likely pare it down, although that would take a bit of time.

You have accurately discerned the problem: What I was attempting to do was to obtain an initial random number, save it, and use the saved random number the next time I wanted the element from the table. I initially did not believe the unset command was needed. But in trying to solve the problem, even using unset did not work. Rather than "Index Being Recalculated," this thread could perhaps been more accurately entitled, "Unset Not Working".

Regardless, this bepuzzlement is now predominately of academic interest since, upon reflection, I'm not too unhappy with what the code is actually doing.

A.


Is this the post you're talking about? If so, I would need to see the full code, or at least the fuller code. I would need enough to both run these two loops that you are talking about and in such a way that I could repeat the error/problem on a scratch page I could setup and run on wamp.

What exactly is the problem? Is it that you get a different random item each time? First time I got the same one. Second time I got two different ones.

I can tell you this, if you keep going:


$lemma = rand (0, count($quotations) -1);
$menuLabelIndex = $lemma;
unset ($lemma);

each time, the likelihood of getting a different result is high, because each time you do this, you potentially get a different random number.

DyDr
05-27-2016, 02:30 PM
The only way the index value would be recalculated during one execution/request of the script is if you are calling or including/requiring the posted section of code more than once, you have some other code that's modifying the value (perhaps a conditional test that's setting the value rather than comparing the value), you have a logic error or scope problem that's using a different value, you have code that always uses the first/last value, and a few more possibilities.

As already mentioned, it would take having enough of your code that reproduces the problem in order to specifically help you. There's no point in taking the time to paring down the code you post.

marain
05-27-2016, 02:53 PM
The only way the index value would be recalculated during one execution/request of the script is if you are calling or including/requiring the posted section of code more than once, you have some other code that's modifying the value (perhaps a conditional test that's setting the value rather than comparing the value), you have a logic error or scope problem that's using a different value, you have code that always uses the first/last value, and a few more possibilities.

As already mentioned, it would take having enough of your code that reproduces the problem in order to specifically help you. There's no point in taking the time to paring down the code you post.

I do not believe any of the situations you describe are happening, but I could be wrong. (I've been maintaining this code for years, but I was not its original author.) Hesitant to post a file of that size here, I've uploaded the full code to http://www.marainlaw.com/pageContent/menuCode.txt .

A.

DyDr
05-27-2016, 03:33 PM
Note, the second quotation is always the next entry in the array from the first quotation. The problem is due to this - $i++, on about line 358 in the posted code.

Almost all of this code will go away if you do two things -

1) Make a single array with the key being the current $menuLinks values and the value being the $menuItems values. You can then just use a foreach(){} loop to loop over the single array. This will make it easier to maintain the data since the key/values will be defined together.

2) You are currently building each line down the page, taking into account what may be on the left and right side of each line to control how the page is laid out. Use css to layout the page. The left-menu should be a div of content. The main-content should be a div of content. The bottom-menu should a div of content. Each section of content should be produced as an independent section.

jscheuer1
05-27-2016, 04:11 PM
Note, the second quotation is always the next entry in the array from the first quotation.

No, it is not. Sometimes it is the same, sometimes it is another one not anywhere near being next in the array.

jscheuer1
05-27-2016, 04:29 PM
OK, my diagnosis is that DyDr was right at first when he speculated: "you are calling or including/requiring the posted section of code more than once"

My reasoning is that I ran the code that you linked to and it only made one menu. In order for it to make two menus, it must be being used more than once, and that of course would make it be a different random number the next time.

jscheuer1
05-27-2016, 04:38 PM
That's it. The code is being used twice. Once for the side menu when $menuType is 'button' and once for the bottom menu when $menuType is not 'button'. So to 'fix' it you would have to generate $menuLabelIndex on the calling (including) page or script and do it just one time per page.

Or perhaps - but this may or may not work, may or may not have unintended consequences (works here in testing though):


$lemma = rand (0, count($quotations) -1);
$menuLabelIndex = isset($menuLabelIndex)? $menuLabelIndex : $lemma;
unset ($lemma);

BTW unsetting $lemma was never going to fix this. So of course unset is working fine.

DyDr
05-27-2016, 05:32 PM
Okay, so it's not always the next one now.

The supplied code cannot be producing the linked to web page. The supplied code is looping once. It is echoing a left-hand link syntax, followed by a bottom link, with | characters between items, in each pass through the loop. Even if the OP removed the end of the first loop/start of the next in the supplied code, the order of the left-hand links/bottom links in the output doesn't match the code.

In the view source of the output, the markup for the entire bottom menu, with the | separators, is first, followed by the markup for the left-hand link menu. The exact output and the order of the output cannot be different than when it was produced and sent to the browser.

I'm going to guess that the OP's real code is including this code twice, with some not-shown logic to control what it does, or there are actually two separate pieces of code, one for the left-menu and one for the bottom menu, and the random number code is producing two different numbers because it is running twice.

@OP, we cannot specifically help you with anything your code is doing when you don't supply accurate code.

Edit: I see there have been more posts while I was writing this. The $menuType value is 'button' for the links in both menus. See the class name in the view source in the links.

The only thing we can both tell is the code is being used twice and the OP is posting adulterated, time wasting, information.

jscheuer1
05-27-2016, 05:40 PM
This will probably fix it (as highlighted, also as explained in my previous post):


$lemma = rand (0, count($quotations) -1);
$menuLabelIndex = isset($menuLabelIndex)? $menuLabelIndex : $lemma;
unset ($lemma);

Otherwise, you will need to set it in the calling script (also as mentioned in my previous post).

marain
05-27-2016, 10:39 PM
John,

Your suggested code does indeed fix it. (As indicated in post #3, I'll now need to decide whether I want it to stay "fixed." Regardless, I thank both you and DyDr for your patience, and your efforts.) I'll keep http://www.marainlaw.com/pageContent/menuCode.txt up for a few days, in case anyone else wants to look at it. I also want to study the solution in more depth to get a fuller understanding. I will do that, but probably will not get to it this weekend.

jscheuer1
05-28-2016, 03:33 AM
It's not really that complicated, if in fact my suggestion worked without causing any additional problem(s), the most likely possible problem being that the random link would then become the same throughout an entire session, though I tend to doubt that's possible.

Assuming all is well, here's the explanation -

The code in menuCode.txt is run twice per page load. Once (presumably the first time, but that might not be crucial) with $menuType set as 'button'. That produces the left side menu. Then another time with $menuType not set as 'button' (but, a fine point admittedly but perhaps of note, presumably set to something), that produces the bottom menu. If we make sure to only set $menuLabelIndex one out of these two times (as my code suggestion virtually guarantees), then you will have the same random link in both iterations. And, as I say, the most likely complication would be if $menuLabelIndex somehow survives into subsequent page load(s) in the session. That's doubtful, but to know that for sure I would need to see more code and/or run the pages numerous times and see what happens after the change. Anyways, if that were to be the case (unintended persistence beyond a single page), then the random link would persist throughout a given user's session - presumably until they left the site, or perhaps until they closed their browser.

As I say though - that's unlikely. If the new code doesn't present any persistent problems like that in - say 5 experimental tries, it's most likely a non-issue.

All that said, and even if it works as desired without any issues, I understand how leaving it as it was might be preferable. After all, as it was before we started investigating this it produced 2 random links per page - which isn't the worst thing, might actually be making things more interesting than the consistency you originally sought.

Was just looking at the pages again, looks like it's working with no problems.

marain
05-28-2016, 01:56 PM
It works as desired with no discernible issues.

What befuddled me was that if the unset ($lemma); command is actually inside of a loop, it is not obvious--at least not obvious to me. It was for that reason that I dismissed DyDr's initial suggestion that the code was being executed more than once per page load. Turns out his (and your) analysis was correct. That is what I need to study in more depth. (That is likely to happen not soon.)

Regardless, y'all have pointed the way so that I can complete the analysis on my own. Now I just need to decide on whether or not to retain the consistency you helped me achieve.

A.

P.S. I am unfamiliar with DyDr's OP and @OP abbreviations, or acronyms.

styxlawyer
05-28-2016, 02:53 PM
.
.
.
P.S. I am unfamiliar with DyDr's OP and @OP abbreviations, or acronyms.

OP is a common forum acronym for Original Poster (the member who started the thread) and @OP is simply directing a comment to that member.

Hope that helps.

jscheuer1
05-28-2016, 04:11 PM
I setup a test page I named: menuitems_h.php - that I put the code from menuCode.txt in. I ran that, and it only made one menu. So it had to be running twice. So I made another page. I named it menuitems_1_h.php - and it I put just:


<?php
$menuType = 'button';
include 'menuitems_h.php';
$menuType = 'bob';
include 'menuitems_h.php';
?>

I did that because the type of menu (left side or bottom) that's made is controlled by whether or not $menuType is set to 'button'. (setting it to 'bob' the second time was arbitrary - it had to be something or else there would be an error, and it couldn't be 'button' or else it would make another side menu) So you can pretty easily find where the two places are that call the menu code by looking for instances of $menuType in the calling code (on the page above menuCode.txt).

Now, this (the way it is now) is pretty inefficient because the menu arrays are being defined twice. I would be tempted to do all that, including choosing the random item one level up, before calling menuCode.txt. That would also solve the problem. What I did simply ensures that the second time around, the initial random value is used instead of generating a new one. The more elegant solution would be to only have it happen once.

I think that - defining the menu arrays only once is the way to go even if you want it to be random again for the second menu. It would still be more efficient to only generate another random entry the second time around and insert it at the desired index in the $menuItems array (replacing the previous random one), rather than generate an entire new set of the 3 menu related arrays.

marain
05-28-2016, 04:49 PM
It would have taken me forever, or longer, to figure that out.

I vastly prefer elegance to inefficiency. In this case, that preference, of course, competes with "if it ain't broke, don't fix it." Perhaps I'll elegantize it at some point. For now, however, I've no more excuses to keep me from doing the other work I'd planned for the weekend.

Thanks again.

A.

DyDr
05-29-2016, 07:38 PM
"if it ain't broke, don't fix it."
A.

Speaking of which, there is a typo error in some of the repeated logic, that's causing different spacing between the categories in the menus. The code is outputting a <br> after the last item in each menu category. In one place it is incorrectly testing if a value is $menuLinks[$i] === 'pgp_key.php' in another place it is properly testing if a value is $menuLinks[$i] === 'pgp_key'

One point of good programming practice is to not repeat yourself. The only things that are logically different between the production of the two menus is the separator character between items (a <br> vs a |) and if the category heading is output. There should be one set of code to do this with logic only to handle the things that are different. This would eliminate duplicate coding, which would fix this particular problem, since the value being tested would only exist once in the code.

And, as already mentioned somewhere in this thread, you can eliminate most of this code by using a different data structure. By storing the menu items in an array of arrays, with the category name as the main array index, and the menu items as a sub-array under each category, you could simply loop over the main array, outputting the category heading when needed, then loop over each sub-array. You can simply handle the different separator character between items by storing each link in an array, then implode() that array with the separator character that currently being called for.