How to Build a Complex Web-Page from Dataset?

Below is a screen-shot of a web-page that is currently hard-coded, but which I am trying to make dynamic by hooking it up to MySQL on the back-end.

I have a rock-solid Data Model on the back-end, so there are no issues there.

What does seem to be the issue, is that it apparently is much harder - at least for me - to take all of that disparate data and merge it together with my HTML to build the web page!!

Last night I tried just grabbing the pertinent data for all Sub-Sections where Section = ‘Finance’ and Dimension = ‘Featured Finance’ into one large data set. But when I tried to figure out how to build each Sub-Section with the proper Featured Article and related Article Links, I got my butt kicked!!

Maybe using Arrays or Multi-Dimensional Arrays would make more sense?? :-/

Up to this point, I know that the way I build PHP pages is pretty crude. And it would be great to learn something more sophisticated like Model-View-Controller and OOP down the road. But for now, I realistically need to keep things simple, and try to solve this issue using Procedural Coding…

My “Section Landing Page” is one of the last things I need to complete to finish v2.0 of my website, but I am dreadfully stuck on this one, and could really use some help solving things!!! :bawling:

Sincerely,

Debbie

For a more simple approach couldn’t pages be setup to define page type at the top of the page, and then the page would be built based on these variables? Say you’ve got three main layouts, each with corresponding parts, header, body and foot sections. You could have a DB table that defines which of these layouts to use based on your categories or actual pages in directories, e.g. http://mysite.com/finance has index.php page with page-type variable defined as $pagestyle2. Based on this variable you would include header2, content2 and footer2 to build the page. As far as sub sections for menus, articles etc this idea of building an array based on the page called is sound. Not sure you need to build an array of every article name in your site and select by key which list to show, or just make list of appropriate articles based on the page. Just a thought.

Drummin,

Sorry, that doesn’t help answer my OP.

Debbie

Debbie:

Separate the layout from the data. The layout is a bunch of <div>s.

<body>
<div><?php echo $div1; ?></div>
<div><?php echo $div2; ?></div>
<div><?php echo $div3; ?></div>
<div><?php echo $div4; ?></div>
</body>

In the data section, fill all the variables with the pertinent data

I hear what you are saying, but please take a closer look at my screen-shot in the OP…

What makes things tricky, is that I have to find the “Sub-Sections” that apply to the current “Section”, and then loop through each one building the “Sub-Section boxes”, and then I also need to find all “Articles” which relate to a given “Sub-Section” and then include them.

Unfortunately, I can’t post my entire script here, but this is what I have so far…

  • At the top of my script, I run Query #1 to get a listing of Sub-Sections for the given Section.

Finance
Legal
Management

  • Beneath this, I added Query #2 which creates a listing of all Articles for the given Section. (That is, all “Sub-Sections” for the given “Section”.)

  • Then down in my HTML part, I have this code…


	<?php
		// Build Featured Sub-Sections.
		while (mysqli_stmt_fetch($stmt1)){
			echo "<div class='boxSubSection'>
					<h3>$subsectionName</h3>";

					// Build Featured Articles.
					while (mysqli_stmt_fetch($stmt2)){
						echo $articleSubsectionSlug . ', ' . $articleSlug . "<br />";
					}

			echo "</div>";
		}

The outside loop seems to be working fine, but where I left things off, is I just have a dump of all Articles for the given Section apeparing in my first Sub-Section box?

(I had hoped to put an IF-THEN-ELSE inside the Inner Loop, but when my WHILE LOOP is a “One-Trick Pony”, so that won’t work…)

Follow where I am stuck?

Normally, I am used to building my queries at the top of my script, and then usually looping through the ONE QUERY down in my HTML area to display the data.

But because this page is more complex, it seems like I need to run a SECOND QUERY down in my HTML nested inside the OUTER WHILE, because I can’t determine the SECOND QUERY until I know which Sub-Section is being built in the OUTER LOOP/FIRST QUERY if you follow me?!

Sincerely,

Debbie

P.S. I don’t know if I can do what I need to strictly with queries, or if this is a case where using Arrays would help??

I don’t know about anyone else, but I can’t even see it yet. I see “Attachments Pending Approval.”

Personally, I don’t even bother using SitePoint’s attachments anymore. It takes way too long to get approval. I’d suggest using a free image upload service – maybe imgur.com, for example.

Hi Debbie,
Although I can’t view you’re attached image (invalid file type) you did mention hard coded html, which is why I brought up including html parts, header etc based on page type being called. I do agree that building an array based on sub-categories would help with calling up correct content and page elements which was also a question you asked. As far as limiting results, the queries that build the array “Could” be limited to x amount of results. These can all be built above output and a simple foreach loop could display result in html.

