tomarild.h Skrevet 27. november 2012 Del Skrevet 27. november 2012 Hei! Jeg skal sette opp et nettsted hvor brukerne kan registrere seg. Finnes det noen mulighet for å logge hvor mange ganger de forskjellige brukerne har klikket på linker på nettstedet mitt? Det skal kodes i PHP og jeg bruker SQL-databaser. Skulle gjerne hatt en slik funksjon, og samtidig en funksjon som angir antall klikk i parentes ved siden av de forskjellige linkene. Funksjon 1: Si at det er en liste på forsiden som er som dette: Hvordan lage sprø svor på ribba (12) Hjelp til pynting av juletre (3) Tips til rengjøring av pipeløp (4) Hvordan tracke linkklikking (0) Hvis en bruker nå er logget inn på siden, så ønsker jeg at det oppdateres antall klikk i profilen hans, hvis han for eksempel klikker på de tre øverste linkene i en slik liste. Dette tallet med brukerens totalt antall klikk, skal kunne hentes ut til å vise brukerens total klikk på linker - på dens profilside. Og det skal ikke være mulig å telle klikk på samme link flere ganger. Funksjon 2: Tallet i parentes ved siden av linken oppdateres med +1 hver gang noen klikker på linken. Dette må også skje dersom noen som ikke er logget inn klikker. Kommer til å trenge litt hjelp til å kode en del til dette nettstedet, og lurer også på hvor jeg kan poste freelance-oppdrag på forumet her? Håper noen kan svare meg på om disse funksjonene er mulig. I så fall skal jeg sette opp en oversikt over hva jeg behøver hjelp til. Lenke til kommentar
forvirretoggal Skrevet 28. november 2012 Del Skrevet 28. november 2012 En forholdsvis "enkel" løsning, der man ikke tar hensyn til unike brukere vil være å lage noe som dette: <?php /* script out.php */ $linkid = $_GET["id"]; $a = mysql_connect("localhost","username","password") or die("Kunne ikke koble til. " . mysql_error()); $b = mysql_select_db("database") or die("Kunne ikke velge database. " . mysql_error()); $c = mysql_query("SELECT * FROM linker WHERE id='".$linkid."'") or die("Kunne ikke utføre spørring. " . mysql_error()); while($resultat = mysql_fetch_assoc($c)) { $id = $resultat["id"]; $klikk = $resultat["klikk"]; $url = $resultat["url"]; } $klikkny = $klikk +1; $d = mysql_query("UPDATE linker SET klikk='".$klikkny."' WHERE id='".$id."'") or die("Kunne ikke oppdatere antall klikk. " . mysql_error()); ?> <meta http-equiv="refresh" content="0;URL=<?php echo $url; ?>"> Ovenstående eksempel er skrevet uten at det er testet, uten hensyn til mulighet for SQL-Injection og det tas ikke noe ansvar for at dette er den mest optimale koden. Dette fordrer også at alle linker hentes fra en database tabell, og at man i $url har hele http:// adressen. (Samt at linkene må gå via out.php?id= ) Det bør imidlertid gi deg en liten pekepinn på hvordan det kan gjøres, eller det kan inspirere andre til å komme med bedre forslag Lenke til kommentar
tomarild.h Skrevet 28. november 2012 Forfatter Del Skrevet 28. november 2012 Hei Martin! Takk for at du tok deg tid, og takk for godt svar. Jeg får til registrering av klikk med inspirasjon fra din kode. Problemet mitt nå er hvordan jeg skal sette det opp slik at det kun telles ett klikk fra samme bruker på en link. Altså.... hvis jeg har en link som heter vg.no, så skal det kun telles +1 den første gangen jeg klikker den linken. Klikker jeg linken en gang til, så telles det ikke. Et annet problem er hvordan jeg skal kunne telle alle klikkene en innlogget bruker klikker på hele nettstedet. Takk for hjelp :-) Lenke til kommentar
Feh Skrevet 28. november 2012 Del Skrevet 28. november 2012 Et kjøpt søk på google og fant denne: CCount. Står at den kan telle unike klikk men utover det gadd jeg ikke lese hvordan den egentlig fungerer, det kan du gjøre selv Sånn rett ut fra toppen av hodet kan du evt. prøve dette under. Du må i så fall opprette to tabeller, clicktable og linktable, eller bytte ut infoen til linktable med en tabell over lenker du har fra før osv. Her lagres en cookie for hver bruker som trykker på en lenke og lagrer det individuelle trykket i en database. Ved å gjøre det slik kan du få ut både antall klikk, og antall unike klikk. Men som sagt, rett fra toppen av hodet, utestet og sikkert en del bugs og sikkert ikke den smootheste måten det kan gjøre på, men kanskje du forstår ideen Scriptet kan f.eks kalles via en jquery .click funksjon som kalles hver gang en lenke trykkes på (merk at da burde de lenkene som skal være med i tellingen ha en egen klasse/id) og et ajax call som sender linkid til php filen. For å gjøre det mer dynamisk kan du også legge til en CRON jobb på serveren som kjører f.eks en gang om dagen og som sletter alle oppføringer fra databasen som er mer enn 14 dager gamle (som er det samme jeg har satt cookiens levetid på). <?php $link = mysqli_connect('localhost', 'brukernavn', 'passord', 'database') or die ("Kunne ikke koble til databasen"); $linkid = $_GET["id"]; if(isset($_COOKIE['cid'])) { $cid = $_COOKIE['cid']; } else { function generateRandomString($length = 10) { return substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, $length); } $randomString=generateRandomString(); setcookie('cid', $randomString, time()+60*60*24*14, '/'); } $timestamp=date('Y.m.d h:i:s'); //setter inn klikk i databasen, ikke unikt $insert_click=mysqli_query($link, "INSERT INTO clicktable VALUES ('$linkid', '$cid', '$timestamp' ") or die ("Kunne ikke sende informasjon til databasen"); //henter ut alle unike IDer som har trykket på lenken $get_current_clicks=mysqli_query($link, "SELECT DISTINCT cid FROM clicktable WHERE linkid='$linkid'"); //teller antall unike IDer som har trykket på lenken $clicks=mysqli_num_rows($link, $get_current_clicks); //setter tallet tilbake i lenketabellen/der hvor URLene blir lagret $update_clicks=mysqli_query($link, "UPDATE linktable SET clicks='$clicks'"); ?> For å hente ut hvor mange klikk en lenke har kjører du følgende kode bak hver lenke som produseres: <?php $get_clicks=mysqli_query($link, "SELECT clicks FROM linktable WHERE linkid='$linkid'"); echo ' (' . $clicks . ')'; ?> Hvis du vil lage en liste over lenker (f.eks 10 stk), rangert etter "mest populære" kan du gjøre følgende: <?php $get_clicks=mysqli_query($link, "SELECT * FROM linktable ORDER BY clicks DESC LIMIT 10"); $clicks=mysqli_num_rows($link, $get_clicks); echo '<p>Mest populære artikler:</p>'; echo $link . ' (' . $clicks . ')'; ?> Lenke til kommentar
TheClown Skrevet 28. november 2012 Del Skrevet 28. november 2012 Metoden postet ovenfor baserer seg på å lage en cookie som brukeren får lagret på sin datamaskin. En bedre metode er å legge begrensning på IP-adressen personen har. Eller en kombinasjon av begge. Det hadde tatt meg 10 sekund å slette Cookien (spesielt i Opera hvor man kan søke opp cookies og slette/endre dem), og klikke igjen. Det er dermed ikke bulletproof, men det er svært vanskelig å lage noe som er det. Lenke til kommentar
LarsM Skrevet 28. november 2012 Del Skrevet 28. november 2012 (endret) Her er et forslag for struktur i databasen: Hvis du bare skal tracke klikk fra innloggede brukere, altså brukere som er registrert i databasen, så kan du opprette et "Many-To-Many relationship" mellom brukere og adresser. Dette forholdet kan du tenke på som slik: "Én bruker kan ha besøkt mange sider, og én side kan ha blitt besøkt av mange brukere". For å modellere dette i MySQL trengs tre tabeller: Tabellen over brukere, tabellen over sider og tabellen som beskriver forholdet mellom brukere og sider. Ettersom dette bare er et eksempel til løsning, så definerer vi en ganske enkel struktur på tabellene: Brukere:brukerId, INT(11), PRIMARY KEY navn, VARCHAR(45) [*]Sider: url, VARCHAR(255), PRIMARY KEY antall, INTEGER(11) [*]Besoek: brukerId, INT(11), PRIMARY KEY, FOREIGN KEY(Brukere.brukerId) url, VARCHAR(255), PRIMARY KEY, FOREIGN KEY(Sider.url) Kort fortalt, så betyr PRIMARY KEY (primærnøkkel) at dette feltet er unikt i alle rader i databasen. Jeg har antatt at brukere lagres i databasen med en unik brukerid. Videre, har jeg antatt at alle sider som besøkes innehar en unik URL, altså opprettes en primærnøkkel også her. Hvis du har en unik identifikator på alle sider, og du kun skal logge klikk på egne sider, så kan du benytte deg av et heltall (INTEGER) som felt her også (eller hva enn du føler passer). Feltet antall holder styr på hvor mange ganger ikke-registrerte brukere har besøkt siden (les: klikket på linken). Tabellen Besoek inneholder alle "klikk" hver bruker har gjort på en side. For at et forhold mellom bruker og side ikke skal registreres flere ganger i databasen, så settes både brukerId og url til primærnøkkel. I tillegg opprettes det to FOREIGN KEYs (fremmednøkler). Fremmednøkkelen brukerId peker til brukerId i Brukere-tabellen, mens url peker til url i Sider-tabellen. Det er også en fordel (nødvendig? Jeg husker ikke i skrivende stund) at fremmednøkkel-feltene har samme datatype som primærnøklene de henviser til. Med primærnøkkel på både brukerId og url i Besoek, så vil ikke en innsetting fra samme bruker bli registrert, men heller gi en feil fra MySQL sin side. Når er det klart for å gjøre de forskjellige spørringene. For å hente ut antall besøk en bruker har gjort: SELECT COUNT(*) FROM Besoek WHERE brukerId = <brukerens id.>; For å hente ut totalt antall besøk til en spesifikk side: SELECT antall, COUNT(*) FROM Besoek WHERE Besoek.url = '<adresse til siden>' AND Besoek.url=Sider.url; For å sette inn et nytt besøk: INSERT INTO Besoek VALUES(<brukerens id>, '<adresse til siden>'); For å oppdatere antall besøk fra uregistrerte brukere: UPDATE Sider SET antall = antall + 1 WHERE url='<adresse til siden>'; Evt. hvis du ikke vil sette inn siden i databasen før noen kan klikke på linken: INSERT INTO Sider VALUES('<adresse til siden>', 1) ON DUPLICATE KEY UPDATE SET antall = antall + 1; Sistnevnte krever MySQL 5.0 eller nyere. Hvis INSERT-setningen resulterer i feil fordi denne adressen allerede ligger i databasen, vil antallet i stedet økes med 1. I denne løsningen, så lagres klikk fra brukerne et annet sted enn de fra de uregistrerte. Det kan være dette ikke er optimalt, men det var det jeg kom på i farten. :-) Lykke til! - Lars M. Endret 28. november 2012 av LarsM Lenke til kommentar
TheClown Skrevet 28. november 2012 Del Skrevet 28. november 2012 Tabellen sider burde også har en ID. Å ha tekstfelt som KEY er smått fyfy. Lenke til kommentar
Feh Skrevet 28. november 2012 Del Skrevet 28. november 2012 (endret) Metoden postet ovenfor baserer seg på å lage en cookie som brukeren får lagret på sin datamaskin. En bedre metode er å legge begrensning på IP-adressen personen har. Eller en kombinasjon av begge. Det hadde tatt meg 10 sekund å slette Cookien (spesielt i Opera hvor man kan søke opp cookies og slette/endre dem), og klikke igjen. Det er dermed ikke bulletproof, men det er svært vanskelig å lage noe som er det. Forsåvidt. Dog ser jeg ikke helt insentivet til å skulle endre cookien til dette formål, men at det slettes er selvfølgelig en fare. Det beste hadde nok vært å bruke en kombinasjon av lagring på brukernavn for registrerte, og IP adresser for besøkende. Her er et... *snip* 1. ikke bruk URL som primary key, legg til en URLID som er primary. Tekst som primary er ille nok, tekst som i tilleg inneholder " eller ' er enda værre. 2. Du tar ikke høyde for unike besøkende, kun totalt antall besøk. 3. Å bevisst sende inn en ugyldig spørring (duplicate key) til databasen er dårlig praksis og bør unngås. 4. Løsningen din vil ikke fungere siden du har satt begge variablene i besoek tabellen som primary keys. Det vil for det første si at en bruker kun kan besøke én lenke, før neste besøk ikke blir lagret (duplicate key). For det andre vil ikke andre brukeres klikk på samme URL lagres fordi du igjen får duplicate key error (adressen finnes fra før). Endret 28. november 2012 av Feh Lenke til kommentar
tomarild.h Skrevet 28. november 2012 Forfatter Del Skrevet 28. november 2012 Hei alle! Trådstarter her! Responsen har etterhvert vist seg å være over all forventning. Jeg vet liksom ikke helt hvordan jeg skal få beskrevet hvor takknemlig jeg er for at dere bruker så mye tid på å svare. Jeg innser at dette er ganske komplisert for meg å få til, selv om jeg forstår en god del av det som blir foreslått av dere. Jeg har knotet og fikset litt, slik at jeg nå klarer å registrere alle klikk, og jeg klarer også å summere alle klikkene en bruker f.eks har fått på linker han har lagt ut. Det jeg ikke vil komme til å fikse, er det som blir diskutert ovenfor - nemlig at man bare skal kunne telle klikk fra samme link én gang og hvordan man skal regne ut hvor mange ganger en innlogget bruker har klikket på linker. PS! Det skal telles linkklikk også fra uregistrerte. Jeg tror rett og slett at jeg skal lage en ordentlig prosjektbeskrivelse av hva jeg ønsker meg, også kan den som vil tilby seg å lage en ferdig løsning. Pris kan vi diskutere når vi kommer så langt. Tusen takk for all hjelp - så langt! :-) Lenke til kommentar
Feh Skrevet 29. november 2012 Del Skrevet 29. november 2012 Det skal være ganske enkelt å få til hvis du har kommet så langt. I scriptet som lagrer klikkene til databasen kan du legge til litt validering for å kun telle unike klikk, og istedet bruke en counter for å registrere alle klikk (hvis dette også er av interesse). Bare lag en ekstra tabell med feltene: clickid (primary), userid, ip, url eller urlid og legg til følgende i starten av scriptet ditt $ip=$_SERVER['REMOTE_ADDR']; $username=... hva du bruker for å lagre brukernavn, $_GET, $_POST, $_SESSION eller $_COOKIE eller om det allerede ligger i en variabel trenger du ikke deklarere det en gang til. For å sjekke tabellen om brukeren/besøket har klikket linken før, legg inn en spørring etterfulgt av if/else før insert setningen: $query...SELECT * FROM klikktabell while ... { $stored_userid=... $stored_url/$urlid=... if(isset($brukernavn)) { if($userid==$stored_userid && $url==$stored_url) { //Begge er like, ikke gjør noe } else { //Ett av feltene er ulike (f.eks samme brukerid, men forskjellig URL, eller samme URL, men annen brukerid), eller begge feltene er ulike //Kjør insert setningen din her } } } if(!isset($brukernavn)) { $ip=$_SERVER['REMOTE_ADDR']; ...gjør det samme som i scriptet over, bare bytt ut user med IP } På den måten skal du i teorien kun sette inn unike rader i tabellen. Hvis en bruker har trykket en lenke, vil neste trykk ikke telle, men hvis den trykker en annen lenke skal den komme i basen. Samme hvis en annen bruker har trykket en lenke, vil nesete brukers trykk registreres. Det er kun når en ID/IP trykker på den samme lenken flere ganger og begge verdier er like at klikket ikke registreres. Du kan da også hente ut antall unike trykk på en lenke ved å kjøre en count() på URL feltet. Koden er selvsagt teoretisk og ikke testet. Lenke til kommentar
tomarild.h Skrevet 29. november 2012 Forfatter Del Skrevet 29. november 2012 Hei Feh! Nå er jeg NESTEN i mål føler jeg. Takk for nye tips! Jeg laget en ny tabell, og får uproblematisk fylt den med brukerens ip og noe jeg kaller linkid (unikt id-nummer som hver link har). Dette burde jo strengt talt holde. Det jeg trenger nå, er en spørring som sjekker om det finnes en match mellom linkid og ip i databasen. Finnes det skal man bare redirectes til URLen (som man kanskje kan hente med en $_GET-funksjon eller noe?). Finnes det IKKE noen match, så skal det da så klart settes info inni tabellen "klikktabell" og klikk skal oppdateres i tabellen som heter "innlegg". Du har jo lagt et eksempel til spørring ovenfor, men jeg får ikke det til å fungere. Har du et forslag på hvordan jeg enkelt kan gjøre en slik spørring? Jeg skjønner at jeg må lage en connection til databasen og tabellen "klikktabell", der jeg f.eks må si at HVIS linkid= $_GET['id'] AND ip=$_SERVER['REMOTE_ADDR'], så skal man redirectes, hvis ikke - skal da data innsettes. Lenke til kommentar
forvirretoggal Skrevet 30. november 2012 Del Skrevet 30. november 2012 (endret) Nå er jeg NESTEN i mål føler jeg. Takk for nye tips! Jeg laget en ny tabell, og får uproblematisk fylt den med brukerens ip og noe jeg kaller linkid (unikt id-nummer som hver link har). Dette burde jo strengt talt holde. Det jeg trenger nå, er en spørring som sjekker om det finnes en match mellom linkid og ip i databasen. Finnes det skal man bare redirectes til URLen (som man kanskje kan hente med en $_GET-funksjon eller noe?). Se litt på denne siden for mulige løsninger. Har selv ikke så mye erfaring med bruk av JOIN selections, men om det er kun et fåtall felt som skal velges i samme spørring kan du sikkert bruke "SELECT table1.column1, table2.column2 FROM table1, table2 WHERE table1.column1 = table2.column1;" Endret 30. november 2012 av martinbn Lenke til kommentar
LarsM Skrevet 30. november 2012 Del Skrevet 30. november 2012 (endret) 1. ikke bruk URL som primary key, legg til en URLID som er primary. Tekst som primary er ille nok, tekst som i tilleg inneholder " eller ' er enda værre. Hva annet enn at URL-ene har varierende lengde tenker du på som ille? " og ' bør uansett encodes før URL-en legges inn. Her var det kun snakk om databasestruktur, ingen detaljer om implementasjonen ellers. 2. Du tar ikke høyde for unike besøkende, kun totalt antall besøk. Igjen, kun databasen jeg beskrev. Hvordan man vil håndtere unike besøk (klikk) fra folk som *ikke* er registrert nevner jeg ikke, men cookies er foreslått av andre. Antall-feltet var ment som å lagre klikk fra ikke-registrerte brukere, som jeg nevnte. 3. Å bevisst sende inn en ugyldig spørring (duplicate key) til databasen er dårlig praksis og bør unngås. Den andre muligheten er å gjøre en spørring på forhånd, som igjen koster ekstra. Da mener jeg man må sjekke hva som er dyrest: gjøre et ekstra databasekall eller håndtere en feil. 4. Løsningen din vil ikke fungere siden du har satt begge variablene i besoek tabellen som primary keys. Det vil for det første si at en bruker kun kan besøke én lenke, før neste besøk ikke blir lagret (duplicate key). For det andre vil ikke andre brukeres klikk på samme URL lagres fordi du igjen får duplicate key error (adressen finnes fra før). I problemet han beskriver, så forstod jeg det som at han kun ville ta vare på ett klikk per bruker på en lenke. Når begge feltene er primærnøkler, så blir dette en sammensatt nøkkel, slik at en rad i tabellen kun er unik (les: det finnes ingen duplikatnøkkel) for én brukers id. og én URL. For eksempel, så er ikke raden (brukerId, url) [1000, www.vg.no] lik [1000, www.db.no] selv om brukerId-feltet er likt. Evt. [1000, www.vg.no] og [1001, www.vg.no]. Hvis han da legger til en bruker i relasjonen når han klikker, og benytter seg av de nøklene jeg definerte, så vil det kun bli lagt til én gang. Merk at dette gjaldt registrerte brukere. - Lars M. Endret 30. november 2012 av LarsM Lenke til kommentar
tomarild.h Skrevet 30. november 2012 Forfatter Del Skrevet 30. november 2012 (endret) Hei igjen! Nå er jeg virkelig helt i mål snart. Har klart å løse det meste med hjelp av det som er blitt skrevet her av dere. Har ikke direkte brukt eksemplene, men de har fått meg til å finne ut alternative måter å løse det på. Nå gjenstår én liten filleting. I en IF-Else, skal jeg redirecte til URL med $_GET-funksjon. Det får jeg ikke til. Altså... jeg trenger noe slikt: ...... else { header("Location: $_GET['url']"); } Men dette fungerer ikke. Vet ikke helt hvorfor. Noen som har tips til redirect med $_GET? Endret 30. november 2012 av Tom-A. Lenke til kommentar
tomarild.h Skrevet 30. november 2012 Forfatter Del Skrevet 30. november 2012 Hei igjen! Nå er jeg virkelig helt i mål snart. Har klart å løse det meste med hjelp av det som er blitt skrevet her av dere. Har ikke direkte brukt eksemplene, men de har fått meg til å finne ut alternative måter å løse det på. Nå gjenstår én liten filleting. I en IF-Else, skal jeg redirecte til URL med $_GET-funksjon. Det får jeg ikke til. Altså... jeg trenger noe slikt: ...... else { header("Location: $_GET['url']"); } Men dette fungerer ikke. Vet ikke helt hvorfor. Forsøker også ting á la } else { ?> <META HTTP-EQUIV=Refresh CONTENT="10; URL=<?php echo $_GET['url']; ?>"> <?php } mysql_close($con) ?> ... men det funker heller ikke. Noen som har tips til redirect med $_GET? Lenke til kommentar
tomarild.h Skrevet 1. desember 2012 Forfatter Del Skrevet 1. desember 2012 Da har jeg løst alt jeg lurte på! Har ikke brukt noe av det dere har skrevet og tipset om direkte - men alle tipsene deres har fått meg til å tenke ut muligheter for hvordan ting kan løses. Mange av løsningene mine er sikkert ikke godt nok sikkerhetsmessig eller iht til diverse retningslinjer - men så er det heller ikke Facebook 2 jeg lager :-) Tusen takk for alle bidrag! Knallbra! :-D Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå