views:

236

answers:

8

Basically I have articles in my database and I want to alter the way the first record displays. I want the lastest (Posted) article to be the focus and the older article just to list, (see F1.com). I need to know how to get the first of my values in the array and get it to display differently but I am not sure how to do this, I can do it so all rows display the same just not how to alter the first row. I also need to know how to tell the rest of the rows to display the same afterwards im guessing you use an if statement there and before that some kind of count for the rows.


Current code:

    $result = mysql_query("SELECT * FROM dbArticle WHERE userID='".$_SESSION["**"]."' ORDER BY timestamp DESC");

while($row = mysql_fetch_array($result))
  {
  echo "<h2 class=\"heading1\">". $row['title'] ."</h2>";
  echo "By:  ".$row['username']."  Type: ".$row['type']."  Posted: ".$row['timestamp']." 
  $body = $row['body'];
  echo "<br/><p>";
  echo substr("$body",0,260);
  echo "...<span class=\"tool\"><a class=\"blue\" href=\"index.php?pageContent=readArticle&id=".$row['id']."\">Read More</a></span></p><hr/>";
  }
mysql_close($con);


Ok I have taken Luke Dennis's code and tried to test it, but I am getting this error: Warning: Invalid argument supplied for foreach() this is the line of the foreach statment. Something that has just come to mind is that I will only want 5 or so of the older articles to display. This is what I have thats creating the error:

<? $con = mysql_connect("localhost","****","***");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

mysql_select_db("******", $con);

$result = mysql_query("SELECT * FROM dbArticle ORDER BY timestamp DESC");
$first = true;    
foreach($result as $row){
    if($first)
    {
        echo"".$row['title']."";
        echo"this is the headline";

        $first = false;
    }
    else
    {
        echo"".$row['title']."";

    }
}

?>

Do I need to add mysql_fetch_array somewhere to set the array up?

+8  A: 

I would just iterate through the results and apply a css class to the first entry:

$first = true;    
while ($row = mysql_fetch_assoc($result)) {
  $cssClass = '';
  if ($first) {
    $cssClass = 'highlight';
  }
  echo '<p class="' . $cssClass . '">' . $row['text'] . '</p>';
  $first = false;
}
Brian Fisher
Cheers Brian I had to alter the coding abit but it worked in the end. Cheers :D
Cool Hand Luke UK
+1  A: 

A simple if statement when looping through your results will usually do the trick. You can use a boolean to indicate if you've output the first row of results or now. If you haven't then give it a particular style and then set the boolean to true. Then all subsequent rows get a different style.

Jarod Elliott
A: 

I presume you have some code that loops through your resultset and prints them into the page? Could you paste this code in, and that might give us a starting point to help you.

Andy Hume
I've added my code.
Cool Hand Luke UK
+5  A: 

It's a bit crude, but I often hard-code a variable to designate the first run through a loop. So something like:

$first = true;
foreach($list_of_items as $item)
{
    if($first)
    {
        // Do some stuff

        $first = false;
    }
    else
    {
        // Do some other stuff
    }
}
Luke Dennis
I don't understand your varible $list_of_items is this what I need to rename to my sql results?
Cool Hand Luke UK
$list_of_items is just a generic varible he made to point out that the first varible is the list. you can name it what ever you want.
Jayrox
You may read: foreach($result as $row)
Pim Jager
+1  A: 

All of the above are correct. Luke Dennis' post is of course fleshed-out a bit more.

As Brian Fisher said, add some CSS styling to the first link when you encounter it per Luke's post.

I took a look at the article list on the F1 website. Pretty well constructed site - "One would expect that." :-)

Anyway, the article listings are contained within a two row table (summary="Latest Headlines") in descending order (newest first).

Just place a class in the second column (<td class="first-news-article">). Then add the class name and appropriate styling values in the css file - probably your' modules.css. There's already quite a few class values associated with articles in that file, so you may be able to just use an existing value.

That should be about it - other than actually doing it!

By the way, judging by the quality of the underlying html, I'm assuming there's already an "article list emitter." Just find that emitter and place the appropriate conditional to test for the first record.

Darrell

I just noted your code addition. I assume that you were showing the F1 site as an example. Anyway, I think you're on your way.

darrellblackhawk
I don't have a >50 rep yet, so here's my posting to your "limit to 5" question.SELECT * FROM dbArticle ORDER BY timestamp DESC limit 6This will take the newest article and up to 5 older articles
darrellblackhawk
A: 

The best way to do this is to put a fetch statement prior to the while loop.

Putting a test inside the while loop that is only true for one iteration can be a waste of time for a result of millions of rows.

Nerdling
for some reason i doubt this would even be an issue. besides a quick if($first === true) is... well... quick.
Jayrox
Well, if you have a million rows, that's one million "quick" tests. The point is that it does not scale well as that's a lot of CPU time wasted if things get into the real-world database realm.
Nerdling
If he has 1,000,000 rows, he's not cycling through them all to put them on a webpage. Worrying about optimizing THIS situation is a complete waste.
mabwi
He's doing a select * which could bring back the entire database (he has a user id as the only restriction, for which there might only be one user). Since this won't likely reduce the number of rows returned, I feel strongly that this should still be optimized.
Nerdling
In a practical application, the result *could* bring back a million rows - however a real page would paginate the results and the if test would be negligible.
Josh Smeaton
A: 

I'd use array_shift():

$result = mysql_fetch_assoc($resultFromSql); // <- edit
$first = array_shift($result);
echo '<h1>'.$first['title'].'</h1>';

foreach ($result as $row) {
  echo '<h2>'.$row['title'].'</h2>';
}
Henrik Paul
Hmm thats not working either, its showing these two errors:Warning: array_shift() [function.array-shift]: The argument should be an array in line with array_shift on. ANDWarning: Invalid argument supplied for foreach() in line with foreach on
Cool Hand Luke UK
You'd need to convert the SQL result into an array first, yes.
Henrik Paul
A: 

I don't know PHP, so I'll pseudocode it in Perl. I wouldn't do it like this:

my $row_num = 0;
for my $row ($query->next) {
    $row_num++;

    if( $row_num == 1 ) {
        ...format the first row...
    }
    else {
        ...format everything else...
    }
}

The if statement inside the loop unnecessarily clutters the loop logic. It's not a performance issue, it's a code readability and maintainability issue. That sort of thing just BEGS for a bug. Take advantage of the fact that it's the first thing in the array. It's two different things, do them in two different pieces of code.

my $first = $query->next;
...format $first...

for my $row ($query->next) {
    ...format the row...
}

Of course, you must make the first row stand out by using tags.

Schwern