That’s a bummer, because I have no way of knowing whether you can see it or not. (The minute I uploaded it, it looked like it was viewable to all?!)

Well, I think you guys definitely need to see my screen-shot in order to truly understand what I am doing and where I need help.

(Mods, please approve my screen-shot!!)

Sincerely,

Debbie

I see the screen shot now. Don’t see the difficulty in what you’re trying to do. You have a category shown with featured content and image and then links to four others under this category shown. An array would handle this. If using numeric keys, [0] would be the key to the featured article and [1] through [4] would be links.

I explained above where I am stuck… :frowning:

Sincerely,

Debbie

Can you build this array with a single query using left join to grab related articles? The loop might look something like this (not knowing variables used).

$Sections_array = array();
		while (mysqli_stmt_fetch($stmt1)){
			$Sections_array[$sectionName][$subsectionName]['Section_Name'][] = $sectionName;
			$Sections_array[$sectionName][$subsectionName]['SubSection_Name'][] = $subsectionName;
			$Sections_array[$sectionName][$subsectionName]['Section_Image'][] = $sectionImage;
			$Sections_array[$sectionName][$subsectionName]['Section_Content'][] = $sectionContent;
			$Sections_array[$sectionName][$subsectionName]['Section_Path'][] = $sectionPath;
		}

Hi Debbie,

I’d pull together all the data you need into an array at the top of your script, before you generate your HTML.
You’d build your data array something like this:


$subsections = array();

// First query results
while (mysqli_stmt_fetch($stmt1)) {
    $subsections[$subsectionId] = array(
        'name' => $subsectionName
    );
}

// Second query results
while (mysqli_stmt_fetch($stmt2)){
    $subsections[$subsectionId]['articles'] = array(
        'subsectionSlug' => $articleSubsectionSlug,
        'slug' => $articleSlug,
        'url'  => $articleUrl
    );
}

Then, when you generate your HTML, you can just loop through the arrays like this:


<?php foreach ($subsections as $subsection): ?>
<div class='boxSubSection'>
    <h3><?php echo $subsection['name'] ?></h3>";

    // Build Featured Articles.
    <?php foreach ($subsection['articles'] as $article): ?>
        <?php echo $article['subsectionSlug'] ?>, <?php echo $article['slug'] ?><br />";
    <?php endforeach; ?>

</div>
<?php endforeach; ?>

Edit:
I’d agree with Drummin, if you can use a JOIN to grab all the data you need in one query, that’s even better.

Why do I need to use arrays at all?

Is there some benefit to running a query, building an array, and then in essence having to run a 2nd query - on the array - to get the data that you had the 1st time?!

(Just asking.)

Then, when you generate your HTML, you can just loop through the arrays like this:


<?php foreach ($subsections as $subsection): ?>
<div class='boxSubSection'>
    <h3><?php echo $subsection['name'] ?></h3>";

    // Build Featured Articles.
    <?php foreach ($subsection['articles'] as $article): ?>
        <?php echo $article['subsectionSlug'] ?>, <?php echo $article['slug'] ?><br />";
    <?php endforeach; ?>

</div>
<?php endforeach; ?>

Except if you look at my screen-shot, it’s a little trickier than that, because I have to build what I am calling a “Featured Article” in the Sub-Section, plus a list of “Featured Article Links”…

Edit:
I’d agree with Drummin, if you can use a JOIN to grab all the data you need in one query, that’s even better.

I did add the Sub-Section to the beginning of my Article record-set, but it seemed to me like I needed two queries: One to define the Sub-Sections, and a second to define the Articles.

Sincerely,

Debbie

Hi Debbie,

Yeah I did have a good look at the screenshot you posted - my code was just an example to show you how you’d loop through the arrays to create your HTML. Obviously you’d have to tailor it to create the output you want, but the process is the same.

As for creating arrays of the data rather than building straight from the DB results, there are a couple reasons you might want to do it that way. If your second query is pulling in data for all the subsections, you’d need extra conditional logic to check which rows to output in which section, which makes the code harder to read as you’ve more php mixed in with your html. I also like to keep the the DB stuff separate from the HTML generation - it’s easier to read and maintain (especially as your app grows more complex and you add additional requirements), and it makes it easier in future to separate out your DB access into a separate file from your views (HTML).

To be honest, it would be easier to discuss this if you could tell us how your DB tables are set out, and what your queries look like - as we mentioned before, it might be possible to get all the data in one query.

So here are some snippets of what I have come up with so far…

(Things seem to be working, but it feels like maybe my code is still too loopy…) :-/

