Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  27 1493
samfunnsukritisk
JunkieXL's Avatar
Hei!
Jeg lager en side som skal ha en countdown. Countdownen skal foregå til en bestemt tid som er kalkulert med PHP og lagret i en MySQL database. Det jeg lurer på er hvordan jeg skal få den lokale tiden med javascript og sendt den videre til en PHP-variabel
(Siden som tiden skal sendes fra kan bli stående en stund)
Hvorfor ikke bruke server-tiden ?
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Sitat av 852 Vis innlegg
Hvorfor ikke bruke server-tiden ?
Vis hele sitatet...
Fordi tiden blir regnet ut med PHP, altså, med mindre PC-tiden ikke er nøyaktig lik servertiden vil countdownen bli feil.
Sist endret av JunkieXL; 5. juni 2011 kl. 20:13.
Trigonoceps occipita
vidarlo's Avatar
Donor
Du tenker feil. Sjekk om tida sidan forrige handling er utløpt, ved å sjå om timestamp no er større enn timestamp lagra i databasen.

Tida på klienten forblir på klienten. Den bruker du bare som en indikasjon til brukeren. For om du gjer det slik du ser ut til å tenke vil jo brukeren kunne redigere tida fritt.
Lite kontroversiell
ticks's Avatar
Lagre tiden som Unix Timestamp (time() i PHP). Bruk Date().getTime() i Javascript for å få tilsvarende timestamp hos klienten. Da er det simpel subtraksjon for å få resterende tid (phpTimestamp -jsTimestamp = sekunder)
Sist endret av ticks; 5. juni 2011 kl. 20:15.
Da må du f.eks. sende en ajax request til serveren via javascript.

Ser dog ikke poenget med å åpne opp for at klienten kan manipulere nedtellingen?
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Mulig det er jeg som er veldig dum som lagrer tiden som TTMMSS i stede for å bruke timestamp?
Sist endret av JunkieXL; 5. juni 2011 kl. 20:19.
Men.. har du ikke tenkt på at klienten kan ha feil tid? Jeg sitter nå på en maskin som har feil tid: 13:38 15.05.2006, hvordan behandler du meg?
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Sitat av 852 Vis innlegg
Men.. har du ikke tenkt på at klienten kan ha feil tid? Jeg sitter nå på en maskin som har feil tid: 13:38 15.05.2006, hvordan behandler du meg?
Vis hele sitatet...
Den lokale tiden som skal telles ned til lagres for seg selv, har felter i databasen for den samme tiden bare regnet ut til servertid.
Lite kontroversiell
ticks's Avatar
Sitat av JunkieXL Vis innlegg
Mulig det er jeg som er veldig dum som lagrer tiden som TTMMSS i stede for å bruke timestamp?
Vis hele sitatet...
Det er veldig mye enklere å forholde seg til timestamps av unix-varianten, fordi det gir deg et atomært nummer å behandle, og ikke et nummer som må behandles flere ganger før det kan brukes.

Du kan heller bruke Date() i Javascript for å formatere unix-timestampet når du skal bruke det til output.
Sist endret av ticks; 5. juni 2011 kl. 20:26.
Den mest sikre måten får å unngå manipulering fra client er å sende en ny http-request til serveren hvert sekund. Men dette fører til en del ekstra trafikk. Så du kan jo sette en fast count-down tid når siden lastes, og hvis client sender request før denne er gått ut, så setter du gjenverde count-down tid og sender den til clienten.

Med statisk count down tid så mener jeg:

Kode

<?php
  $countDown = 60;
  printf (
    "<script type="text/javascript"> " .
    "var countDown = %d; " .
    "</script>",
    $countDown
  );
?>
Men du må huske å kontrollere opp mot databasen at countdown tiden er gått ut når clienten sender request, får å forhindre manipulasjon.
Sist endret av 0xFF; 5. juni 2011 kl. 20:27.
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Sitat av 0xFF Vis innlegg
Den mest sikre måten får å unngå manipulering fra client er å sende en ny http-request til serveren hvert sekund. Men dette fører til en del ekstra trafikk. Så du kan jo sette en fast count-down tid når siden lastes, og hvis client sender request før denne er gått ut, så setter du gjenverde count-down tid og sender den til clienten.

