Hei ohjelmointiputkan väki,
Minulla on seuraavanlainen kysymys:
Skriptini pohjautuu tähän: Käyttäjät Online (PHP), paitsi IP on käyttäjän nimi
Miten saan ylimääräiset merkinnät pois tulostuksesta, kun tulostan käyttäjät online kautta aikojen seuraavanlaisesti:
foreach(@file("kaytt_paikalla.txt") as $onlines){ $online=explode("|",$onlines); echo'<tr><td>'.date("d.m.Y H:i",$online[1]).'</td><td>'.$online[0].'</td></tr>'; }
eli nyt näkyy näin:
21.09.2008 12:25 jessenic
21.09.2008 12:32 jessenic
21.09.2008 12:38 jessenic
21.09.2008 12:43 jessenic
ja pitäisi näkyä:
21.09.2008 12:25-12:43 jessenic
Onpas vanhentunutta koodia tuo vinkki.
Riippuu vähän siitä, miten haluat tulkita noita tietoja. Joitain kysymyksiä, mitä itellä heräsi:
-Miten määrität käyttäjän sisälläoloajan? Näetkö jostain, milloin käyttäjä on poistunut sivustolta?
-Entäpä jos päivä vaihtuu, näytetäänkö 21.09.2008 12:53 - 22.09 08:00
?
Kyse on siis datan parsimisesta. Jotain tällaista, mutta tämä ei vielä ota yllä esitettyjä kysymyksiä huomioon mitenkään ja antaakin useissa tapauksissa virheellisiä tuloksia:
<?php /* Muuttujat datan parsintaan ja järjestelyyn */ $raw_data = array(); $online_data = array(); /* Online-tietojen haku kera virheenkäsittelyn */ try { $raw_data = @file( 'kaytt_paikalla.txt' ); if ( $raw_data === false ) { throw new Exception( 'File not found' ); } } catch ( Exception $e ) { echo "Can't parse online data"; } /* Parsitaan ja järjestellään tiedot */ foreach ( $raw_data as $line ) { @list( $name, $time ) = @explode( '|', $line, 2 ); if ( !isset( $online_data[ $name ] ) ) { $online_data[ $name ] = array(); } $online_data[ $name ][] = (int)( rtrim( $time ) ); } ?> <html> <head> <title>Testi</title> </head> <body> <div> <table> <?php foreach ( $online_data as $name => $times ): sort( $times ); ?> <tr> <td><?php echo date( "d.m.Y H:i", reset( $times ) ); ?> - <?php echo date( "H:i", end( $times ) ); ?></td> <td><?php echo $name; ?></td> </tr> <?php endforeach; ?> </table> </div> </body> </html>
Sori, olen huono selittämään mutta seuraavalla tavalla:
jos tiedostossa on peräkkäin monta samaa käyttäjää, niihin tulee viiva väliin
ja jos päivä vaihtuu siinä välissä, niin sitten näin:
21.09.2008 12:25-12:43 jessenic
22.09.2008 10:00-10:05 jessenic
Eli jos välissä on joku muu käyttäjä, niin näin:
21.09.2008 12:25-12:32 jessenic
21.09.2008 12:32-12:33 jokumuu
21.09.2008 12:38-12:43 jessenic
Kah, sitten pääset muokkaamaan tuota järjestelyä foreach-silmukassa. Sinne jotain, joka järjestelee datan päivien mukaan, eli vaikkapa: Käytä päiviä avaimina taulukkoon x
, joka sisältää päivän kirjautumistiedot. Sieltä sitten poimit käyttäjien online-aikoja. Tähän kun täydentelee niin näyttää jo joltakin:
<?php /* * Lisäys edelliseen koodiin: * Muuttuja, jolla pidetään lukua * avoinna olevista lopetusajoista */ $undetermined_endtimes = array(); //--snip-- /* Parsitaan ja järjestellään tiedot */ foreach ( $raw_data as $row ) { /* Parsitaan rivin tiedot */ $row_data = explode( '|', $row ); $name = ''; $time = 0; if ( count( $row_data ) > 1 ) { $name = $row_data[ 0 ]; $time = (int)( rtrim( $row_data[ 1 ] ) ); } else { continue; } /* * Muodostetaan päiväys, nollataan * lopetusaikaseuranta ja muodostetaan * päiväykselle oma osio online-taulukkoon */ $date = date( "d.m.Y", $time ); if ( /* ... */ ) { } /* * Jos käsiteltävällä käyttäjällä on avoin * lopetusaika käsiteltävän päivän kohdalla, * merkitään käsiteltävä aika lopetusajaksi */ if ( /* ... */ ) ) { //... } /* * Muutoin tallennetaan käyntitiedot online- * taulukkoon kyseisen päivän kohdalle */ else { //... /* Merkitään lopetusaika avoimeksi */ } } ?> <html> <head> <title>Testi</title> </head> <body> <div> <table> <?php foreach ( $online_data as $date => $hitsPerDate ): ?> <tr> <?php foreach ( $hitsPerDate as $hit ): ?> <td><?php echo $date; ?> <?php echo date( "H:i", $hit[ 'time' ][ 'start' ] ); ?> <?php if ( isset( $hit[ 'time' ][ 'end' ] ) ): ?> - <?php echo date( "H:i", $hit[ 'time' ][ 'end' ] ); ?> <?php endif; ?></td> <td><?php echo $hit[ 'name' ]; ?></td> <?php endforeach; ?></tr> <?php endforeach; ?> </table> </div> </body> </html>
Tulee muuten kauhian näköstä lähdekoodia tuolla kun PHP karsii noita merkkejä ja sisennyksiä mielivaltaisesti välistä. Pitää joko valita hirveän ulostulon tai hirveän sisäänmenon väliltä. Tai Tidy?
Siis tarkoitat HTML-lähdekoodia? Olen sitä mieltä, että ulkonäöllä ei ole mitään väliä, kunhan se on validia. Sitä ei kuitenkaan ole kenenkään tarkoitus ylläpitää ja jos tarvitsee tutkia niin sen voi ajaa siinä vaiheessa tidyn läpi.
Njoo vua tais se pukata sinne ylimääräistä väliäkin ellei putkittanu kaikkia <?php...?> ilman rivityksiä. Vaan tulipa jo pyyhittyä oma toimiva versio niin enpä sitten korjailekaan, siitä nimittäin taisi tulla hieman rampa. Elikkä edellinen koodinihan määrittelee online-aikaväliksi kaksi saman päivän lähintä aikaa, sitä varten pitäisi lisätä vielä oma tarkastelunsa. Mutta ilmassa on vielä se perimmäinen kysymys: miten erotellaan käyttäjän lähtöaika tuloajasta? Se kun on tuosta raakadatasta hankala sanoa.
Vastaisiko tämä tavoitetta?
<?php $ajat = $vanha_kayttaja = false; # Lisätään tunnisterivi, josta havaitaan datan loppu $rivit[] = "LOPETUS|0"; echo "<table><tbody>"; foreach ($rivit as $rivi) { list($kayttaja, $aika) = explode("|", trim($rivi)); if ($kayttaja == $vanha_kayttaja) { # käyttäjä pysyi samana, joten lisätään uusi aika listaan $ajat[] = $aika; } else { # jos rivejä on kertynyt, käsitellään ne if (is_array($ajat)) { tulosta($vanha_kayttaja, $ajat[0], $ajat[count($ajat) - 1]); } # tarkistetaan, tuliko vastaan oma lopetusrivimme if ($kayttaja == "LOPETUS" && $aika == 0) { break; # data loppui } # aloitetaan uusi listaus ja lisätään ensimmäinen aika $ajat = array(); $vanha_kayttaja = $kayttaja; $ajat[] = $aika; } } echo "</tbody></table>"; function tulosta($kayttaja, $alku, $loppu) { # muotoile tiedot haluamallasi tavalla printf("<tr><td>%s - %s</td><td>%s</td></tr>\n", date("Y-m-d H:i:s", $alku), date("Y-m-d H:i:s", $loppu), $kayttaja ); } ?>
Sinänsä datan käsittely noin on aika älytöntä. Jos käyn sivustolla kahdesti, 22.00 ja taas aamulla 8.00, eikä kukaan satu siinä välissä paikalle, olenko silloin ollut paikalla 22.00–8.00? Ehkäpä tuohon kannattaisi jokin fiksu arvio kehittää, luultavasti olen ollut paikalla iltasella enintään 22.00–22.05.
Aihe on jo aika vanha, joten et voi enää vastata siihen.