Code Flow:

  • First I start off grabbing the Section from the URL, and making sure it is valid.
  • Then I determine the SubSections associated with the Section in the URL, like this…

	$sectionSlug = $_GET['section'];
	$sectionName = getSectionName($dbc, $sectionSlug);
	$dimensionSlug = 'featured-' . $sectionSlug;

	// Build Featured Sub-Sections.

	// Build query.
	$q1 = "SELECT ss.slug, ss.name
			FROM section_dimension AS sd
			INNER JOIN dimension_subsection AS ds
			ON sd.dimension_slug = ds.dimension_slug
			INNER JOIN subsection AS ss
			ON ss.slug = ds.subsection_slug
			WHERE sd.section_slug = ?
			AND sd.dimension_slug = ?
			ORDER BY sd.section_slug, ss.sort";

	// Prepare statement.
	$stmt1 = mysqli_prepare($dbc, $q1);

	// Bind variable to query.
	mysqli_stmt_bind_param($stmt1, 'ss', $sectionSlug, $dimensionSlug);

	// Execute query.
	mysqli_stmt_execute($stmt1);

	// Store results.
	mysqli_stmt_store_result($stmt1);

	// Check # of Records Returned.
	if (mysqli_stmt_num_rows($stmt1)>0){
		// Featured Sub-Sections Found.

		// Bind result-set to variables.
		mysqli_stmt_bind_result($stmt1, $subsectionSlug, $subsectionName);

		// Fetch below in loop...

	}else{
		// Error-Handling
	}

  • Next I build a listing of ALL Articles for the given Section. This is where it seems like I need a 2nd Nested Query inside the WHILE which builds the SubSections…

	// Build Featured Articles.

	// Build query.
	$q2 = "SELECT ap.ds_subsection_slug, a.slug, a.heading, a.summary, a.image
			FROM article AS a
			INNER JOIN article_placement AS ap
			ON a.slug = ap.article_slug
			WHERE ap.sd_section_slug = ?
			AND ap.ds_dimension_slug = ?
			ORDER BY ap.ds_subsection_slug, RAND()";

	// Prepare statement.
	$stmt2 = mysqli_prepare($dbc, $q2);

	// Bind variable to query.
	mysqli_stmt_bind_param($stmt2, 'ss', $sectionSlug, $dimensionSlug);

	// Execute query.
	mysqli_stmt_execute($stmt2);

	// Store results.
	mysqli_stmt_store_result($stmt2);

	// Check # of Records Returned.
	if (mysqli_stmt_num_rows($stmt2)>0){
		// Featured Sub-Sections Found.

		// Bind result-set to variables.
		mysqli_stmt_bind_result($stmt2, $articleSubsectionSlug, $articleSlug, $articleHeading,
								$articleSummary, $articleImage);


		// Build Featured-Articles Array.
		$n=1;
		while (mysqli_stmt_fetch($stmt2)){
			$featuredArticlesArray[$n] = array('articleSubsectionSlug' => $articleSubsectionSlug,
										'articleSlug' => $articleSlug,
										'articleHeading' => $articleHeading,
										'articleSummary' => $articleSummary,
										'articleImage' => $articleImage);
			$n=$n+1;
		}//End of BUILD FEATURED-ARTICLE ARRAY

		// Fetch below in loop...

	}else{
		// Featured Sub-Sections Not Found.
	}

  • Finally down in the HTML area of my script, I have…

	<!-- FEATURED SUBSECTIONS -->
	<div id="boxFeaturedSubsections">
		<h2>Featured</h2>

		<?php
			// ********************************
			// Build Featured Sub-Sections.		*
			// ********************************
			while (mysqli_stmt_fetch($stmt1)){
				// Start of Sub-Section Box.
				echo "<div class='boxSubSection'>
						<h3>$subsectionName</h3>";

				// ****************************
				// Build Featured Articles.		*
				// ****************************
				$a = 1;
				foreach($featuredArticlesArray as $articleNo => $articleArray){

					// ********************************
					// Find Articles in Sub-Section.	*
					// ********************************
					if ($articleArray['articleSubsectionSlug'] == $subsectionSlug){
						// Match.
						if ($a == 1){
							// Build Featured-Article.
							echo "<div class='subFeatured'>
									<a href=''>
										{$articleArray['articleImage']}
										<h4>{$articleArray['articleHeading']}</h4>
									</a>
									{$articleArray['articleSummary']}
								</div>";

						}else{
							if ($a == 2){
								// Start of Featured-Links.
								echo "<div class='subArticles'>
										<ul>";
							}

							echo "			<li>
												<a href='/$sectionSlug/{$articleArray['articleSubsectionSlug']}/{$articleArray['articleSlug']}'>{$articleArray['articleHeading']}</a>
											</li>";
						}
						$a = $a + 1;

					}//End of FIND ARTICLES IN SUBSECTION

				}//End of BUILD FEATURED ARTICLES

				// End Featured-Links
				echo "				</ul>
										</div>";

				// End of Sub-Section Box.
				echo "</div>";

			}//End of BUILD FEATURED SUB-SECTIONS
		?>

