[php] foreach lus resulteert in een warning

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
require("header.php");
?>

<h3>Een database verbinding opzetten en een query uitvoeren</h3>

<?php 
    require("base.php");
    //Leest SQL database gegevens in
    
    $dbh=mysql_connect("$dbhost","$dbuser","$dbpass");
    
    if(!$dbh) {
        echo "<br><br>";
        echo "<font color=\"#FF0000\"> ERROR ! Ik kan geen verbinding maken met de $db database.</font><br>\n";
        echo "</body></html>";
        exit;
    }

    $res = mysql_db_query("$db","select * from pem;",$dbh);
    $fout = mysql_errno($dbh);
    
    if (!$res) {
        $fout = mysql_error($dbh);
        echo "$fout";
        mysql_close($dbh);
        echo "</body></html>";
        exit;
    }

    //De waarden van de regels en velden vastleggen
    $aantal_lijnen=mysql_num_rows($res);
    $aantal_velden=mysql_num_fields($res);

    //BEGIN TABEL
    echo "<table border=2 celpadding=2 width=\"100%\">\n";

    //$aantal_velden & mysql_field_name voor header van tabel!
    
    for($i=0;$i<=$aantal_velden;$i++){
        printf("<th>%s</th>",mysql_field_name($res,$i));
    }
        
    for($i=0;$i<=$aantal_lijnen;$i++){
        $row = mysql_fetch_row($res);
        echo "<tr>";

        //foreach doorloopt elke waarde en plaatst deze in $col
        
        foreach($row as $col) {
            
            //De if kijkt of $col leeg is of niet. Zo ja, krijg hij de waarde &nbsp;
            if(!$col) {
                $col="&nbsp;";
            }
            echo "<td>$col</td>\n";
        }
        echo "</tr>\n";
    }

    //EINDE TABEL
    echo "</table>";

?>

<?php
require("footer.php");
?>


De error die ik krijg is: Warning: Invalid argument supplied for foreach() in e:\easyphp1-7\www\connect3.php on line 50

[ Voor 126% gewijzigd door Verwijderd op 06-03-2004 23:13 ]


Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 16-09 18:38
Zet es tussen [php] en [/php] tags?

