Page 1 of 1

Unsetting a var out of an array then using foreach

Posted: Wed Jan 21, 2004 8:08 am
by pinehead18
Ok, what i'm trying to do here is in the code i'm telling it to take 4 fields from the db. Put them into an array. Then i tell it that if one of those vars out of the array == default.gif unset that var.. Like unset $var[2] if it is set. or if var[4] is set unset it. Then i tell it with a foreach loop to display everything in $pics that is set. Again i hope that my if statement will unset everythin in $pics that == default.gif. I get a parse error on my ifstatement and it doens't seem to work. Any suggestions?

Code: Select all

<?php
$sql = "SELECT * FROM users WHERE user='$name'";
$result = mysql_query($sql,$con);
$row = mysql_fetch_array($result) or die(mysql_error());

        $mainpic = $row['mainpic'];

        $pic1 = $row['pic1'];
        $pic2 = $row['pic2'];
        $pic3 = $row['pic3'];
        $pic4 = $row['pic4'];

        $pics = array($pic1,$pic2,$pic3,$pic4);

        if ($pics[] == "default.gif") { unset($pics[]) }

foreach($pics as $picname)
{
$table .= "
<td align=center><a href=http://lifeinkc.com/viewimage.php?image=$picname&name=$name> <span style='text-decoration: none'><img
src=http://lifeinkc.com/pics/$picname height=80 width=80></a></span></td>
";
}

?>

Posted: Wed Jan 21, 2004 8:08 am
by pinehead18
btw thats my parse error
Fatal error: Cannot use [] for reading in / on line 46

Posted: Wed Jan 21, 2004 9:28 am
by McGruff
pinehead18 wrote:btw thats my parse error
Fatal error: Cannot use [] for reading in / on line 46

Code: Select all

$var[] = 44;
When adding a value to an array, a blank key just tells php to set the next numerical key - but this:

Code: Select all

$var[] == 'something'
..has no meaning: no array key has been specified for the comparison.

Also: in your code, the if statement needs to migrate south - inside the foreach loop.


I think it would be useful to split that code up into functions, here's an idea of what I mean:

Code: Select all

function fetchData($name, $con)
{ 
    $sql = "SELECT col1, col2, col3 [..etc] FROM users 
              WHERE user='$name'";

    $result = mysql_query($sql,$con);
    return mysql_fetch_array($result) or die(mysql_error());
}

function pruneList($list)
{
    foreach($list as $key=>$value)
    {
        if ($list[$key] == DEFAULT_GIF)  // define a config constant? 
        { 
            unset($list[$key]) 
        }
    }
    return $list;
}

function buildList($name, $con)
{
    $list = fetchData($name, $con)
    return pruneList($list);
}

function buildCell($picname, $name)
{
    $td = '<td align=center>';
    $td .= '<a href=http://lifeinkc.com/viewimage.php?image=' . $picname . '&name=' . $name . '>';
    $td .= '<span style="text-decoration: none">';
    $td .= '<img src=http://lifeinkc.com/pics/' . $picname . ' height=80 width=80>';
    $td .= '</a>';
    $td .= '</span>';
    $td .= '</td>';

    return $td;
}

function buildCells($list, $name)
{
    $cells = '';

    foreach($list as $value)
    {
        $cells .= buildCell($value, $name);
    }
    return $cells;
}

// in use:
$list = buildList($name, $con);
$cells = buildCells($list, $name);
Untested. Just a quick once over to give you an idea how it might be refactored.

Posted: Wed Jan 21, 2004 11:31 am
by pinehead18
what is the point of function buildCells($list, $name)
{
$cells = '';

foreach($list as $value)
{
$cells .= buildCell($value, $name);
}
return $cells;
}


?

Posted: Wed Jan 21, 2004 5:51 pm
by McGruff
The buildCells fn loops through the list, building part of the html for a table row - ie a bunch of cells. Are you wondering why there are now two foreach loops?

Splitting a chunk of code into discrete functions, each of which does just one thing, is helpful because it makes code more easy to read (choice of var & fn names is also important). Basically, it's like adding titles and chapters to a book: much easier to find what you're looking for and to figure out what it does.

It can also allow you to spot underlying patterns you might otherwise have missed. For example, I've made a point of separating the process of building a list (unformatted data) and applying formatting to the list. That's the kind of thing you might notice when refactoring away. Separating the model (ie data) & view is a fundamental principle in programming which prevents all kinds of awkward dependencies.

For example, suppose you are asked to provide a txt file as well as the html page? If the data and formatting are clearly separate that's relatively easy: you can apply whatever formatting you need to the bare data for output in any of a number of options. If instead you've got a tangled, spaghetti script it's much harder to do that. It's hard just to try to work out what the blasted thing does again never mind try to edit it.

Posted: Wed Jan 21, 2004 7:44 pm
by pinehead18
So with your script. When i go to place the code inside my talble which is inside of $output = "my page html";

i just call $list = buildList($name, $con);
$cells = buildCells($list, $name);

those?

Posted: Wed Jan 21, 2004 8:30 pm
by McGruff
Yes.

Previously I was trying to emphasise the difference between data and formatting but it might be slightly better to wrap it all up in a single "master" function (which makes calls to the other fns). I'd have to look at your whole script really to think how I'd try to fit everything together:

Code: Select all

<?php

// $name & misc fn defs have been defined earlier

// .. other code adding to $table ..

$table .= htmlCells($name, $con);

// .. other code adding to $table ..

?>
The underlying aim is to encapsulate discrete script tasks in their own little functions, and build on that. There's no "right" answer exactly except that the "chapters & titles" (functions) should clearly separate different tasks and make the script easy to read overall.

Very quickly this all leads to OOP & a further encapsulation of groups of functions in classes.