Questions/Concerns:
1.) I’m not sure if I needed to use an Array above.

2.) The way I have it now, I query all of the Articles for a given Section and Dimension. While this number would likey be under 50, it seems like it would make more sense to do a query for each Sub-Section… (This is really what started this thread. Part of me wants to keep my Outer While loop, but inside of it, run a query based on the current Sub-Section in the loop. The logic being that I am only grabbing the Articles that apply to the current Sub-Section. Because this is a summary page, I don’t plan on having more than 5 Articles per Sub-Section box, because there will be a link like this “<< View all MARKET articles>>” at the bottom of each Sub-Section box. Still, I feel like I’m being sloppy here?!)

3.) It seems a little flaky how I had to add IF-THEN’s to handle the start of my HTML…

4.) It seems like my Array Variable names are rather LARGE in my HTML code…

5.) In general, it just seems like my code could be streamlined more. (Maybe not?!)

Hope you can follow my code snippets above, plus my comments/questions…

Sincerely,

Debbie

fretburner,

Glad to see you’re online! :slight_smile:

I just posted a fair amount of my code, so I hope that will make it easier to see what I have…

Yeah I did have a good look at the screenshot you posted

Good, because I think that screen-shot says it all.

As for creating arrays of the data rather than building straight from the DB results, there are a couple reasons you might want to do it that way. If your second query is pulling in data for all the subsections, you’d need extra conditional logic to check which rows to output in which section, which makes the code harder to read as you’ve more php mixed in with your html. I also like to keep the the DB stuff separate from the HTML generation - it’s easier to read and maintain (especially as your app grows more complex and you add additional requirements), and it makes it easier in future to separate out your DB access into a separate file from your views (HTML).

Two comments on this…

First, the way I did things, I think I could have accomplished the same end result with or without an array.

Second, I’m afraid I may have put more logic in the HTML section than you’d recommend. (Which, of course, is why I am here asking for help!!)

To be honest, it would be easier to discuss this if you could tell us how your DB tables are set out, and what your queries look like - as we mentioned before, it might be possible to get all the data in one query.

See if my last post helps answer your questions.

I could post an ERD here, but I am leery to do that, because I don’t want to get into a debate about my Data Model. (I spent nearly a month on it, and had it thoroughly checked be some data gurus, and it is not negotiable!!) :lol:

Suffice it to say, because I have an awesome Data Model, I can get any combination of data in ONE results-set, so that isn’t an issue.

I just broke things out into two queries, because that was the easiest for me to get my head around programmatically with manipulating things…

Hope that helps?!

Sincerely,

Debbie

I finally got to see your screen shot. Provided you keep your data and your layout well separated in your own mind (and in the code) there should be no difficulty building that page. Your issue is mapping the data in your tables to your output, section by section and sub-section by sub-section.

You build the output as includes or as variable at the top of the script and then merge them into the overall page. If a section has just one data-set it is easy to build it as an include. If it has multiple data-sets like the “Featured Article Links” then you need a loop. Arrays are not needed if you are clever in your SQL selects and make MySQL do the heavy lifting. Otherwise arrays are great for cleaning up the data before converting them to output. The while() loop is the equivalent of the foreach() loop. I’d work hard at getting the SQL selects just right (sorry, I have not looked at your code).

BTW, I’d query the database section by section and sub-section by sub-section, that’s the way to get MySQL to do all the heavy lifting.

Agreed!!

You build the output as includes or as variable at the top of the script and then merge them into the overall page. If a section has just one data-set it is easy to build it as an include. If it has multiple data-sets like the “Featured Article Links” then you need a loop.

If you get a chance, please look at my code just recently posted above, and let me know how I did?!

Arrays are not needed if you are clever in your SQL selects and make MySQL do the heavy lifting.

I agree.

Otherwise arrays are great for cleaning up the data before converting them to output. The while() loop is the equivalent of the foreach() loop. I’d work hard at getting the SQL selects just right (sorry, I have not looked at your code).

Again, if you have time to read over my code, I’d be curious how you all think I did…

BTW, I’d query the database section by section and sub-section by sub-section, that’s the way to get MySQL to do all the heavy lifting.