$row zou een array moeten zijn... mysql_fetch_row geeft ook een array terug, en wel met nummers als indexen... dus $res is niet goed. :S Probeer anders eens
PHP:
1
2
for ($i = 0; $i <= count($row); $i++) {
$col = $row[$i];


Dubbelcheck je $res; vervang
PHP:
1
if ($fout != 0) //0 evaltueert tot false, dus... 

Door:
PHP:
1
if (!$res)

[ Voor 19% gewijzigd door Skaah op 06-03-2004 22:00 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
Returns an array that corresponds to the fetched row, or FALSE if there are no more rows.
Ik gok zo dat de laatste+1 call een boolean oplevert, wat uiteraard geen array is en dus ongeldig voor foreach ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Wat ACM zegt... klopt!

Er stond:
PHP:
1
for($i=0;$i<=$aantal_lijnen;$i++)


Aangezien de teller standaard op 0 begint mag de 'for' lus (i) niet op het aantal_lijnen +1 uitkomen! Dat is namelijk 1 te veel en dat veld bestaat dan niet.

De 'for' lussen moeten dus dit worden:

PHP:
1
for($i=0;$i<$aantal_lijnen;$i++)

[ Voor 21% gewijzigd door Verwijderd op 06-03-2004 23:33 ]


Acties:
  • 0 Henk 'm!

Verwijderd

In je for loop maak je geen gebruik van je teller variabele.
Compacter zou zijn:

PHP:
1
2
3
while($row = mysql_fetch_row($res)) {
 // hier de foreach loop
}


Zo gauw de rijen uit $res op zijn, geeft de volgende aanroep van mysql_fetch_row($res) false terug. Binnen deze lus is $row dus altijd een array. Scheelt weer een hoop tellen... :)

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Verwijderd schreef op 06 maart 2004 @ 21:04:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    //De waarden van de regels en velden vastleggen
    $aantal_lijnen=mysql_num_rows($res);
    $aantal_velden=mysql_num_fields($res);

    //$aantal_velden & mysql_field_name voor header van tabel!
    
    for($i=0;$i<=$aantal_velden;$i++){
        printf("<th>%s</th>",mysql_field_name($res,$i));
    }
        
    for($i=0;$i<=$aantal_lijnen;$i++){
        $row = mysql_fetch_row($res);
        echo "<tr>";

        //foreach doorloopt elke waarde en plaatst deze in $col
        
        foreach($row as $col) {
            
            //De if kijkt of $col leeg is of niet. Zo ja, krijg hij de waarde &nbsp;
            if(!$col) {
                $col="&nbsp;";
            }
            echo "<td>$col</td>\n";
        }
        echo "</tr>\n";
    }
Ik begrijp ook niet echt waarom je de variabelen $aantal_lijnen en $aantal_velden aanmaakt. Denk je echt dat for($i=0;$i<=$aantal_velden;$i++) overzichtelijker is dan for($i=0;$i<=mysql_num_fields($res);$i++). Ik vind dat niet echt een gerechtvaardig gebruik van een variabel.

Stel je leest de code en je komt zo'n variabel tegen. Dan moet je eerst terug in de code gaan spitten om zijn initialisatie op te zoeken waarna je pas zijn waarde weet. De tweede versie heeft als voordeel dat je het direct op de plek zelf ziet. En aangezien je de waarde maar 1 keer gebruikt is het vrijwel onnodig om daar een extra variabel voor aan te maken. Iedereen met een beetje php kennis die ziet direct wat je met zo'n regel bedoeld. En mocht een expressie zo groot worden dat het niet meer goed op 1 regel past, doe het dan lekker op 2 of meer. Dat neemt naar mijn mening echt niets van de overzichtelijkheid en netheid van de code weg (als je het goed doet althans).

Mischien ben ik een beetje zeikerig, maar het kan je toch wel redelijk wat regels code schelen in een groot project en daarmee ook overzichtelijkheid.

En wat infinyx zei, gebruik gewoon die while loop. Dat staat ook heel wat netter.

Edit:

En nog iets
PHP:
1
2
3
if(!$col) {
    $col="&nbsp;";
}

Hierbij doe je de lezer van de code vermoeden dat $col een bool is. En dat is het niet volgens mij. Gebruik liever de functie empty:
PHP:
1
2
3
if(empty($col)) {
    $col="&nbsp;";
}

Vind ik persoonlijk wat beter staan altijd.

[ Voor 13% gewijzigd door Michali op 07-03-2004 12:57 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
Michali schreef op 07 maart 2004 @ 12:51:
Ik begrijp ook niet echt waarom je de variabelen $aantal_lijnen en $aantal_velden aanmaakt. Denk je echt dat for($i=0;$i<=$aantal_velden;$i++) overzichtelijker is dan for($i=0;$i<=mysql_num_fields($res);$i++). Ik vind dat niet echt een gerechtvaardig gebruik van een variabel.
Als je een harde garantie wilt dat het hetzelfde getal is, dan zou ik toch echt een van te voren geinitialiseerde variabele gebruiken. Test deze code voor de gein maar es:
PHP:
1
2
3
4
5
6
$array = array(1);
for($i = 0; $i < count($array); $i++)
{
   echo $array[$i], ' ';
   $array[] = $i + 1;
}


Nou weet ik dat mysql_num_rows vast niet ineens een andere waarde teruggeeft, maar het is ook weer niet handig om per mogelijke operatie een ander type for te gebruiken, sowieso doe je dus een overbodige operatie per iteratie.
Stel je leest de code en je komt zo'n variabel tegen. Dan moet je eerst terug in de code gaan spitten om zijn initialisatie op te zoeken waarna je pas zijn waarde weet.
Meestal staat het bij zulk soort variabelen direct voor het gebruik en als je code goed in elkaar zit gebruik je zo veel mogelijk zaken uit de lokale scope, die bij goed gestructureerde code maximaal een of enkele schermgroottes is ;)
Iedereen met een beetje php kennis die ziet direct wat je met zo'n regel bedoeld.
De namen zijn zo duidelijk gekozen, dat iedereen met een beetje fantasie niet eens de initialisaties van die variabelen hoeft op te zoeken ;)
En mocht een expressie zo groot worden dat het niet meer goed op 1 regel past, doe het dan lekker op 2 of meer. Dat neemt naar mijn mening echt niets van de overzichtelijkheid en netheid van de code weg (als je het goed doet althans).
Imho boet je dan wel aan duidelijkheid in, een for met een variabele is lekker kort, met een statement erin is het al snel minder duidelijk, imho.
Vind ik persoonlijk wat beter staan altijd.
Ik denk dat dat nou het minst sterke argument voor het gebruik van empty is ;) Dat het vele malen beter uitdrukt wat er gebeurt (en je dus ook direct gaat bedenken of je wel of niet de complete empty-functionaliteit bedoelde) lijkt me een betere :P

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
ACM schreef op 07 maart 2004 @ 13:45:
[...]

Als je een harde garantie wilt dat het hetzelfde getal is, dan zou ik toch echt een van te voren geinitialiseerde variabele gebruiken. Test deze code voor de gein maar es:
PHP:
1
2
3
4
5
6
$array = array(1);
for($i = 0; $i < count($array); $i++)
{
   echo $array[$i], ' ';
   $array[] = $i + 1;
}


Nou weet ik dat mysql_num_rows vast niet ineens een andere waarde teruggeeft, maar het is ook weer niet handig om per mogelijke operatie een ander type for te gebruiken, sowieso doe je dus een overbodige operatie per iteratie.
Je hebt gelijk dat bij een constuctie als deze het dan wel mis loopt. Maar daar heb ik verder ook niets over gezegd. Ik denk ook dat het beter is om bij een uitgebreide functie aanroep de waarde even op te slaan in een lokale variabel. Maar volgens mij is iets als mysql_num_rows zo snel dat het niet veel uit zal maken. Niet dat ik het verder overigens gebruik, ik gebruik gewoon een simpele while loop om door de result set heen te lopen.
Meestal staat het bij zulk soort variabelen direct voor het gebruik en als je code goed in elkaar zit gebruik je zo veel mogelijk zaken uit de lokale scope, die bij goed gestructureerde code maximaal een of enkele schermgroottes is ;)

De namen zijn zo duidelijk gekozen, dat iedereen met een beetje fantasie niet eens de initialisaties van die variabelen hoeft op te zoeken ;)

Imho boet je dan wel aan duidelijkheid in, een for met een variabele is lekker kort, met een statement erin is het al snel minder duidelijk, imho.
Het hoeft ook niet te belachelijk te worden met statements in een loopje. Maar als je gewoon tijd neemt om de code te lezen dan vind ik zoiets even duidelijk naar mijn mening. Ik wil zelf toch altijd wel even checken welke waarde een variable toegewezen krijgt om er zeker van te zijn.
Ik denk dat dat nou het minst sterke argument voor het gebruik van empty is ;) Dat het vele malen beter uitdrukt wat er gebeurt (en je dus ook direct gaat bedenken of je wel of niet de complete empty-functionaliteit bedoelde) lijkt me een betere :P
Mijn argumenten zijn niet altijd even duidelijk maar goed. Ik bedoelde dus ook eigenlijk wat jij zei, maar dan meer op een impliciete manier. ;)

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dank voor de reply's...

Ben nog niet zo heel erg bedreven in het programmeren. Vandaar soms de kleine omwegen, om wel het resultaat te krijgen dat ik wil. :-)
Pagina: 1