[PHP] Telefoonboek index maken zonder 2x query

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • om3ega
  • Registratie: Maart 2001
  • Laatst online: 00:11
Voor een website wil ik in PHP een telefoonboek weergeven. Zeg even dat hier 500 namen in staan. Maar niet alle letters van het alfabet zijn vertegenwoordigd.

Bovenaan het telefoonboek heb ik een rijtje [A] [B] [C] [D] etc.. met ankers in de code zodat je direct naar de juiste letter springt.

Dit werkt allemaal prima , maar .... Wat ik eigenlijk zou willen is dat wanneer een letter niet vertegenwoordigd is , de index ( [A] [B] [C] ) geen hyperlink is.

Snelheid van de page is belangrijk.

Wat is nu mijn uitdaging ?

Ik voer 1 malig de query uit. Hierin krijg ik het totale telefoonboek wat ik opbouw in een table.
Wat ik dus zou moeten kunnen zien (zonder de resultaten te fetchen , want dan moet ik de query nogmaals uitvoeren toch?) is of de achternamen met A , B , C etc aanwezig zijn.
Dit moet gebeuren voordat ik de resultaten echt fetch en ze in de tabel zet.

Hoe kan ik zoiets het beste aanpakken? Of moet ik toch maar 2x de query draaien?

Was dit een beetje duidelijk zo? :)

Acties:
  • 0 Henk 'm!

  • RupS
  • Registratie: Februari 2001
  • Laatst online: 17-07 14:45
Je hebt met twee verschillende recordsets te maken, dus het is lastig om dat in 1 query te duwen lijkt me.
Maar als het een betrekkelijk eenvoudige select is, dan zou ik er gewoon een extra query voor uitvoeren.
Ik gok dat je MySQL gebruikt? Het is een extra belasting (m.i. te verwaarlozen), maar ik denk dat het een extra simpele select sneller is dan een samengestelde query bouwen of iets dergelijks...

Een andere optie (niet heel erg netjes, en JavsScript afhankelijk) is de anchors pas schrijven in een div, nadat je tabel is opgebouwd, je weet dan namelijk al welke letters je bent tegengekomen...

[edit]
stukje code: :)
PHP:
1
2
3
4
5
6
7
$letters = array();
while ($record = mysql_fetch_array()) {
  // bouw tabel op
  $letter = substr($record['naam'],0,1);
  if (!in_array($letter,$letters)) 
    array_push($letters,$letter);
}

[ Voor 21% gewijzigd door RupS op 25-02-2005 08:32 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Heb zelf ook eens zoiets gemaakt:

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
function show_alfabet($table, $columns, $pageID)
{
    require('./includes/config.php');
    $used_letters = array();
    if (!$sql = mysql_query("SELECT " . $columns . " FROM " . $table . ""))
    {
        echo 'Regel: <b>' . __LINE__.'</b>, Query mislukt: ' . mysql_error();
    }
    else
    {
        $aantal = mysql_num_rows($sql);
        while ($result = mysql_fetch_assoc($sql))
        {
            $key = array_keys($result);
            $first = substr($result[$key[1]], 0, 1);
            $cap = strtoupper($first);
            $used_letters[] = $cap;
        } 
        $alfabet = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
        foreach($alfabet as $key)
        {
            if (in_array($key, $used_letters))
            {
                if ($key == $_GET['letter'])
                {
                    echo "<span style=\"color: #B63025; font-weight: bold\">" . $key . "</span>&nbsp;";
                }
                else
                {
                    echo "<a href=" . $_SERVER['PHP_SELF'] . "?page=" . $_GET['page']  . "&pageID=" . $pageID . "&letter=" . $key . ">" . $key . "</a>&nbsp;";
                }
            }
            else
            {
                echo $key . '&nbsp;';
            }
        }
    }
}


wellicht heb je er wat aan...

[ Voor 26% gewijzigd door Verwijderd op 25-02-2005 08:26 ]


Acties:
  • 0 Henk 'm!

  • om3ega
  • Registratie: Maart 2001
  • Laatst online: 00:11
De javascript oplossing vind ik nog niet eens zo gek idee :) .. nog niet aan gedacht.

Daar ga ik eens mee spelen :)

Acties:
  • 0 Henk 'm!

Verwijderd

Of creatief zijn; niet mijn stijl overigens:

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
    // connect     
    mysql_connect('???', '???', '???');
    mysql_select_db('???');

    // query
    $query = "SELECT naam, SUBSTRING(naam,1,1) AS first_letter FROM tabelnaam ORDER BY naam ASC";
    $result = mysql_query($query) or die(mysql_error());

    // letters
    $nameHolder = '';
    $curRow = 0;
    $totalRows = mysql_num_rows($result);
    while(list($naam, $first_letter) = mysql_fetch_row($result))
    {

        // save current name in holder
        $nameHolder .= '<br>' . $naam;
        
        // show first letter as link
        echo '[' . $first_letter . '] - ';

        // update curRow
        $curRow++;

        // show names if this is the last loop walk-trough
        if($totalRows == $curRow)
        {

            echo $nameHolder;

        }

    }

Acties:
  • 0 Henk 'm!

  • om3ega
  • Registratie: Maart 2001
  • Laatst online: 00:11
Hmm , dat is ook een goeie.. dat scheelt je ook 2 query's maken.. eens even proberen :) tnx allemaal.. Er zijn veel wegen naar Rome :)

Acties:
  • 0 Henk 'm!

  • Dennis
  • Registratie: Februari 2001
  • Nu online
SQL UNION kun je ook gebruiken, maar of MySQL dat ondersteunt :).

Acties:
  • 0 Henk 'm!

  • Yo-han
  • Registratie: December 2001
  • Laatst online: 18-08 20:16

Yo-han

nope.

Dennis schreef op vrijdag 25 februari 2005 @ 10:47:
SQL UNION kun je ook gebruiken, maar of MySQL dat ondersteunt :).
Vanaf MySQL versie 4.nogwat wordt union idd ondersteund en zou een goeie optie zijn om het geheel met 1 query op te lossen.

edit:

Union wordt ondersteund vanaf 4.0.0, zie voor meer info http://dev.mysql.com/doc/mysql/en/union.html

[ Voor 23% gewijzigd door Yo-han op 25-02-2005 10:52 ]


Acties:
  • 0 Henk 'm!

  • pietje63
  • Registratie: Juli 2001
  • Laatst online: 21:10

pietje63

RTFM

Wat je ook kunt doen beetje vergelijkbaar met ivy's oplossing is dus de letters er gelijk uithalen met de overige data, alles nog in arrays zetten (zowel de data van de eerste letter als de data als de andere data, en daarna pas de pagina layout technisch opbouwen. Je moet voor de eerste letter data echter wel wat extra php trucjes doene (array uniek of heet het ook al weer?) dus of je pagina er veel sneller van wordt?

Wat je ook nog kan doen als "slechte html constructie" is het volgende
code:
1
2
3
4
5
6
7
8
<table>
  <tr>
  lijst met letters
    <td>
    hier de rest van het telefoonboek
    </td>
  </tr>
<table>

Doordat de lijst van de letters niet in een cel van de tabel valt wordt deze (iig door internet explorer, bij andere browsers weet ik het even niet) helemaal bovenaan in de tabel getoond. Op deze manier kun je het met een trucje dus ook in 1 query doen.

ps. is dit een opdracht voor school of lijkt dat maar? Zo ja dan zal ik niet met mijn 2e oplossing komen want die is redelijk dirty

[ Voor 12% gewijzigd door pietje63 op 25-02-2005 11:53 . Reden: code tags ipv html ]

De grootste Nederlandstalige database met informatie over computers met zoekfunctie!!


Acties:
  • 0 Henk 'm!

  • om3ega
  • Registratie: Maart 2001
  • Laatst online: 00:11
Nee ik zit al een aantal jaartjes niet meer op school ;) .. Het is voor een intranet site.
Ik ga bovenstaande uitwerkingen proberen. Momenteel werk ik met 2 queries.. het gaat redelijk snel , maar het zit me niet lekker dat ik 2 querys moet gebruiken als mijn gevoel zegt dat ik alle data eigenlijk al heb :)

Dus ik denk dat ik er dankzij jullie hulp wel uitkom :)
Pagina: 1