Well, this is where I was getting really confused, and so I ended up taking the approach that I did.

Query #1 finds all “SubSections” for the “Section” in the URL. (Simple enough.)

And ideally, I would run a second query off of each “SubSection” found in Query#1.

But the only place I can see where that works, is in my WHILE loop.

If I did that in the top-half of my script, I’d have no where to put that data?! :-/

And if I did that down in the bottom-half of my script, then it would really muck up my HTML.

So what I did - as a compromise - was to build Query #2, which contains all Articles for the given SECTION, and I appended the SUBSECTION as the first column, so that when I access the results of Query #2 in my array - which probably was NOT needed - then I have that first column to use as a “filtering device”.

Since this page is designed to highlight things, I will never have more than maybe 10 Articles per SubSection for a given Section. (So, the approach posted above is NOT expensive at all.)

However, wanting to be a “PHP Ninja” some day, I just don’t think I chose the most efficient way of doing things…

Make sense?

BTW, I know all of you are busy, but what I need the most help with is understanding how my code - found in Post #15 above - might be improved…

(What I posted above is working, but if I can make my code more efficient, then all the better!!)

Thanks,

Debbie

You put the output into variables. That’s what variables are for! :wink:

And if I did that down in the bottom-half of my script, then it would really muck up my HTML.

Right, don’t do that.

So what I did - as a compromise - was to build Query #2, which contains all Articles for the given SECTION, and I appended the SUBSECTION as the first column, so that when I access the results of Query #2 in my array - which probably was NOT needed - then I have that first column to use as a “filtering device”.

Since this page is designed to highlight things, I will never have more than maybe 10 Articles per SubSection for a given Section. (So, the approach posted above is NOT expensive at all.)

However, wanting to be a “PHP Ninja” some day, I just don’t think I chose the most efficient way of doing things…

Make sense?

I don’t know, sounds complicated. Let’s go back my original suggestion:

<body>
<div><?php echo $div1; ?></div>
<div><?php echo $div2; ?></div>
<div><?php echo $div3; ?></div>
<div><?php echo $div4; ?></div>
</body>

There you have the variables ($div1, $div2, $div3, $div4) that you need to build in the data section of the script. What could be easier?

BTW, I know all of you are busy, but what I need the most help with is understanding how my code - found in Post #15 above - might be improved…

I don’t particularly want to read the code for several reasons:

1.- You haven’t disclosed the table structure making it impossible to evaluate the sql
2.- I haven’t yet got to “prepared” statements, I’m currently working on class architectue. :wink:
3.- If and when you reorganize your page the code is likely to be different.

But I did look at it

// Build Featured-Articles Array. 
$n=1; 
while (mysqli_stmt_fetch($stmt2)) { 
    $featuredArticlesArray[$n] = array('articleSubsectionSlug' => $articleSubsectionSlug, 
                                       'articleSlug' => $articleSlug, 
                                       'articleHeading' => $articleHeading, 
                                       'articleSummary' => $articleSummary, 
                                       'articleImage' => $articleImage); 
    $n=$n+1; 
}//End of BUILD FEATURED-ARTICLE ARRAY 

You don’t need the $n=$n+1; The name C++ comes from the ++ operator. You could use

$featuredArticlesArray[$n++]

which would increment $n after it was used. ++$n would increment $n before it was used.

But you don’t need $n in the loop at all,

$featuredArticlesArray[]

would increment the key after each use. So far you have saved two statements ( $n=1; $n=$n+1; ). I’m not sure how much faster your code will run. :smiley:

BTW, you intialized $n with 1. Numeric arrays start with zero. I’m not sure how to explain this but bugs are most often found at the start and the end of loops and series that start with one (1) tend to have more bugs that series that start with zero (0). I know his from experience but I don’t have the mathematical explanation for it.

Hey Debbie,

The changes you posted looked good, and if it gets you the result you want then that’s great. I don’t really have much to add at this point, but one thing you could do that would make the HTML a little bit cleaner would be to build your article urls when you loop over the results of $stmt2, like this:


while (mysqli_stmt_fetch($stmt2)){
    $featuredArticlesArray[] = array(
        'articleSubsectionSlug' => $articleSubsectionSlug
        'articleHeading' => $articleHeading,
        'articleSummary' => $articleSummary,
        'articleImage' => $articleImage
        'articleUrl' => "/{$sectionSlug}/{$articleSubsectionSlug}/{$articleSlug}"
    );
}

Then your HTML link is just:


<a href="{$articleArray['articleUrl']}">{$articleArray['articleHeading']}</a>

It’s a bit easier to see what’s going on at a glance now.