Med statisk count down tid så mener jeg:

Kode

<?php
  $countDown = 60;
  printf (
    "<script type="text/javascript"> " .
    "var countDown = %d; " .
    "</script",
    $countDown
  );
?>
Men du må huske å kontrollere opp mot databasen at countdown tiden er gått ut når clienten sender request, får å forhindre manipulasjon.
Vis hele sitatet...
Altså manipulasjon er ikke noe jeg bekymrer meg for fordi det føkker kun opp for brukeren selv. Siden som skal ha countdownen er en nedtelling på ett tekstbasert mafiaspill etter at man har tatt ett oppdrag, og man får ikke gjort noe før entryen med ventetiden er fjernet fra databasen, og dette skjer ikke før tiden er nådd på serveren...

Countdownen er rett og slett bare en pekepinn for brukeren om hvor lenge det er til han kan ta oppdrag igjen.
Sist endret av JunkieXL; 5. juni 2011 kl. 20:31.
Lite kontroversiell
ticks's Avatar
Jeg forstår ikke hvorfor du har noe behov for å bruke klientens tid i utgangspunktet. Du trenger bare en linje i PHP som sier "$ctTime = $sqlTime - time()", og så sende $ctTime til javascript-funksjonen som starter nedtellingen?
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Sitat av 0xFF Vis innlegg
Nok ett tekstbasert mafia spill? Det finnes sikkert 6 x 10⁹²⁴⁵² av dem fra før av, hvorfor lager du ikkje noe brukanes?
Vis hele sitatet...
Det er ikke direkte ett tekstbasert mafiaspill :P
Det er ikke mafia-relatert, og det er egentlig ikke så veldig mye spill heller. Dette er bare en liten tilleggsfunksjon til en annen side.

Sitat av ticks Vis innlegg
Jeg forstår ikke hvorfor du har noe behov for å bruke klientens tid i utgangspunktet. Du trenger bare en linje i PHP som sier "$ctTime = $sqlTime - time()", og så sende $ctTime til javascript-funksjonen som starter nedtellingen?
Vis hele sitatet...
Men javascript bruker vel brukerens lokale tid når den da teller ned?
Sitat av JunkieXL Vis innlegg
Den lokale tiden som skal telles ned til lagres for seg selv, har felter i databasen for den samme tiden bare regnet ut til servertid.
Vis hele sitatet...
Det er helt sikkert jeg som er dum her.
Så du har den lokale tiden som skal telles ned til i db felt, og du tar tiden til klientens maskin, gjør en differansiering og spytter ut hvor mye tid som er igjen. Forstår jeg riktig? Det du sier er at du gjør den om til servert-tid, greit. Hvis jeg har tiden 13:59 15.05.2006, så gjør du dette om til servertid. Nedtellingen blir på flere år, mener du da at du gir en ultimatgrense, f.eks at differansen er større enn null og mindre enn x. Jeg tror dette kan løses mye mer effektivt.

Hvis du har tiden den skal telles ned til, og bruker NOW() funksjonen i mysql for å finne tiden nå, differansierer disse og gir det til .js, er etter min mening mye mer effektivt.
Lite kontroversiell
ticks's Avatar
Sitat av JunkieXL Vis innlegg
Men javascript bruker vel brukerens lokale tid når den da teller ned?
Vis hele sitatet...
Dette avhenger jo fullstendig av hvordan du koder det.

Kode

<html>
  <head>
    <script type="text/javascript">
      var counter;
      var time;
      function start(t) {
        time = t;
        document.getElementById('countdown').innerHTML = time;
        counter = setInterval("update_display()",1000);
      }
  
      function update_display() {
        time--;
        document.getElementById('countdown').innerHTML = time;
      }
    </script>
  </head>
  <body onload="start(50);">
    <span id="countdown"></span>
  </body>
