while znotraj whila

primer kode:
query = mysqlquery ("bla bla bla");
while ($row = mysql
fetcharray($query))
{
query2 = mysql
query ("bla bla bla");
while ($row2 = mysqlfetcharray($query2))
{
print "nekaj";
}
print "nekaj";
}

bistvo je, da iz prvega query-ja vlečem neko novico, iz drugega pa želim dobiti komentarje te novice... problem je v tem, da mi prikaže le en komentar

zanima me, zakaj mi prvi while deluje pravilno in mi "printa" normalo, tako kot hočem... medtem ko mi drugi iz baze vrne samo zadnji vnos (po id-ju)

zanima me tudi, če je to normalno obnašanje, ali bi morala stvar izgledati drugače, pa imam jaz nekje v kodi napako...

vesel bi bil seveda kakšnega predloga za rešitev težave :)

22 odgovorov

hvala ti HeXeR

SlimDeluxe:

rnk:
Znotraj loopov se ne raje ne daje težkih IO operacij - kar query je. Nalovdaj podatke, ki jih rabiš z enim ali dvema poizvedbama in potem obdelaj dato.

Težkih? Če imaš pravilen design baze in ne izvajaš kompliciranih stikov med tabelami z dosti podatkov bi temu rekel vse prej kot težka IO operacija.

Let me rephrase. Znotraj loopov se ne daje poizvedb, ki šibajo na tak bottleneck kot je disk, če le ni treba (kar pa ponavadi ni).

1

Se strinjam, vendar se hkrati sprašujem, ali je bolje delati stik
novica x komentar
in imeti toliko večji rezultat v nenormalizirani obliki, kot pognati 10x query v smislu (pseudo koda):
result = select * from novica limit 10;
foreach(result as novica)
{
result2 = select * from novica where id = novica['id'] limit 10;
foreach(result2 as komentar)
{
novica['komentarji'][] = komentar;
}
}
Cool bi bilo, če bi dejansko imel nek benchmark (če bi se komu dalo narediti) :)
Čeprav če pomislim, zadeva je itak malo mimo, ker
1. za frontpage itak nikoli ne selectaš čisto vseh novic, glede komentarjev pa rabiš samo število (paginacija po komentarjih je ob ogledu novice).
2. uporabil bi object, db ali vsaj template caching

:)

Primer za izpis novic, komentarjev (1:n), kategorije (1:n) in avtorja (1:n).

  1. query: Select id-jev vseh novic, ki jih želimo izpisat (sem sodijo vsi pogoji, limiti, order by ...). Te id-je shraniš v spremenljivko.

  2. query: Select tistih parametrov, ki jih potrebujemo za izpis novice, dodan pogoj 'WHERE id_novice IN (rezultat 1. querya)' ter order by field. Tu prejmeš tudi recimo avtorja in kategorijo - uporabiš join.

  3. query: Select vseh komentarjev, order by field (link zgoraj).

V prvi zanki se nato sprehajaš čez rezultate 2. zahtevka, v drugi (notranji) zanki pa skozi rezultate 3. zahtevka dokler se ujemata id-ja novic. Vsi queriji so izvedeni zunaj zank, eden za drugim.

Če ne potrebuješ izpisa komentarjev, ampak samo število komentarjev, odstraniš prvi in zadnji zahtevek ter seveda notranjo zanko, v drugem zahtevku pa dodaš še join tabele komentarjev ter count. Najbolje pa bi bilo, da uporabljaš trigger (oziroma to rešiš programsko) ter tabeli novic dodaš atribut za število komentarjev, ki ga spreminjaš ob vnosu ali izbrisu komentarja.

1

hvala za te odgovore... zej me pa zanima kak bi pravo embed kodo (npr z youtuba) v print, oziroma spremenljivko...

$koda = $row['embed'];
print   $embed;

zej mi pač sam prenese kodo iz baze, ne znam pa videa prikazat na strani...

print $koda; in ne print $embed.

Priporočam echo $koda;, namesto print-a.

znas mogoce v par besedah razlozit bistveno razliko med print in echo
(malo off..)

mprose7, takole nekako je:

echo sprejme več parametrov, print le enega. print vrača vrednost (vedno 1), echo ne. Načeloma je echo hitrejši, ampak ne prav bistveno. Občutno hitrejši je echo le v primeru, če uporabljaš več parametrov, ker pri echo concatanje stringov ni potrebno, s print bi pa to moral početi. Še vedno se pa te razlike v praksi tako malo poznajo, da je uporaba echo/print bolj kot ne stvar okusa. :)

4

ja pač to je bla napaka v zapisu na forum... zanima me kako bi embed kodo dobil iz baze in potem prikazal video na strani (in pri tem seveda uporabljal while)