</html>
Bytt ut start(50); med start(<?php print($ctTime); ?>);, hvor "$ctTime = $sqlTime - time()" så er du ready and set.
Sist endret av ticks; 5. juni 2011 kl. 20:56.
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Sitat av 852 Vis innlegg
Det er helt sikkert jeg som er dum her.
Så du har den lokale tiden som skal telles ned til i db felt, og du tar tiden til klientens maskin, gjør en differansiering og spytter ut hvor mye tid som er igjen. Forstår jeg riktig? Det du sier er at du gjør den om til servert-tid, greit. Hvis jeg har tiden 13:59 15.05.2006, så gjør du dette om til servertid. Nedtellingen blir på flere år, mener du da at du gir en ultimatgrense, f.eks at differansen er større enn null og mindre enn x. Jeg tror dette kan løses mye mer effektivt.

Hvis du har tiden den skal telles ned til, og bruker NOW() funksjonen i mysql for å finne tiden nå, differansierer disse og gir det til .js, er etter min mening mye mer effektivt.
Vis hele sitatet...
Så da sitter jeg altså nok en gang igjen med en ajax-nedtelling?

Er ikke helt sikker på om jeg skjønte det du skrev, men jeg kan gi ett lite innblikk i hvordan database-tabellen fungerer.
[fra] = tiden da alt blir satt inn i databasen etter servertid, i formatet TTMMSS
[til] = tiden da raden skal bli slettet etter servertid, regnet ut med PHP, TTMMSS
[til_lokal] = tiden som skal telles ned til etter klientens tid <- Det er denne jeg sliter med
[ventetiden] = Hvor lang ventetiden er, TTMMSS

Sitat av ticks Vis innlegg
Dette avhenger jo fullstendig av hvordan du koder det.

Kode

<html>
  <head>
    <script type="text/javascript">
      var counter;
      var time;
      function start(t) {
        time = t;
        document.getElementById('countdown').innerHTML = time;
        counter = setInterval("update_display()",1000);
      }
  
      function update_display() {
        time--;
        document.getElementById('countdown').innerHTML = time;
      }
    </script>
  </head>
  <body onload="start(50);">
    <span id="countdown"></span>
  </body>
</html>
Bytt ut start(50); med start(<?php print($ctTime); ?>);, hvor "$ctTime = $sqlTime - time()" så er du ready and set.
Vis hele sitatet...
Men hvordan skal jeg få gjort om min rare tid i formatet TTMMSS til timestamp?
Sitat av JunkieXL Vis innlegg
Men hvordan skal jeg få gjort om min rare tid i formatet TTMMSS til timestamp?
Vis hele sitatet...
Må bare få presisert at jeg har minimal erfaring med dette, har holdt på i en måned og denne informasjonen får du basert på to bøker jeg har lest med null praksis erfaring: Ved å bruke dato og deretter mktime();
Lite kontroversiell
ticks's Avatar
Kan du ikke bare endre måten du lagrer timestamp på i utgangspunktet? TTMMSS er et klønete format.
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Sitat av ticks Vis innlegg
Kan du ikke bare endre måten du lagrer timestamp på i utgangspunktet? TTMMSS er et klønete format.
Vis hele sitatet...
Ja, jeg her helt enig. Jeg tror jeg gjør om alt til timestamp nå som jeg endelig forsto poenget med det. Hadde jeg begynt med timestamp i utgangspunktet hadde jeg sluppet evig lange koder for å kalkulere den nye tiden.

Hvis jeg skal "lage nytt" for tiden som skal telles ned til kan jeg vel bare plusse på sekundene som man må vente?

(Funksjonen jeg brukte for å regne ut tiden)

Kode

$dato_h = date('H');
$dato_i = date('i');
$dato_s = date('s');
$vt_h = substr($la_mission['vt'], 0, 2);
$vt_i = substr($la_mission['vt'], 2, 2);
$vt_s = substr($la_mission['vt'], 4, 2);
$minne_i_xt = 0;
$minne_h_xt = 0;
							// sekunder
								if($vt_s+$dato_s>59) {
								$eit = "60";
								$minne_i_xt = +1;
								$minne_s = $vt_s + $dato_s - $eit;
									if(strlen($minne_s) == 1) {
									$minne_s_u = "0". $vt_s + $dato_s - $eit;
									$minne_s = "0" . $minne_s_u;
									}
								}
								else {
								$minne_s = $vt_s + $dato_s;
									if(strlen($minne_s) == 1) {
									$minne_s_u = $vt_s + $dato_s;
									$minne_s = "0" . $minne_s_u;
									}	
								}
							// minutter
								if($vt_i+$minne_i_xt+$dato_i>59) {
								$eit = "60";
								$minne_h_xt = +1;
								$minne_i = $vt_i+ $minne_i_xt + $dato_i - $eit;
									if(strlen($minne_i) == 1) {
									$minne_i_u = "0". $vt_i+ $minne_i_xt + $dato_i - $eit;
									$minne_i = "0" . $minne_i_u;
									}
								}
								else {
								$minne_i = $vt_i + $dato_i + $minne_i_xt;
									if(strlen($minne_i) == 1) {
									$minne_i_u = $vt_i + $dato_i + $minne_i_xt;
									$minne_i = "0" . $minne_i_u;
									}	
								}
							// timer
								if($vt_h+$minne_h_xt+$dato_h>23) {
								$eit = "24";
								$minne_h = $vt_h +$minne_h_xt+ $dato_h - $eit;
									if(strlen($minne_h) == 1) {
									$minne_h_u = "0". $vt_h +$minne_h_xt+ $dato_h - $eit;
									$minne_h = "0" . $minne_h_u;
									}
								}
								else {
								$minne_h = $vt_h +$minne_h_xt+ $dato_h;
									if(strlen($minne_h) == 1) {
									$minne_h_u = $vt_h +$minne_h_xt+ $dato_h;
									$minne_h = "0" . $minne_h_u;
									}	
								}
Sitat av ticks Vis innlegg
Dette avhenger jo fullstendig av hvordan du koder det.

Kode

<html>
  <head>
    <script type="text/javascript">
      var counter;
      var time;
      function start(t) {
        time = t;
        document.getElementById('countdown').innerHTML = time;
        counter = setInterval("update_display()",1000);
      }
  
      function update_display() {
        time--;
        document.getElementById('countdown').innerHTML = time;
      }
    </script>
  </head>
  <body onload="start(50);">
    <span id="countdown"></span>
  </body>
</html>
Bytt ut start(50); med start(<?php print($ctTime); ?>);, hvor "$ctTime = $sqlTime - time()" så er du ready and set.
Vis hele sitatet...
Et lite problem som jeg kan se for meg er at $sqlTime i db er mindre enn time(). Da må han passe på å sjekke om dette er tilfellet. $sqlTime i db må også slettes når nedtellingen er slutt, og det må han bruke ajax til. Ellers må han vel bruke MAX(); til å dra ut den verdien som har høyest id, men det blir igjen klønete med for mye ubrukt data i db. Synes ajax er den mest effektive løsningen her jeg. Hva mener du?
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Sitat av 852 Vis innlegg
Et lite problem som jeg kan se for meg er at $sqlTime i db er mindre enn time(). Da må han passe på å sjekke om dette er tilfellet. $sqlTime i db må også slettes når nedtellingen er slutt, og det må han bruke ajax til. Ellers må han vel bruke MAX(); til å dra ut den verdien som har høyest id, men det blir igjen klønete med for mye ubrukt data i db. Synes ajax er den mest effektive løsningen her jeg. Hva mener du?
Vis hele sitatet...
Jeg har denne i toppen av siden, slik at når nedtellingen er over så blir siden refreshet og deretter sendt tilbake, hvis du skjønner?

Kode

// Slett Ventetid 
$currenttime = time();
mysql_query("DELETE FROM vt WHERE til<$currenttime);
Lite kontroversiell
ticks's Avatar
Sitat av JunkieXL Vis innlegg
Hvis jeg skal "lage nytt" for tiden som skal telles ned til kan jeg vel bare plusse på sekundene som man må vente?
Vis hele sitatet...
Stemmer! Vil du f.eks. ha et timestamp 10 minutter frem i tid gjør du rett og slett slik:

Kode

$someTime = time() + (60*10);
Sitat av 852 Vis innlegg
Et lite problem som jeg kan se for meg er at $sqlTime i db er mindre enn time(). Da må han passe på å sjekke om dette er tilfellet. $sqlTime i db må også slettes når nedtellingen er slutt, og det må han bruke ajax til. Ellers må han vel bruke MAX(); til å dra ut den verdien som har høyest id, men det blir igjen klønete med for mye ubrukt data i db. Synes ajax er den mest effektive løsningen her jeg. Hva mener du?
Vis hele sitatet...
Jeg regner med at han har en slik if-sjekk (time()-$sqlTime<=0) i starten av skriptet, som bestemmer om man skal ha tilgang til funksjonen eller du må vente. Da kan han også skrive koden for å fjerne raden i databasen når tiden er utløpt i denne if-sjekken. Når telleren når 0 kan javascriptet refreshe siden for deg (eller kjøre et ajax-request), og koden som fjerner raden blir da kjørt. Ajax er ingen nødvendighet.

EDIT: Hm, kanskje refreshe før jeg skriver
Sist endret av ticks; 5. juni 2011 kl. 21:55.
Hvis du skal bruke den på denne måten så er det enkleste å starte med år-mnd-dag-time-min-sek.

Kode

  printf ("%s", date ("YmdHis"));
Vil gi:

Kode

20110605215541
Da kan du trekke fra, legge til, sammenligne o.l. med -, +, >, <, =.. osv. Hvis du tar sek først, så vil du få store forskjeller bare av noen få sek. Grunnen til at jeg har tatt med År, mnd, og dager er fordi da går det ikkje ann at scriptet tar feil.
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Sitat av ticks Vis innlegg
Stemmer! Vil du f.eks. ha et timestamp 10 minutter frem i tid gjør du rett og slett slik:

Kode

$someTime = time() + (60*10);

Jeg regner med at han har en slik if-sjekk (time()-$sqlTime<=0) i starten av skriptet, som bestemmer om man skal ha tilgang til funksjonen eller du må vente. Da kan han også skrive koden for å fjerne raden i databasen når tiden er utløpt i denne if-sjekken. Når telleren når 0 kan javascriptet refreshe siden for deg (eller kjøre et ajax-request), og koden som fjerner raden blir da kjørt. Ajax er ingen nødvendighet.

EDIT: Hm, kanskje refreshe før jeg skriver
Vis hele sitatet...
Tusen takk hvert fall, skal se om jeg får det til å fungere nå!
Synes det er utrolig interessant løsning. Så du er avhengig av at javascript refresh-er siden når nedtellingen er ferdig, og det er helt ok for deg at du er avhengig av dette? Må understreke at nicket ditt passer deg utmerket. hehe

Mulig at jeg er på bærtur her, men er det ikke mer effektivt å definere et variabel istedenfor å "utføre" query-en hver eneste gang siden blir lastet? Hvis det er uaktuellt med variabel, vil det ikke være mer sikkerhetsmessig ok dersom du sjekker først om det finnes til<$currenttime før du utfører query-en? Det er vel mer belastende å utføre en query enn å bare sjekke om det finnes mer enn 0 rader med betingelsen $til<$currenttime. Litt usikker på hva som er best her. Mener du det er nødvendig å sjekke først om det finnes mer enn null rad? Det kan jo være klienten som refresher og ikke selve .js
Sist endret av 852; 5. juni 2011 kl. 22:04. Grunn: :p og ikke :P
samfunnsukritisk
JunkieXL's Avatar
Trådstarter
Sitat av 852 Vis innlegg
Synes det er utrolig interessant løsning. Så du er avhengig av at javascript refresh-er siden når nedtellingen er ferdig, og det er helt ok for deg at du er avhengig av dette? Må understreke at nicket ditt passer deg utmerket. hehe

Mulig at jeg er på bærtur her, men er det ikke mer effektivt å definere et variabel istedenfor å "utføre" query-en hver eneste gang siden blir lastet? Hvis det er uaktuellt med variabel, vil det ikke være mer sikkerhetsmessig ok dersom du sjekker først om det finnes til<$currenttime før du utfører query-en? Det er vel mer belastende å utføre en query enn å bare sjekke om det finnes mer enn 0 rader med betingelsen $til<$currenttime. Litt usikker på hva som er best her. Mener du det er nødvendig å sjekke først om det finnes mer enn null rad? Det kan jo være klienten som refresher og ikke selve .js
Vis hele sitatet...
Uhm, jeg skjønte ikke helt hva du mente, men det er mulig det er jeg som har forklart alt på en litt rar måte.

Systemet fungerer slikt:

Brukeren tar ett oppdrag på en egen oppdragsside. -> Uansett om han lykkes eller mislykkes får han en form for "ventetid"(En hvis tid man må vente før man kan utføre ett nytt oppdrag).
Hvis man prøver å gå inn på denne siden som lister opp alle oppdragene man kan ta, og siden ser at brukeren har ventetid lagret i databasen, vil den vise en nedtelling, slik at brukeren slipper å sitte og regne på dette selv.
Queryen som fjerner raden med ventetid ligger øverst i headeren som er den samme på alle sidene, altså den blir slettet uansett hvilken side man er på.
Derfor har jeg slik at hvis brukeren ønsker å se på denne nedtellingen, så refresher den siden når nedtellingen er på 0 for å fjerne raden med ventetid fra databasen, og når brukeren da blir sendt videre tilbake til siden han var på, vil ventetid-raden være slettet og nedtellingen vil ikke bli vist.

Hvis det klarner opp litt? :P
Sitat av JunkieXL Vis innlegg
Uhm, jeg skjønte ikke helt hva du mente, men det er mulig det er jeg som har forklart alt på en litt rar måte.

Systemet fungerer slikt:

Brukeren tar ett oppdrag på en egen oppdragsside. -> Uansett om han lykkes eller mislykkes får han en form for "ventetid"(En hvis tid man må vente før man kan utføre ett nytt oppdrag).
Hvis man prøver å gå inn på denne siden som lister opp alle oppdragene man kan ta, og siden ser at brukeren har ventetid lagret i databasen, vil den vise en nedtelling, slik at brukeren slipper å sitte og regne på dette selv.
Queryen som fjerner raden med ventetid ligger øverst i headeren som er den samme på alle sidene, altså den blir slettet uansett hvilken side man er på.
Derfor har jeg slik at hvis brukeren ønsker å se på denne nedtellingen, så refresher den siden når nedtellingen er på 0 for å fjerne raden med ventetid fra databasen, og når brukeren da blir sendt videre tilbake til siden han var på, vil ventetid-raden være slettet og nedtellingen vil ikke bli vist.

Hvis det klarner opp litt? :P
Vis hele sitatet...
$currenttime = time();
$num= mysql_num_rows(mysql_query("SELECT * FROM vt WHERE til<$currenttim"));
if($num>0){
mysql_query("DELETE * FROM vt WHERE til<$currenttime);
}

Tenkte jeg på. Problemet mitt med:
mysql_query("DELETE FROM vt WHERE til<$currenttime);

Jeg ser derimot hva som gikk galt i hodet mitt, jeg brukte * (all), og dette gir feil hvis jeg: mysql_query("DELETE * FROM vt WHERE til<$currenttime); og det finnes ikke til<$currenttime, mens den returnerer null hvis jeg ikke bruker * all.