Morjensta
Millainen rakenne kannattaisi antaa foorumin tietokannalle?
- tietokantani - - aiheen nimi - (Aiheen nimi aina oma taulu?) - lähettäjä - aika - viesti - - lähettäjä - aika - viesti - - aiheen nimi - (Aiheen nimi aina oma taulu?) - lähettäjä - aika - viesti - - lähettäjä - aika - viesti -
Tuo on ainoa tapa, jonka osaan näin hatusta vetää. Olisiko tämä myös mahdollinen?
- tietokantani - - viestit - (Yleinen taulu?) - aihe - lähettäjä - aika - viesti - - aihe - lähettäjä - aika - viesti -
En kyllä lähtisi luomaan jokaisella aiheelle omaa taulua, vaan loisin yhden taulun esim. "viestit" ja sinne sitten sarakkeet id,aiheen_nimi,viesti,pvm jne...
Edit.
Tietenkin voisi luoda yhden taulun aihee nimiä varten ja toisen viesteille ja siellä viestitaulussa jokaiselle tietueelle annetaan aihetta vastaava id...
Näin:
taulu: aiheet +-----------+--------------+ | id | aiheen_nimi | +-----------+--------------+ | 1 | Eka aihe | +-----------+--------------+ taulu: viestit +-----------+--------------+-----------+ | id | aihe_id | viesti | +-----------+--------------+-----------+ | 1 | 1 | viesti | +-----------+--------------+-----------+
Triton kirjoitti:
En kyllä lähtisi luomaan jokaisella aiheelle omaa taulua, vaan loisin yhden taulun esim. "viestit" ja sinne sitten sarakkeet id,aiheen_nimi,viesti,pvm jne...
Eli tämä jälkimmäinen? Minustakin olisi kyllä tyhmää lähteä tekemään jokaiselle aiheelle omaa taulua. Eikös tämä vaan hidastaisi kun on paljon tietoa?
Järkevä ratkaisu on käyttää kahta taulua: yhdessä ovat aiheet, toisessa ovat viestit (eli juuri Tonin esittelemä tapa). Nyrkkisääntö tietokannan suunnittelussa on, että taulujen määrä ei kasva, kun tietokantaan lisätään tietoa.
Antti Laaksonen kirjoitti:
Järkevä ratkaisu on käyttää kahta taulua: yhdessä ovat aiheet, toisessa ovat viestit (eli juuri Tonin esittelemä tapa). Nyrkkisääntö tietokannan suunnittelussa on, että taulujen määrä ei kasva, kun tietokantaan lisätään tietoa.
Itsekin kun mietin tarkemmin, niin näinpä tämä taitaa olla...
Antti Laaksonen kirjoitti:
Järkevä ratkaisu on käyttää kahta taulua: yhdessä ovat aiheet, toisessa ovat viestit (eli juuri Tonin esittelemä tapa). Nyrkkisääntö tietokannan suunnittelussa on, että taulujen määrä ei kasva, kun tietokantaan lisätään tietoa.
Selvä, eikun rakentamaan sitten yksinkertaista foorumiani. :D
PS. Antti, Putkassa tälläin myös?
EDIT: Jos antaa aika sarakkeelle tyypin, niin laitetaanko INT vai DATE?
Ja noi ihan TEXT vaan?
MIB kirjoitti:
EDIT: Jos antaa aika sarakkeelle tyypin, niin laitetaanko INT vai DATE?
Ja noi ihan TEXT vaan?
DATE noista vaihtoehdoista paras (= ainut oikea).
trilog kirjoitti:
MIB kirjoitti:
EDIT: Jos antaa aika sarakkeelle tyypin, niin laitetaanko INT vai DATE?
Ja noi ihan TEXT vaan?DATE noista vaihtoehdoista paras (= ainut oikea).
Selvä. Muutetaampa sitten.
EDIT: Jostain syystä forum tietokantaani ei saada yhteyttä, toisin sanoin pääsy mitätöidään: Access denied for user ''@'localhost' to database 'forum'
Koodia:
<?php $yhteys = mysql_connect("localhost", "", "") or die(mysql_error()); mysql_select_db("forum") or die(mysql_error()); if ($yhteys) echo "Kunnossa"; else echo "Epäkunnossa"; mysql_close($yhteys); ?>
Tuolla kyseisellä tietokannalla ei toimi, mutta test kannallani toimii. En ole mitään erikoista säätänyt tuohon forum kantaan.
EDIT2: Laitoin tunnukseksi root niin jo lähti toimimaan. Ei omalla serverillä ennen ole tarvinnut tuollaisia... :S
MIB kirjoitti:
PS. Antti, Putkassa tälläin myös?
Kyllä vain.
MIB kirjoitti:
Jos antaa aika sarakkeelle tyypin, niin laitetaanko INT vai DATE?
Tämä ei ole tärkeä valinta. Minä olen yleensä valinnut tyypin INT ja tallentanut siihen PHP:n aikaleiman.
Antti Laaksonen kirjoitti:
MIB kirjoitti:
PS. Antti, Putkassa tälläin myös?
Kyllä vain.
MIB kirjoitti:
Jos antaa aika sarakkeelle tyypin, niin laitetaanko INT vai DATE?
Tämä ei ole tärkeä valinta. Minä olen yleensä valinnut tyypin INT ja tallentanut siihen PHP:n aikaleiman.
Selvä. Näiden vastausten perusteella alan tekemään. :) Kiitos vastanneille!
Antti Laaksonen kirjoitti:
Tämä ei ole tärkeä valinta. Minä olen yleensä valinnut tyypin INT ja tallentanut siihen PHP:n aikaleiman.
Eikö TIMESTAMP -tietotyyppi ole tuota varten?
Aikaleima on kokonaisluku, joten tyyppi INT on minusta sopiva.
Syitä, miksi käyttää valmiita tietokannan aikatietotyyppejä:
ORDER BY
ei toimikaan oikein INT
tai TEXT
muotoisten kenttien kanssa.Valmiit aikatietotyypit ovat siis mahdollisesti selkeyttämässä ja helpottamassa koodia sekä tietokannan rakennetta ja pitävät huolen mahdollisten sudenkuoppien välttämisestä — käytä siis niitä. Tässä ehkäpä DATETIME
, koska halunnet varmaan myös kellonajan, jolloin viesti kirjoitettiin.
Kun saat softan valmiiksi, laitahan demoa tännekkin :)
PS. Muuten, miten tallennan ajan? Tulee vaan nollia tietokantaan viestiä kirjoittaessa.
EDIT: Että tuli jotain nollien tilalle, niin piti muuttaa aika sarakkeen muodoksi INT. Se tallentaa nyt ajan tätä luokkaa: 1243781366. Jos tuo on muuttujassa (kun luetaan viestiä) $lähetetty, ja luetaan näin:
Toimiiko tälläinen?
MIB kirjoitti:
Toimiiko tälläinen?
Joo, ton sain toimimaan, mutta, nyt tuli seuraava pulma. Miten käännän listan ympäri? Nyt uusin on alhaalla, kun kuuluisi toistapäin olla. Array_reverce vai oli array_revearce:lla menisi jos olisi tekstitiedostossa?
MIB kirjoitti:
Joo, ton sain toimimaan, mutta, nyt tuli seuraava pulma. Miten käännän listan ympäri? Nyt uusin on alhaalla, kun kuuluisi toistapäin olla. Array_reverce vai oli array_revearce:lla menisi jos olisi tekstitiedostossa?
ORDER BY
ja DESC
? Menee se tosin PHP:n puolellakin array_reverse
llä kun vain haet halutut tiedot taulukkoon (suosittelen kuitenkin ensimmäistä tapaa).
trilog kirjoitti:
ORDER BY
jaDESC
?
Ai niin joo! :D Unohdin tämän ihan kokonaan.
trilog kirjoitti:
MIB kirjoitti:
EDIT: Jos antaa aika sarakkeelle tyypin, niin laitetaanko INT vai DATE?
Ja noi ihan TEXT vaan?DATE noista vaihtoehdoista paras (= ainut oikea).
Aikaleimaksi kylläkin DATETIME on DATEa parempi, koska DATE ei sisällä lainkaan kellonaikaa. Toisaalta TIMESTAMP on ehkä tässä tilanteessa paikallaan. Sen voi myös säätää taulua luodessa asettumaan tai myös päivittymään itse, jolloin esimerkiksi viestien lähetys- ja muokkausaikoja ei tarvitsisi itse koskaan asettaa, vaan ne tulisivat automaattisesti.
Metabolix kirjoitti:
Aikaleimaksi kylläkin DATETIME on DATEa parempi, koska DATE ei sisällä lainkaan kellonaikaa. Toisaalta TIMESTAMP on ehkä tässä tilanteessa paikallaan. Sen voi myös säätää taulua luodessa asettumaan tai myös päivittymään itse, jolloin esimerkiksi viestien lähetys- ja muokkausaikoja ei tarvitsisi itse koskaan asettaa, vaan ne tulisivat automaattisesti.
Totta, mutta huomioithan "noista vaihtoehdoista". :)
Olisihan minun toki pitänyt mainita tähän tarkoitukseen paras vaihtoehto, mutta en sitten tullut ajatelleeksi sen enempää.
trilog kirjoitti:
ORDER BY
jaDESC
Miten tämä taas menikään?
vai jotain muuta?
SELECT * FROM viestit WHERE aihe_id = '$id' ORDER BY aika DESC
Juuri noin se toimii... Eli luonnollisesti tuo järjestää tietueet nousevassa järjestyksessä aika-sarakkeen mukaan.
Triton kirjoitti:
Juuri noin se toimii... Eli luonnollisesti tuo järjestää tietueet nousevassa järjestyksessä aika-sarakkeen mukaan.
Olisiko DESC uusin ensimmäisenä (viimeiseksi lähetetty) vai ASC?
ASC = pienimmästä suurimpaan
DESC = suurimmasta pienimpään
Uusin aika on suurin, eli oikea valinta on DESC.
Antti Laaksonen kirjoitti:
ASC = pienimmästä suurimpaan
DESC = suurimmasta pienimpäänUusin aika on suurin, eli oikea valinta on DESC.
Kiitos, nyt toimii :)
Nyt olisi tämä muuten valmis, paitsi kaikki hienoudet puuttuu:
- Oma sivu
- Rekisteröinti (Tunnus on aina minun nimeni :P Tulee korjaus)
- Tilastot, mm. viestimäärät per keskustelu tms.
Voi kertoa, mitä voisin lisätä siihen.
Tuohon tilastot juttuun vielä sen verran, että olisi kiva tuo asuinpaikka juttu kartalla, mutta se on aikas vaikea tehdä. :D
EDIT: Nyt on todella lähellä, että itse aiheiden aloitus ja vastaaminen toimivat! Pari juttua silti kiikastaa: 1. Jos aiheeseen ei ole vastattu, aiheen alkuun tulostuu 3 mysql erroria. Tämän saan korjattua tarkistamalla onko vastausta käytten If -lausetta.
2. Yhteen aiheeseen voi vastata vain kerran. Olen huomannut saman ongelman ennenkin, mutta eri tilanteessa.
Tein tietokanta rakenteen seuraavasti:
Minulla on forum tietokanta, jossa on 3 taulua; aiheet, viestit ja vastaukset.
Aiheet tauluun tallentuu aiheiden otsikot.
Viestit tauluun tallentuu jokaisen aiheen aloitusviesti.
Vastaukset tauluun tallentuvat vastaukset joita sitten haetaan sinne tallennetun otsikon perusteella.
Sitten on myös nämä puutteet, mitkä aikaisemmin mainitsinkin, että ei voi muokata viestiä tms. Sen muokkaamisen saan tehtyä helposti.
PS. Onkohan minun ollut järkevää tehdä foorumi niin, että aisiin ei viitata ID:n perusteella vaan otsikolla? Eli, tämän alue.php?id=xxx
onkin alue.php?aihe=Aiheen Nimi
.
MIB kirjoitti:
Viestit tauluun tallentuu jokaisen aiheen aloitusviesti.
Vastaukset tauluun tallentuvat vastaukset joita sitten haetaan sinne tallennetun otsikon perusteella.
Aloitusviestien tallennus erilliseen tauluun voi olla aika turhaa. Jos kaikki viestit olisivat samassa taulussa, aloitusviestin tunnistaisi siitä, että sen lähetysaika on varhaisin.
MIB kirjoitti:
Onkohan minun ollut järkevää tehdä foorumi niin, että aisiin ei viitata ID:n perusteella vaan otsikolla?
Tässä voi muodostua ongelmaksi, jos kahdella aiheella on sama otsikko. Lisäksi kaikki merkit eivät voi esiintyä sellaisenaan sivun osoitteessa.
Antti Laaksonen kirjoitti:
MIB kirjoitti:
Onkohan minun ollut järkevää tehdä foorumi niin, että aisiin ei viitata ID:n perusteella vaan otsikolla?
Tässä voi muodostua ongelmaksi, jos kahdella aiheella on sama otsikko. Lisäksi kaikki merkit eivät voi esiintyä sellaisenaan sivun osoitteessa.
Kyllä, kaikki eivät voi esiintyä, mutta silloin korvaan nämä sallitulla merkillä ja muunnan ne tulostusvaiheessa takaisin. (Tulee kun ehditään)
Oli myös helpompaa tehdä se otsikon perusteella.
Jos on saman niminen aihe jo ennestään kun aihetta luodaan, koodi ei luo uutta aihetta vaan kirjoittaa viestin vanhaan aiheeseen. (Tarkoitus ainakin tulla)
<?php $kysele2 = "SELECT * FROM vastaukset WHERE otsikko = '$otsikko'"; $hae = mysql_query($kysele2, $yhteys); $vastaaja = mysql_result($hae, $i, "lähettäjä_id"); $aika2 = mysql_result($hae, $i, "aika"); $aikaa = date("d.m.Y H:i", $aika2); $viestii = mysql_result($hae, $i, "viesti"); echo "<tr><td width=\"250\">Lähettäjä:<b> $vastaaja</b></td><td>Milloin: <b>$aikaa</b></td></tr>"; echo "<tr><td>$viestii<br><br></td></tr>"; ?>
Miten tarkistetaan, onko tiedot haettavissa? if ($hae) ei vastaa samaa kuin 0 tässä tarkoituksessa.
MIB kirjoitti:
Miten tarkistetaan, onko tiedot haettavissa?
Funktiolla mysql_num_rows voi tarkistaa, kuinka monta riviä tietoa kysely nouti tietokannasta. Puuttuukohan yllä olevasta koodista silmukka? Tämä selittäisi sen, että vain yksi vastaus näkyy.
Antti Laaksonen kirjoitti:
MIB kirjoitti:
Miten tarkistetaan, onko tiedot haettavissa?
Funktiolla mysql_num_rows voi tarkistaa, kuinka monta riviä tietoa kysely nouti tietokannasta. Puuttuukohan yllä olevasta koodista silmukka? Tämä selittäisi sen, että vain yksi vastaus näkyy.
Kiitos, tietenkin se menee näin ;)
On käytännöllisempää hakea kokonainen rivi hakutuloksista vaikkapa mysql_fetch_assoc-funktiolla. Tämä myös palauttaa falsen, jos dataa ei ole saatavilla.
<?php // Yritetään hakea rivi, ja jos sellainen vielä saadaan, jatketaan silmukkaa. while ($rivi = mysql_fetch_assoc($hae)) { // Taulukossa ovat kätevästi kaikki hakutuloksen tiedot. $viesti = $rivi["viesti"]; }
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\xampplite\htdocs\foorumi\ylaosa.php:9) in C:\xampplite\htdocs\foorumi\yla.php on line 1
Mitä tämä meinaa? Tuo ykkös rivi on tämän näköinen: <?php session_start();
Ei minun mielestä tuossa ole mitään väärin. Silti sanoo niin.
EDIT:
Lainaus toisesta keskustelusta:
Blaze kirjoitti:
Kristallipallo sanoo, että sulla on jotain HTML:ää ennen tuota. Laita tuo PHP-pätkä ihan ensimmäiseks. http://pp.kpnet.fi/blaze/codefaq/#headerssent
Näinhän oli taas käynyt, että oli turhaa tulostettu väärään paikkaan väärää tietoa.
XML-sivua ei voi näyttää XML-syötettä ei voi näyttää, jos tyylisivu on XSL. Korjaa virhe ja valitse Päivitä tai yritä myöhemmin uudelleen. -------------------------------------------------------------------------------- XML-asiakirjassa voi olla vain yksi ylätason elementti. Virhe resurssia http://192.168.0.105/foorumi/uusiaihe.php?alue=1 kä... <b>Warning</b>: Cannot modify header information - headers already sent by (output started at C:\xampplite\htdo...
Tämmöisen virheen näyttää. Koodit:
1. uusiaihe.php (Aiheen luontiin)
<?php include("yla.php"); $yhteys = mysql_connect("localhost", "root", ""); mysql_select_db("forum", $yhteys); $alue = $_GET["alue"]; $viesti = $_POST["viesti"]; $otsikko = $_POST["otsikko"]; $aihe_id = $_GET["alue"]; $lähettäjä_id = $user['tunnus']; $aika = time(); if ($alue == "1") { $kysely = "INSERT INTO aiheet (aihe_id, otsikko) VALUES ('1', '$otsikko')"; $kysely2 = "INSERT INTO viestit (viesti_id, otsikko, aihe_id, lähettäjä_id, aika, viesti) VALUES ('1', '$otsikko', '1', '".$user['tunnus']."', '$aika', '$viesti')"; mysql_query($kysely, $yhteys); mysql_query($kysely2, $yhteys); header("Location: alue.php?id=1"); } mysql_close($yhteys); ?>
2. yla.php (Asetuksia)
<?php session_start(); include("config.php"); //muuta config.php:n polku oikeaksi //avataan yhteys tietokantaan $lnk = mysql_connect($db_server,$db_user,$db_passwd) or die ("Yhteys tietokantaan epäonnistui"); mysql_select_db($db_db,$lnk) or die ("Tietokannan valitseminen epäonnistui"); //käyttäjä on oletuksena false. Älä varsinkaan poista, ellet tiedä mitä teet :) $user = false; /* SISÄÄNKIRJAUTUMINEN */ if(isset($_POST['tunnus']) && isset($_POST['salasana'])){ //muuttujat turvallisesti talteen $tunnus = get_magic_quotes_gpc() ? $_POST['tunnus'] : mysql_real_escape_string($_POST['tunnus']); $salasana = get_magic_quotes_gpc() ? $_POST['salasana'] : mysql_real_escape_string($_POST['salasana']); $salasana = md5($salasana); //luodaan käyttäjäkohtainen uniikki id $istuntotunnus = md5(uniqid("")); //lisätään istunto tietokantaan käyttäjän tietoihin mysql_query("UPDATE {$tbl_users} SET istunto = '{$istuntotunnus}' WHERE tunnus = '{$tunnus}' AND salasana = '{$salasana}'",$lnk) or die (mysql_error()); //jos lisättyjä rivejä on yksi, kirjautuminen onnistui if(mysql_affected_rows($lnk) == 1){ //laitetaan sessioon talteen istuntotunnus $_SESSION['log_key'] = $istuntotunnus; //takaisn edelliselle sivulle. Parempiakin tapoja on header("Location: ".isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : "index.php"); } } /* ULOSKIRJAUTUMINEN */ if(isset($_REQUEST['logout'])){ unset($_SESSION['log_key']); session_destroy(); } /* KÄYTTÄJÄN TUNNISTUS */ if(isset($_SESSION['log_key'])){ //HAETAAN KÄYTTÄJÄN TIEDOT $sql = "SELECT id, tunnus, DATE_FORMAT(last_load,'%d.%m.%y %h:%i:%s') AS last_load FROM {$tbl_users} WHERE istunto = '".mysql_real_escape_string($_SESSION['log_key'])."'"; $sql = mysql_query($sql,$lnk); if($sql && mysql_num_rows($sql) == 1){ //käyttäjä tunnistettu, kaikki kunnossa $user = mysql_fetch_assoc($sql); //nyt käyttäjän tiedot ovat mukavasti $user[]-taulukossa //esim. käyttäjän id löytyy $user['id'] ja tunnus $user['tunnus'] //lisätään vielä käyttäjän viimeisestä sivunlatauksesta aikaleima mysql_query("UPDATE {$tbl_users} SET last_load = NOW() WHERE id = ".$user['id'], $lnk); } } /* TÄSTÄ ETEENPÄIN VOI SOVELTAA NIIN PALJON KUIN JAKSAA. JOS KÄYTTÄJÄ ON SISÄLLÄ, VOIDAAN SE TODETA YKSINKERTAISESTI TUTKIMALLA $user-TAULUKKOA: if($user){ //tee jotain }else{ //tee jotain muuta } YLLÄ HAETTIIN KANNASTA KÄYTTÄJÄN id, tunnus JA VIIMEISIN SIVUNLATAUS, JOTKA NIINIKÄÄN LÖYTYVÄT $users-taulukosta: $user['id'], $user['tunnus'] ja $user['last_load'], */ // Tekee käyttäjille taulun MySQL:ään. Voi poistaa ekan sivunlatauksen jälkeen. mysql_query("CREATE TABLE IF NOT EXISTS `{$tbl_users}` ( id int(11) NOT NULL auto_increment, tunnus varchar(50) default NULL, salasana varchar(32) default NULL, email varchar(60) default NULL, last_load timestamp(14) NOT NULL, istunto varchar(32) default NULL, PRIMARY KEY (id), UNIQUE KEY istunto (istunto) )",$lnk); echo '<?xml version="1.0" encoding="iso-8859-1"?>'; ?>
Missä mättää? :S
EDIT: Tuon XML errorin sain poistamalla yla.php:n lopusta tuon echon. Nyt siis toimii, ainakin melkein.
Warning: Cannot modify header information - headers already sent by (output started at C:\xampplite\htdocs\foorumi\yla.php:99) in C:\xampplite\htdocs\foorumi\uusiaihe.php on line 18
Tätä en saa kyllä millään toiseen paikkaan, tai mitään sen edestä pois :S
Rivi 99 on ainakin tuossa koodissa viimeinen rivi, joten luultavasti tiedostosi lopussa on ylimääräisiä rivinvaihtoja PHP-koodin ulkopuolella eli sulkutagin ?> jälkeen. Voit korjata asian ottamalla sulkutagin pois koodin lopusta (tämä ei ole syntaksivirhe), jolloin tiedosto käsitellään PHP:nä loppuun asti eikä mitään rivinvaihtoja tulosteta.
Metabolix kirjoitti:
Rivi 99 on ainakin tuossa koodissa viimeinen rivi, joten luultavasti tiedostosi lopussa on ylimääräisiä rivinvaihtoja PHP-koodin ulkopuolella eli sulkutagin ?> jälkeen. Voit korjata asian ottamalla sulkutagin pois koodin lopusta (tämä ei ole syntaksivirhe), jolloin tiedosto käsitellään PHP:nä loppuun asti eikä mitään rivinvaihtoja tulosteta.
Hee, nyt toimii :)
Nyt sivulla on seuraavat asiat:
- Kirjautuminen ja rekisteröitymnen:
Kirjautuneena voi ainoastaan luoda aiheen, vastata aiheeseen, katsella jäseniä tai niiden profiileja.
- Oma sivu:
Omalla sivulla on oikea nimi, email, kotisivut, paikkakunta jne..
Tuohon vielä sitten ne perusominaisuudet kuten viestien lähetys tms.
Vielä joitain hienouksia puuttuu.
EDIT: Nyt tarvitsisin seuraavan laisen jutun. Tämä on hiukan ehkä vaikea minun tehdä, kun en viittaa mihinkään ID numeroilla, paitsi käyttäjiin...
Pitäisi saada sellainen koodi, joka tarkistaa, että jos on yli 20 viestiä, niin seuraava tulee toiselle sivulle.
Nyt kun en ole pahemmin mitään ihmeellistä sinne tehnyt, niin voisin muokata niin, että viitattaisiinkin ID:llä eikä nimellä. En vain osaa laskea sitä ID numeroa.
Pitäisi kahdesta taulusta (viestit ja vastaukset) lukea rivimäärä ja lisätä lukuun 1 kun vastataan/luodaan aihe.
-MIB
Ihan hyvin voit sille tietokannalle sanoa montako tulosta haluat sieltä ulos ja mistä kohdasta tulosjoukkoa LIMIT-avainsanan avulla. Ensimmäinen luku on offset (monennesko rivi on ensimmäinen mukaan otettava, indeksointi alkaa nollasta) ja jälkimmäinen on montako riviä otetaan mukaan.
SELECT halutut, sarakkeet FROM taulu WHERE ketju = mitäonkaan ORDER BY aikaleima LIMIT (sivunumero * 20), 20;
Samin tapa on oikea. Se vaatii, että ketjutauluun on talletettu viimeisimmän uusimman viestin aikaleima, mikä on hyvä tapa tehdä tämä. Onnistuu tämä niinkin, että aika on tallennettu vain viestitauluun, mutta silloin kyselystä tulee monimutkaisempi ja (suurilla viestimäärillä) hitaampi.
Toinen juttu: uusiaihe.php:ssä unohdat käyttää mysql_real_escape_string
:iä.
Lisäksi nuo kaksi inserttiä pitäisi oikeasti tehdä transaktiossa. Näiden kahden virheen tiimoilta tekee mieli linkata tähän.
Taitaa olla niin, että se nopeus ero on aika marginaalinen jos käytetään LIMITtiä rajoittamaan hakutuloksien määrää joka tapauksessa.
Selvä, entä tämä ID numero juttu jokaiselle viestille?
alue.php?aihe=Aiheen nimi sijasta otettaisiinkin alue.php?aiheid=aiheennumero&viestiid=viestinumero
Miten kuuluisi tehdä?
Mikä siinä on ongelmana? Olethan jo käyttänyt ID:tä käyttäjille ihan oikein.
Käyttäjien rekisteröityminen ja kirjautuminen perustuu tähän koodivinkkiin.
Teet niin, että saat aiheen numeron php:ltä, kun aihetta klikataan ja haet kannasta viestit, jotka liittyy kyseiseen aiheeseen (aihe_id:seen) ja tulostat ne.
TeNDoLLA kirjoitti:
Teet niin, että saat aiheen numeron php:ltä, kun aihetta klikataan ja haet kannasta viestit, jotka liittyy kyseiseen aiheeseen (aihe_id:seen) ja tulostat ne.
Kyllä osaan tehdä tuon, mutta kun viittaan sisältöön nimen perusteella, niin en käyttänyt aikaa tallentaakseni aihe_id:tä ja viesti_id:tä oikein. Kummankin arvot ovat aina 1.
Siinä tapauksessa sulla on kannan uudelleen suunnittelua edessä. Ainakin suosittelisin sitä, koska aiheen nimen perusteella ei ole kovin järkevää viitata jo senkin takia, että nimi voi olla sama. Millanen sulla on tällä hetkellä se tietokantarakenne ?
kayttajat
----------------------------
kayttaja_id (auto_increment)
kayttaja
passu
aiheet
----------------------------
aihe_id (auto_increment)
aihe
aika
kayttaja_id (viittaa kayttajat tauluun)
viestit
----------------------------
viesti_id (auto_increment)
viesti
aika
aihe_id (viittaa aiheet tauluun)
kayttaja_id (viittaa kayttajat tauluun)
Jotenkin näin pikaisesti sommiteltuna alkaisin itse tekemään tuota. Tässä tapauksessa aiheen ja viestien postaajat haetaan kayttaja_id:n perusteella kayttajat taulusta. Ja aiheeseen liitetään siihen kuuluvat viestit aihe_id:n perusteella.
EDIT: Tätä samaa tyyliä onkin jo viljelty aikaisemminkin tässä threadissa Tonin ja Antin toimesta.
Ajattelin jotain tälläistä:
aiheet: (Jokaisen aiheen nimi ja id tänne) aihe_id (Id, ekalle aiheelle 1, tokalle 2 jne...) otsikko (Aiheen otsikko) viestit: (Jokaisen aiheen ensimmäinen viesti täällä) aihe_id (Tämän perusteella tulostetaan ensimmäinen viesti saman numeroiseen aiheeseen) viesti_id (Tätä tarvitaan muokkaamiseen ja poistoon tms.) otsikko (Aiheen otsikko) lähettäjä_id (Ei varsinaisesti id, vaan nimi, esim Rocceri) aika (xxxxxxxxxx aika) viesti (käyttäjän lähettämä viesti, ensimmäinen aiheessa) vastaukset lähettäjä_id (Lähettäjän tunnus) otsikko (Aiheen otsikko) aika (xxxxxxxxxx aika) viesti (viesti)
Näin on nykyään, mutta nyt viittaan tuolla otsikolla, kun pitäisi id:llä..
Saan tehtyä aika helposti, jos tiedän miten voin laskea taulusta rivien määrä (mysql_num_rows?) ja tulostaa määrän. Saan väännettyä tuosta sitten kaikki tarvittavat..
Katselepa sitä käyttäjätaulua ja tutustu AUTO_INCREMENT-määreeseen hieman tarkemmin. Sitä käyttäessä vasta lisätyn id:n saa mysql_insert_id-funktiolla. Mitään id:tä ei pidä luoda itse epämääräisillä viritelmillä, kun kerran on valmiit välineet juoksevan numeroinnin tekoon.
Metabolix kirjoitti:
Katselepa sitä käyttäjätaulua ja tutustu AUTO_INCREMENT-määreeseen hieman tarkemmin. Sitä käyttäessä vasta lisätyn id:n saa mysql_insert_id-funktiolla. Mitään id:tä ei pidä luoda itse epämääräisillä viritelmillä, kun kerran on valmiit välineet juoksevan numeroinnin tekoon.
Luoko tämä ID:t 1, 2, 3, 4 jne. vai tuommoista hirveää siansakaa?
MIB kirjoitti:
Luoko tämä ID:t 1, 2, 3, 4 jne. vai tuommoista hirveää siansakaa?
Mitä siansaksaa? ID:t alkavat ykkösestä ja kasvavat aina sitä mukaa kun uusi tietue tulee. Samaa ID:tä mikään toinen tietue ei saa, vaikka tietoja poistettaisiin välistä. ID:n on tarkoitus olla tietueen yksilöivä numero, eikä sitä ole mitään syytä pitää esimerkiksi aiheiden määrän kanssa samana.
trilog kirjoitti:
MIB kirjoitti:
Luoko tämä ID:t 1, 2, 3, 4 jne. vai tuommoista hirveää siansakaa?
Mitä siansaksaa? ID:t alkavat ykkösestä ja kasvavat aina sitä mukaa kun uusi tietue tulee. Samaa ID:tä mikään toinen tietue ei saa, vaikka tietoja poistettaisiin välistä. ID:n on tarkoitus olla tietueen yksilöivä numero, eikä sitä ole mitään syytä pitää esimerkiksi aiheiden määrän kanssa samana.
Hups, mun moka. Tota koodia mitä testailin, niin se md5 -cryptasi sen...
Siis, asetan taulun näin? (Aiheet taulu)
mysql_query("CREATE TABLE aiheet (id INT NOT NULL AUTO_INCREMENT, otsikko TEXT) VALUES ('', '$otsikko')");
Md5 ei ole kryptausalgoritmi, vaan hash-algoritmi.
tsuriga kirjoitti:
Md5 ei ole kryptausalgoritmi, vaan hash-algoritmi.
Kirjoitusvirhe.. Tai ajatusvirhe tarkemmin.
Mutta, miten oikeasti teen tämän ID jutun?
MIB kirjoitti:
Mutta, miten oikeasti teen tämän ID jutun?
Siis, mitä epäselvää tuossa enää on. Eli kun luot sen taulun annat sille id-sarakkeelle sen auto_increment lisämääreen. Sitten kun luot uuden tietueen, niin teet sen vaikka näin:
INSERT INTO aiheet (id,otsikko) VALUES ('','Otsikko')
EDIT.
En pistä päätäni pantiksi, mutta tuo käyttämäsi kyselynrakenne
näyttää epäilyttävältä...
MIB kirjoitti:
Siis, asetan taulun näin? (Aiheet taulu)
mysql_query("CREATE TABLE aiheet (id INT NOT NULL AUTO_INCREMENT, otsikko TEXT) VALUES ('', '$otsikko')");
Eli taulun luonnin yhteydessä älä anna sille mitään muita arvoja, paitsi mahdolliset oletusarvot (joiden käytön mahdollisuudesta en tiedä)... Mutta perustietuetta ei kyllä CREATE TABLELLA tehä...
Triton kirjoitti:
INSERT INTO aiheet (id,otsikko) VALUES ('','Otsikko')
Joissakin kannoissa tuo voi jopa toimia (toisissa antaa virheen jos ID on autoincrement ja/tai numero) mutta tyylikkäämmin seuraavasti
INSERT INTO aiheet (otsikko) VALUES ('Otsikko')
Grez kirjoitti:
Triton kirjoitti:
INSERT INTO aiheet (id,otsikko) VALUES ('','Otsikko')Joissakin kannoissa tuo voi jopa toimia (toisissa antaa virheen jos ID on autoincrement ja/tai numero) mutta tyylikkäämmin seuraavasti
INSERT INTO aiheet (otsikko) VALUES ('Otsikko')
Itselläni tuo on aina toiminut kun MySQL:llää olen käyttänyt, mutta täytyy tehdä seuraavalla kerralla tehdä kertomallasi tavalla...
Triton kirjoitti:
Siis, mitä epäselvää tuossa enää on.
En tarkoita tätä. Pitäisi siis nyt ensin tehdä tuo taulu... :p
mysql_query("CRATE TABLE aiheet ( id INT NOT NULL AUTO_INCREMENT, otsikko TEXT, PRIMARY KEY (id) )");
Noin en saanut toimimaan. Miten kuuluu luoda siis taulukko, jossa on id ja otsikko?
Alla on tuosta mun ehdottamasta rakenteesta taulujen luonti koodit, vähäsen testi dataa inserttien muodossa ja lopuksi vielä esimerkki kyselyt miten niitä datoja voi mm. hakea tuolta sitten php:lla työstettäväksi.
CREATE TABLE `kayttajat` ( `kayttaja_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `kayttaja_nimi` varchar(255) NOT NULL, PRIMARY KEY (`kayttaja_id`) ); ENGINE=InnoDB CREATE TABLE `aiheet` ( `aihe_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `aihe` varchar(255) NOT NULL, `aika` DATETIME, `kayttaja_id` int(11) unsigned NOT NULL, PRIMARY KEY (`aihe_id`), FOREIGN KEY (kayttaja_id) REFERENCES kayttajat(kayttaja_id) ON UPDATE CASCADE ON DELETE RESTRICT ); ENGINE=InnoDB CREATE TABLE `viestit` ( `viesti_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `viesti` TEXT NOT NULL, `aika` DATETIME, `kayttaja_id` int(11) unsigned NOT NULL, `aihe_id` int(11) unsigned NOT NULL, PRIMARY KEY (`viesti_id`), FOREIGN KEY (aihe_id) REFERENCES aiheeet(aihe_id) ON UPDATE CASCADE ON DELETE RESTRICT, FOREIGN KEY (kayttaja_id) REFERENCES kayttajat(kayttaja_id) ON UPDATE CASCADE ON DELETE RESTRICT ); ENGINE=InnoDB /* Testi dataa, lisätään muutema käyttäjää */ INSERT INTO kayttajat (kayttaja_nimi) VALUES ('Useri1'); INSERT INTO kayttajat (kayttaja_nimi) VALUES ('Useri2'); INSERT INTO kayttajat (kayttaja_nimi) VALUES ('Useri3'); /* Lisätään userin yksi (jonka id pitäs olla nyt 1 tässä vaiheessa) tekemä aihe aiheisiin */ INSERT INTO aiheet (aihe, kayttaja_id, aika) VALUES ('Userin 1 tekemä aihe', 1, NOW()); /* Lisätään aiheeseen vastaukset userilta 2 ja 3 */ INSERT INTO viestit (viesti, aika, kayttaja_id, aihe_id) VALUES ('Eka viesti aiheeseen', NOW(), 2, 1); INSERT INTO viestit (viesti, aika, kayttaja_id, aihe_id) VALUES ('Toka viesti aiheeseen', NOW(), 3, 1); /* Alla olevalla kyselyllä haetaan aiheet ja niiden aloittajat uusimmasta vanhimpaan */ SELECT a.aihe, a.aika, k.kayttaja_nimi AS aloittaja FROM aiheet a LEFT JOIN kayttajat k ON k.kayttaja_id = a.kayttaja_id ORDER BY a.aika DESC /* Alla olevalla kyselyllä haetaan johonkin aiheeseen liittyvät viestit ja niiden postaajien kayttaja nimet */ SELECT v.viesti, v.aika, k.kayttaja_nimi FROM viestit v LEFT JOIN aiheet a ON a.aihe_id = v.aihe_id LEFT JOIN kayttajat k ON k.kayttaja_id = v.kayttaja_id WHERE v.aihe_id = 1 ORDER BY a.aika DESC
MIB kirjoitti:
Noin en saanut toimimaan. Miten kuuluu luoda siis taulukko, jossa on id ja otsikko?
Siis se taulu luodaan, vaikka näin:
CREATE TABLE aiheet (id int unsigned auto_increment not null primary key, otsikko varchar(100))
Triton kirjoitti:
Siis se taulu luodaan, vaikka näin:
CREATE TABLE aiheet (id int unsigned auto_increment not null primary key, otsikko varchar(100))
Kiitos! Näin tämä toimii mahtavasti. Nytten vähän lisään tuohon tavaraa, ja saan ID:n perusteella kaikki toimimaan. :) Sitten saan toimimaan muokkaus ja poisto koodit.
EDIT: Jostain kumman syystä tämä ei toimi:
mysql_query("CREATE TABLE viestit(aihe_id int unsigned auto_increment not null primary key, viesti_id int unsigned auto_increment not null primary key, otsikko varchar(100), lähettäjä_id TEXT, aika INT, viesti varchat(100))");
Kannattaa ehkä lueskella niitä MySQL:n virheilmoituksia sekä omaa koodia.
MIB kirjoitti:
varchat
Myöskään primary keytä ei pidä käyttää kahdessa kohti, vaan aihe_id:n kuuluisi oikeammin olla foreign key, joka viittaa aihetauluun. (Laiskat jättävät foreign keyt kokonaan pois.) Lisäksi lähettäjän pitäisi olla INT ja viestin maksimipituuden luultavasti enemmän kuin 100 merkkiä. Ääkkösiäkään ei moni suosi tietokannoissa, voivat aiheuttaa ikäviä merkistöongelmia.
On tuossa muitakin virheitä. Primary keytä voi olla yksi per taulu tietääkseni ja nyt yrität laittaa kahta primary keytä. Kahdesta kentästä yhdessä voi tehdä primary keyn kyllä mutta sen tekeminen ei tapahdu noin.
Lisäksi auto_increment voi olla vain yhdessä columnissa myös, joka taas pitää olla määritetty keyksi.
edit: Keele Metabolix koko ajan ehtii ennemmin :)
TeNDoLLA kirjoitti:
On tuossa muitakin virheitä. Primary keytä voi olla yksi per taulu tietääkseni ja nyt yrität laittaa kahta primary keytä. Kahdesta kentästä yhdessä voi tehdä primary keyn kyllä mutta sen tekeminen ei tapahdu noin.
Lisäksi auto_increment voi olla vain yhdessä columnissa myös.
No muttah, miten sitten teen tämän? :S Nyt meni mulla tosi korkealta yli.
Muokattu suoraan tuosta sun versiosta
mysql_query("CREATE TABLE viestit(aihe_id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, viesti_id INT UNSIGNED NOT NULL, otsikko varchar(255), lahettaja_id INT, aika DATETIME, viesti TEXT)");
Samalla aihe_id:llä yleensä tulee monta viestiä, joten oikea muoto aiheille ja viesteille olisi kuitenkin tämä:
CREATE TABLE aiheet( aihe_id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, otsikko VARCHAR(255) ); CREATE TABLE viestit( viesti_id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, aihe_id INT UNSIGNED NOT NULL, lahettaja_id INT, aika DATETIME, viesti TEXT );
Ennen toimi jotenkin, mutta nyt ei mene ollenkaan. Pitänee kirjoittaa nuo pari koodia ihan uudelleen :S
Hieman offtopic, mutta ihmettelen miksihän täällä ei ole SQL:lle omaa syntaksi väritystä.
Nyt tulee seuraava error: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 7"
Koodi
<?php $yhteys = mysql_connect("localhost", "root", ""); mysql_select_db("forum"); mysql_query("CREATE TABLE viestit( viesti_id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, aihe_id INT UNSIGNED NOT NULL, lahettaja_id TEXT, aika INT, viesti TEXT, )") or die(mysql_error()); mysql_close($yhteys); ?>
Pilkku pois viimeisen kentän perästä.
Kiitos.
Hmm... Jotain vaikeuksia koodini kanssa. Ainoastaan yksi virhe enään, sitten toimii kaikki :) (Tulee vielä lisää toimintoja)
Virhe on se, että kun kirjoitan aihetta:
<?php include("yla.php"); $yhteys = mysql_connect("localhost", "root", ""); mysql_select_db("forum", $yhteys); ///////////////////////////////////////////////////////////////////////////////// //////////Tässä ei saa tehdä mitään muutoksia kuin if -lauseen sisään! ////////// ///////////////////////////////////////////////////////////////////////////////// $viesti = $_POST["viesti"]; $aika = time(); $lahettaja = $user['tunnus']; $otsikko = $_POST["otsikko"]; //BBcode functiot function bbcode_format($var) { $search = array( '/\[b\](.*?)\[\/b\]/is', '/\[i\](.*?)\[\/i\]/is', '/\[u\](.*?)\[\/u\]/is', '/\[url\](.*?)\[\/url\]/is', '/\[url\=(.*?)\](.*?)\[\/url\]/is' ); $replace = array( '<strong>$1</strong>', '<em>$1</em>', '<u>$1</u>', '<a href="$1">$1</a>', '<a href="$1">$2</a>' ); $var = preg_replace ($search, $replace, $var); return $var; } //Kutsutaan bbcodea $viesti = bbcode_format($viesti); if (!empty($viesti) && !empty($otsikko)) { $kirjoita_aihe = "INSERT INTO aiheet (otsikko, lahettaja, aika) VALUES ('$otsikko', '$lahettaja', '$aika')"; $kirjoita_viesti = "INSERT INTO viestit(aihe_id, lahettaja_id, aika, viesti) VALUES ('$aiheid', '$lahettaja', '$time', '$viesti')"; mysql_query($kirjoita_aihe, $yhteys); mysql_query($kirjoita_viesti, $yhteys); } mysql_close($yhteys); header("Location: alue.php?aiheid=$aiheid"); ?>
Niin, en ole keksinyt miten haen uusimman aiheen (mikä luodaan ennen viestiä) ID:n ja laitan sen $aiheid muuttujaan.
<?php $query = "SELECT aihe_id FROM aiheet ORDER BY aika DESC LIMIT 1"; $result = mysql_query($query); $result = mysql_fetch_assoc($result); $aiheId = $result['aihe_id']; ?>
ps. en testannut.
TeNDoLLA kirjoitti:
<?php $query = "SELECT aihe_id FROM aiheet ORDER BY aika DESC LIMIT 1"; $result = mysql_query($query); $result = mysql_fetch_assoc($result); $aiheId = $result['aihe_id']; ?>ps. en testannut.
"
Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in C:\xampplite\htdocs\foorumi\setid.php on line 7
"
FOR silmukalla saan tehtyä, joka nyt ei ole maailman viisain tapa.
Parempia tapoja voi ilmoittaa :)
Mikäli virheilmoitus vaatii suomennosta niin se sanoopi, notta "annettu argumentti ei ole kelvollinen MySQL-tulosresurssi", ts. mysql_query
on epäonnistunut, mikä kyllä pitäisi löytyä tulostuneista virheilmoituksista tai logeista.
tsuriga kirjoitti:
Mikäli virheilmoitus vaatii suomennosta niin se sanoopi, notta "annettu argumentti ei ole kelvollinen MySQL-tulosresurssi", ts.
mysql_query
on epäonnistunut, mikä kyllä pitäisi löytyä tulostuneista virheilmoituksista tai logeista.
No, tuli nyt tehtyä FOR silmukalla:
<?php $yhteys = mysql_connect("localhost", "root", ""); mysql_select_db("forum"); $query = "SELECT aihe_id FROM viestit ORDER BY aika DESC LIMIT 1"; $result = mysql_query($query); for ($i = 0; $i < mysql_num_rows($result); $i++) { $id = mysql_result($result, $i, "aihe_id"); } echo $id; mysql_close($yhteys); ?>
EDIT:
Eipäs toimikkaan näin. Huomasin äsken. Miten kannattaisi tehdä? :p
Kandee laittaa toi tulostus tonne silmukan sisään.
ajv kirjoitti:
Kandee laittaa toi tulostus tonne silmukan sisään.
Enpä tiedä, ei se toimi siltikään oikein.
Voisinkos tehdä sen jotenkin muuten? For silmukka ei ole ihan paras vaihtoehto mielestäni.
Annoin jo aiemmin tässä keskustelussa while-silmukan tulosten hakemiseen.
<?php $y = mysql_connect("localhost", "root", ""); mysql_select_db("forum"); $kysely = "SELECT * FROM aiheet ORDER BY aika DESC"; $hae = mysql_query($kysely, $y) or die(mysql_error()); while ($rivi = mysql_fetch_assoc($hae)) { // Taulukossa ovat kätevästi kaikki hakutuloksen tiedot. $id = $rivi["aihe_id"]; echo $id; } mysql_close($y); ?>
Ei tulosta mitään...
Kyllä tähän ei mitään looppeja tarvita.
$kirjoita_aihe = "INSERT INTO aiheet (otsikko, lahettaja, aika) VALUES ('$otsikko', '$lahettaja', '$aika')"; mysql_query($kirjoita_aihe, $yhteys); $aiheid = mysql_insert_id($yhteys); $kirjoita_viesti = "INSERT INTO viestit(aihe_id, lahettaja_id, aika, viesti) VALUES ('$aiheid', '$lahettaja', '$time', '$viesti')"; mysql_query($kirjoita_viesti, $yhteys);
$aiheid = mysql_insert_id($yhteys);
Mitä tämä perjaatteessa tekee? Minusta tuo ei hae tuota tietoa sitten mistään.
EDIT: Hups, mun moka.. Toi Metabolixin juttu toimi hyvin, mutta hain väärän nimistä id:tä.
Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
Hakee siis edellisen insertin auto_increment kolumnin arvon.
opt kirjoitti:
Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
Hakee siis edellisen insertin auto_increment kolumnin arvon.
Sittenhän tämäkin on kätevä.
On se kätevä niin kauan kun olet viimeksi INSERTannu nimenomaan siihen aihe tauluun, mutta jos inserttaatkin välissä johonkin muuhun tauluun, jossa on ID myös niin se hakeekin sieltä sen viimeisimmän ID:n eikä aiheista. Tuo mun laittama ratkaisu oli tarkotettu toimivaksi näin yleisellä tasolla riippumatta edellisestä kyselystä. Tosin sun tapauksessa se edellinen kysely nyt sattuu juuri olemaan se aiheet taulun insertti.
Ja kyllä tämä toimii täysin. Mulle ainakin tulee se uusin aihe_id tuonne $aiheId muuttujan ja nyt testasinkin tämän.
<?php $query = "SELECT aihe_id FROM aiheet ORDER BY aika DESC LIMIT 1"; $result = mysql_query($query); $result = mysql_fetch_assoc($result); $aiheId = $result['aihe_id']; echo $aiheId // Echo lisätty edelliseen esimerkkiin vain.. ?>
Edit1: Ilmeisesti sulla ei se mysql_query toiminut tuossa, koska ei palauttanut oikeata mysql resurssia ? Eli jos copy&pastesit suoraan tuon sinne, niin ootko varma, että sulla on taulun nimet kannassa se 'aiheet' sekä kentän nimet 'aihe_id' ja 'aika' täsmälleen eikä melkein mitä käytät tuossa kyselyssä? Ootko avannut ennen tuota mysql yhteyden mysql_connectilla ja valinnat myös kannan mysql_select_db:llä?
MIB sanoi kaksi keskenään ristiriitaista tarvetta:
"Niin, en ole keksinyt miten haen uusimman aiheen (mikä luodaan ennen viestiä) ID:n ja laitan sen $aiheid muuttujaan."
Eli tarpeet olivat:
1) Uusimman aiheen Id:n hakeminen
2) Sen aiheen Id:n hakeminen, joka juuri luotiin
TeNDoLLA:n ratkaisu toteuttaa kohdan 1.
Sen sijaan kun MIB haluaa luoda aiheen ja siihen aiheeseen liittyvän viestin, niin hän tarvitsee vaihtoehdon 2, eli insert_id on oikea vaihtoehto.
Se on totta juu. Ajattelin vain vielä varmistaa, että meni perille miten se toimii, koska on tuntunut tässä threadin edetessä että OP on aika pihalla.
edit: tosin nyt kun kattoo niin ihan turhaa motkotusta.. kyllähän se lukee selvällä englannin kielelläkin jo tuossa aiemmin :)
ps. vasta herännyt...
ps2. OT: Grez ollut kesälomilla kun ei ole vastaillut aikoihin?
Miten tämä lainaus juttu kannattaa tehdä? Tein niin, että koodi tekee BBcoden (Tämä toimii, ja lainaus linkistä tulee sisältö kyllä lainaus tagien väliin)
[lainaus "Keneltä"]Viesti käyttäjältä[/lainaus]
Mutta, en osaa korvata näitä HTML merkinnällä.
Muut BBcode tagit teen näin:
function bbcode_format($var) { $search = array( '/\[b\](.*?)\[\/b\]/is', '/\[i\](.*?)\[\/i\]/is', '/\[u\](.*?)\[\/u\]/is', '/\[url\](.*?)\[\/url\]/is', '/\[url\=(.*?)\](.*?)\[\/url\]/is', ); $replace = array( '<strong>$1</strong>', '<em>$1</em>', '<u>$1</u>', '<a href="$1">$1</a>', '<a href="$1">$2</a>', ); $var = preg_replace ($search, $replace, $var); return $var; }
MIB kirjoitti:
Miten tämä lainaus juttu kannattaa tehdä? Tein niin, että koodi tekee BBcoden (Tämä toimii, ja lainaus linkistä tulee sisältö kyllä lainaus tagien väliin)
[lainaus "Keneltä"]Viesti käyttäjältä[/lainaus]Mutta, en osaa korvata näitä HTML merkinnällä.
Kopioitu suoraan Ohjelmointiputkan lähdekoodista lisättynä tuohon BB-code -funktioon:
<?php function bbcode_format($var) { $search = array( '/\[b\](.*?)\[\/b\]/is', '/\[i\](.*?)\[\/i\]/is', '/\[u\](.*?)\[\/u\]/is', '/\[url\](.*?)\[\/url\]/is', '/\[url\=(.*?)\](.*?)\[\/url\]/is', '/\[lainaus "(.*?)"\](.*?)\[\/lainaus\]/is', ); $replace = array( '<strong>$1</strong>', '<em>$1</em>', '<u>$1</u>', '<a href="$1">$1</a>', '<a href="$1">$2</a>', '<i><small>$1 kirjoitti:</small></i><br><div style="border-style:solid;border-width:1px;background:#E4E9FF;margin-left:8px">$2</div>', ); $var = preg_replace ($search, $replace, $var); return $var; } ?>
Kun kiellän viesteissä HTML merkinnät, niin miten voin sallia, että lainauksissa kaikki on sallittu?
Miksi ne pitäisi lainauksissa sallia? Eihän viestin rakennetta muuteta, kuin tulostuksen aikana.
Teuro kirjoitti:
MIB kirjoitti:
Kun kiellän viesteissä HTML merkinnät, niin miten voin sallia, että lainauksissa kaikki on sallittu?
Miksi ne pitäisi lainauksissa sallia?
Koska, jostain syystä esimerkiksi viesti
Moi Mitä kuuluu?
tulostuu
käyttäjä kirjoitti:
Moi
<br>
<br>Mitä kuuluu?
ja jos siinä on muita BBcode tageja, niin ne tulostuvat myös <b>, <a href=""></a> jne.
Kun tuon saa toimimaan, niin olisi kiva olla myös sellainen, että viestiä ei muuteta HTML muotoon ennen kirjoitusta vaan sen tulostuksen aikana tai kun vastaus lainataan, niin siinä ei lukisi suoraan <a href=""></a> tai mitään muuta, vaan se BBcode tagi.
Sen takia pitäisi sallia HTML, kun BBcode tagit ovat HTML muodossa kannassa.
Eikö lainaus kannata hakea tietokannasta, jossa lainattu viesti on tietenkin ilman muunnettuja bb-codeja eikös vain?
Teuro kirjoitti:
Eikö lainaus kannata hakea tietokannasta, jossa lainattu viesti on tietenkin ilman muunnettuja bb-codeja eikös vain?
Sitähän tuossa viestissäni mainitsin, mutta miten tulostaessa ne korvataan sitten? Kun tulostan viestin tietyssä kohtaa muuttujassa $viesti, niin laitanko ennen tulostusta tuon minun BBcode muunto jutun? (Minkä trilog postasi tuohon)
Erillisellä muunosfunktiolla kannattaa lähteä liikkeelle. Tällä tavalla saat muutettua tarvottaessa hyvinkin helposti viestien ulkoasuakin.
Teuro kirjoitti:
Erillisellä muunosfunktiolla kannattaa lähteä liikkeelle. Tällä tavalla saat muutettua tarvottaessa hyvinkin helposti viestien ulkoasuakin.
Okei, mutta tämä yllämainitsemani tapa toimii?
Joo, kyllä sain toimimaan nyt ;)
Hitsi kun menee toi muokkaus aika umpeen näin nopeesti. Mutta niin.
Tuo trilogin BBcode juttu toimii hyvin, mutta se ei osaa sellaista asiaa, kuin kaiksi lainausta sisäkkäin. Kahdella lainauksella sisäkkäin käy näin:
Miten korjaisin?
Googlella löyty samoja ongelmia jollain muillakin, löysin jonkun pätkän jota muokkasin vähän. Takuuseen en mene miten tää toimii esim. auki jätettyjen tagien kanssa, mutta toimi ainakin tuossa sun esimerkissäs.
<?php function bbcode_format($var) { $search = array( '/\[b\](.*?)\[\/b\]/is', '/\[i\](.*?)\[\/i\]/is', '/\[u\](.*?)\[\/u\]/is', '/\[url\](.*?)\[\/url\]/is', '/\[url\=(.*?)\](.*?)\[\/url\]/is', '/\[lainaus\](.*?)/is', '/\[lainaus "(.*?)"\](.*?)/is', '/\[\/lainaus\]/is', ); $replace = array( '<strong>$1</strong>', '<em>$1</em>', '<u>$1</u>', '<a href="$1">$1</a>', '<a href="$1">$2</a>', '<div style="background:#F8F8F8;border:1px solid #E4E4E4;">$1', '<div style="background:#F8F8F8;border:1px solid #E4E4E4;"><b>by$1</b><br/>$2', '</div>', ); $var = preg_replace ($search, $replace, $var); return $var; } ?>
Edit: Eli eronahan tuossa on vain se, että lainauksen avaus ja lukitus tagit käsitellään erikseen sen sijaan, että käsittelet tuossa aikaisemmin samassa molemmat.
Toi ainakin toimii, mutta menee hetki muokata oikeen näkönen. :S
EDIT: Voiko lähettää POSTIlla tavaraa ilman lomaketta?
Ärsyttää, kun menee näin nopeesti lukkoon toi editointi... :S
Niin, yks juttu viellä.
Jos haluan siinä järjestyksessä aiheet, kun niihin viimeinen viesti on lähetetty, niin mitä kuuluisi lisätä?
SELECT * FROM aiheet ORDER BY _______________
Ajattelin, että se katsoo, että mikä on uusimman viestin aika, sitten katsoo aihe_id:n ja sitten laittaa oikeaan järjestykseen. En vaan tiedä miten kuuluu tarkistaa, tai oikeastaan miten se kysely menisi.
Saat sen helpoimmalla ehkä, kun teet kyselyn, jossa ryhmittelet viestit aihei_id:n perusteella ryhmiksi. Lopuksi järjestelet kyselyn lähetysajan mukaan laskevaan järjestykseen.
Teuro kirjoitti:
Saat sen helpoimmalla ehkä, kun teet kyselyn, jossa ryhmittelet viestit aihei_id:n perusteella ryhmiksi. Lopuksi järjestelet kyselyn lähetysajan mukaan laskevaan järjestykseen.
Kuten sanoin, nuo SQL lauseet ovat hakusessa.
Ryhmittelen? Siis, GROUP BY?
MIB kirjoitti:
Kuten sanoin, nuo SQL lauseet ovat hakusessa.
Tekemällä oppii ja siperia opettaa.
MIB kirjoitti:
Ryhmittelen? Siis, GROUP BY?
Kyllä.
DATE_FORMAT?
Tarkoittaako tämä sitä, että aika olisi DATEna tuolla tietokannassa?
En saanut toimimaan
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampplite\htdocs\foorumi\groupby.php on line 20
:S
MIB kirjoitti:
DATE_FORMAT? Tarkoittaako tämä sitä, että aika olisi DATEna tuolla tietokannassa? En saanut toimimaan
Kyllä kai päivämäärät kannattaa pitää ihan timestamppina kannassa, jolloin tuo DATE_FORMAT(time, format) funktio osaa käsitellä tuota oikein. Millainen virhe mysql_error() funktion mukaan tuolla on? Monasti se osaa kertoa aika tarkkaan virheestä. Selvää lienee kuitenkin, että ainakin osa kenttien nimistä lienee väärin.
Jos en ihan väärin muista, niin taitaa olla INT tyyppisinä MIBillä nuo aika kentät, joten eikös se silloin toimis muuten samaan tyyliin, mutta ilman tuota DATE_FORMATia.
TeNDoLLA kirjoitti:
Jos en ihan väärin muista, niin taitaa olla INT tyyppisinä MIBillä nuo aika kentät, joten eikös se silloin toimis muuten samaan tyyliin, mutta ilman tuota DATE_FORMATia.
INTnä on joo, katon jos saan tuon toimimaan.
<?php $y = mysql_connect("localhost", "root", ""); mysql_select_db("forum"); $kysely = " SELECT id, aika, otsikko FROM aiheet GROUP BY id ORDER BY aika DESC"; $tulokset = mysql_query($kysely) or die(mysql_error()); /* Tulostaminen */ while($rivi = mysql_fetch_array($tulokset)){ echo $rivi['aika'] . " " . $rivi['otsikko'] . "<br />"; } mysql_close($y); ?>
Tuo toimii melkein, mutta ei katso uusinta viestiä vielä, vaan uusimman aiheen. :D Muunnan vähän niin toimii.
Ei onnistu.
Aiheet taulu on tämmöinen:
id
otsikko
aika
viesti
Ja viestit taulu
viesti_id
aihe_id
lahettaja
aika
viesti
Joten, miten katson uusimman ajan viesteistä, ja järjestelen siten tuon aihe listan. (Ei aiheet taulua, vaan lista sivulla)
En saa tehtyä tuolla esimerkilläsi, kun viesteissä ei ole otsikkoa.
Suunnilleen tälleen (en testannut, mutta idea selvinnee vaikkei ihan toimisikaan)
SELECT a.id, a.otsikko, Max(v.aika) ViimeisinViesti FROM Aiheet a JOIN viestit v ON (v.aihe_id=a.id) GROUP BY a.id, a.otsikko ORDER BY Max(v.aika) DESC
Grez kirjoitti:
Suunnilleen tälleen (en testannut, mutta idea selvinnee vaikkei ihan toimisikaan)
SELECT a.id, a.otsikko, Max(v.aika) ViimeisinViesti FROM Aiheet a JOIN viestit v ON (v.aihe_id=a.id) GROUP BY a.id, a.otsikko ORDER BY Max(v.aika) DESC
Muutama kysymys:
1. Mitä nuo a ja v kirjaimet vaikuttavat tuolla?
2. Mikä tuo ViimeisinViesti juttu on, tai oikeastaan mitä siihen kuuluu laittaa? En usko että tekee mitään noin?
MIB kirjoitti:
Muutama kysymys:
1. Mitä nuo a ja v kirjaimet vaikuttavat tuolla?
2. Mikä tuo ViimeisinViesti juttu on, tai oikeastaan mitä siihen kuuluu laittaa? En usko että tekee mitään noin?
Kumpaankin vastaus on että ne ovat aliaksia. Ensin annetaan tuolle Max-arvolle nimeksi ViimeisinViesti, ja taulut nimetään a:ksi ja v:ksi. Nimeäminen vaikuttaa sitten itse kyselyyn, sekä palautettaviin tuloksiin.
JTS kirjoitti:
MIB kirjoitti:
Muutama kysymys:
1. Mitä nuo a ja v kirjaimet vaikuttavat tuolla?
2. Mikä tuo ViimeisinViesti juttu on, tai oikeastaan mitä siihen kuuluu laittaa? En usko että tekee mitään noin?Kumpaankin vastaus on että ne ovat aliaksia. Ensin annetaan tuolle Max-arvolle nimeksi ViimeisinViesti, ja taulut nimetään a:ksi ja v:ksi. Nimeäminen vaikuttaa sitten itse kyselyyn, sekä palautettaviin tuloksiin.
Okei.
KIITOS GREZ! Tuo toimii ilman mitään muokkausta tuonne koodiin :)
Muokkasin niin, että toimii minulla oikeassa kohtaa:
SELECT a.id, a.otsikko, a.lahettaja, v.aika, Max(v.aika) ViimeisinViesti FROM Aiheet a JOIN viestit v ON (v.aihe_id=a.id) GROUP BY a.id, a.otsikko ORDER BY Max(v.aika) DESC
Nyt vain on seuraavan lainen ongelma. Kun haluaisin, että järjestyksen lisäksi olisi "Viimeinen viesti" kohta taulukossa, niin miten kannattaisi toteuttaa?
***keskustelu.php <?php require_once("settings.php"); $yhteys = mysql_connect("$dbserver", "$dbuser", "$dbpw") or die(mysql_error()); mysql_select_db("$db", $yhteys) or die(mysql_error()); $kysely = "SELECT a.id, a.otsikko, a.lahettaja, v.aika, Max(v.aika) ViimeisinViesti FROM Aiheet a JOIN viestit v ON (v.aihe_id=a.id) GROUP BY a.id, a.otsikko ORDER BY Max(v.aika) DESC"; $haku = mysql_query($kysely, $yhteys) or die(mysql_error()); echo '<table class="teksti" width="95%" cellspacing="0">'; echo '<tr class="taulukkoyla"> <td width="50%"><b>Aiheen otsikko</b></td> <td width="30%"><b>Aloittaja</b></td> <td><b>Aloitusaika</b></td></tr>'; //Käydään kaikki aiheet läpi, ja laitetaan tiedot muuttujiin. for ($i = 0; $i < mysql_num_rows($haku); $i++) { $aihe_id = mysql_result($haku, $i, "id"); $aloittaja = mysql_result($haku, $i, "lahettaja"); $aika = mysql_result($haku, $i, "aika"); $otsikko = mysql_result($haku, $i, "otsikko"); //Siistitään aika $siistittyaika = date("d.m.y H:i:s", $aika); //Tulostetaan aiheet. echo "<tr><td><a href=\"alue.php?aiheid=$aihe_id\">$otsikko</a></td><td><a href=\"profiili.php?tunnus=$aloittaja\">$aloittaja</a></td><td>$siistittyaika</td></tr>"; } echo "</table><br><hr>"; echo '<div style="padding-left: 15px">'; if($user) { ?> <form action="uusiaihe.php" method="post"> <b>Otsikko:</b><br><input type="name" name="otsikko"> <br><br><b>Viesti:</b><br><textarea name="viesti" cols="80" rows="15"></textarea><br><br> <input type="submit" value="Luo aihe"> </form> <?php } else echo "Sinun pitää kirjatua sisään aloittaaksesi aiheen!"; ?> </div>
Tuossa nyt vielä se koodi mihin tuo järjestys kysely tulee.
Tietokantojen (aiheet & viestit) rakenteet laitoinkin jo tuossa aikaisemmin.
Ajattelin tehdä uuden kyselyn, jossa ryhmittelen aihe_id:n perusteella viestit, ja tulostan aina oikean aiheen kohdalla viimeisimmän viestin lähettäjän ja ajan, milloin on postannut viestin. Toteutus vain uupuu.
Toki tuossa on montakin tapaa. Itse hyödyntäisin varmaan sitä seikkaa, että viestit ovat myös Id:n puolesta aikajärjestyksessä.
En saa millään tuota tehtyä. Vaikea juttu. :S
EDIT: Onnistuisiko näin?
SELECT aika, lahettaja_id, aihe_id FROM viestit GROUP BY aihe_id ORDER BY aika DESC LIMIT 1
Sitten vaan hoidetaan muut tulostukset.
Itse ajattelin että teen viewn ja sitten käytän sitä kyselyssä, mutta MySQL:ssä testaaminen kaatuu siihen että mulla ei näköjään ole Create View oikeutta palveluntarjoajan MySQL:ssä enkä nyt jaksa asentaa omalle koneelle.
Anyways, jotain tällaista ajattelin:
CREATE VIEW AiheetViimeisinViesti AS SELECT a.id, a.otsikko, Max(v.viesti_id) viesti_id FROM Aiheet a JOIN viestit v ON (v.aihe_id=a.id) GROUP BY a.id, a.otsikko
ja sitten itse kysely
SELECT a.id, a.otsikko, v.lahettaja, v.aika, v.viesti FROM AiheetViimeisinViesti a LEFT JOIN viestit v ON a.viesti_id=v.viesti_id ORDER BY a.id
En kyllä haluaisi kirjoittaa aiheet taulua uudelleen, kun muitakin tapoja on toteuttaa tämä.
<?php $y = mysql_connect("localhost", "root", ""); mysql_select_db("forum"); $kysely = " SELECT aika, lahettaja_id, aihe_id, viesti, viesti_id FROM viestit GROUP BY viesti_id ORDER BY viesti_id DESC LIMIT 1"; $haku = mysql_query($kysely) or die(mysql_error()); while($rivi = mysql_fetch_array($haku)){ echo '<table class="teksti" width="100%" cellspacing="0">'; echo '<tr> <td bgcolor="#464b4e"><font color="white"><b>Keskustelu:</b></font></td></tr></table>'; $aika = date("d.m.Y H:i:s", $rivi['aika']); echo "".$rivi["viesti"]."<br />(<a href=\"alue.php?aiheid=".$rivi['aihe_id']."\">Lue lisää...</a>)"; } mysql_close($y); ?>
Tämän näköisen systeemin sain tehtyä. Koodi näyttää uusimman viestin foorumilla, ja laittaa siihen linkin.
Mutta, tämä ei liity siihen mitä hain. Tuli vaan tehtyä tämä, kun koitin sitä toista... :D
Asian vierestä, mutta sopivasti sivuten:
Kannattaa jo heti suorilta käsin kirjoittaa mieluummin tuon or die:n tilalle
Olioilla/PHP5:
<?php /* * Esimerkeissä $queryError on / voi olla nimensä * mukaisesti tietokannan palauttama virheviesti. * Esim. vaikkapa se funktion mysql_error()- * funktion palauttama arvo. */ if ($result === false) { throw new Exception($queryError); } ?>
Proseduurinen/PHP4 tapa:
<?php if ($result === false) { trigger_error($queryError, E_USER_ERROR); } ?>
Näin koodia ei tarvitse muokata enää sitten erikseen tuotantokäyttöön. Toki tuohon kannattaa jokin poikkeus-/virheenkäsittelijä tehdä (ks. set_exception_handler
/set_error_handler
), jotta käyttäjille saadaan tulostettua jokin selkokielinen virheilmoitus virhetilanteissa. Virheet eivät tulostu suoraan käyttäjille, vaikka poikkeus-/virheenkäsittelijä unohtuisikin (olettaen, että tuotantoserveri on konffittu oikein, eli virheitä ei suoraan puupata sivulle, vaan logiin).
Muistaakseni PHP:n oma manuaali suosittelee poikkeuksien käyttämistä errorien sijaan aina vitosversiosta lähtien.
Voisihan noinkin sen olioilla tehdä, mutta nyt kismittää liikaa tuo pääasia. :/
Sen varmaan saan tehtyä pian, mutta tuo koodi minkä laitoin tuohon. Jos viesti on esimerkiksi yli 250 merkkiä, niin 250 ensimmäistä merkkiä näytetään ja lopun tilalle tulee ... Koitin varcharia, mutta sitä käytetään vaan kirjoittaessa nähtävästi.
Eikös sen saa ihan SUBSTRING(viesti, alku, pituus) funktiolla? Kannattaa lueskella tuota manuaalia, sieltä löytyy aika paljon tietoa. Sivu on tosin englanniksi, mutta se tuskin haittaa?
Teuro kirjoitti:
Eikös sen saa ihan SUBSTRING(viesti, alku, pituus) funktiolla? Kannattaa lueskella tuota manuaalia, sieltä löytyy aika paljon tietoa. Sivu on tosin englanniksi, mutta se tuskin haittaa?
En saanut näin toimimaan.
Mutta, jos laitan näin? SELECT SUBSTRING(viesti, 0, 200);
. Toimisiko? En voi kokeilla, kun en pääse juuri nyt käsiksi serveriin.
SQL:ssä tekstin indeksit alkavat ykkösestä, mutta muuten meni oikein. Tietenkin tarvitset myös taulut ja ehdot kyselyyn.
SELECT viesti_id, SUBSTRING(viesti, 1, 100) AS alku, aihe_id FROM viestit ORDER BY viesti_id DESC LIMIT 1
Metabolix kirjoitti:
SQL:ssä tekstin indeksit alkavat ykkösestä, mutta muuten meni oikein. Tietenkin tarvitset myös taulut ja ehdot kyselyyn.
SELECT viesti_id, SUBSTRING(viesti, 1, 100) AS alku, aihe_id FROM viestit ORDER BY viesti_id DESC LIMIT 1
No joo, tietenkin tarvitsen nuo muut ehdot ja taulut, mutta toi oli suoraan Copy paste tekniikalla otettu manuaalista.
Kiitos sinulle!
Kun noita BBcode -tageja foorumille lisäilin, niin haluaisin laittaa PHP koodille värityksen. Higlight-string
värittää, sen itsekkin tiesin.
Mutta, sitten kun luon kooditagit, niin miten väritän niiden sisällön?
<?php function bbcode_format($var) { $search = array( '/\[b\](.*?)\[\/b\]/is', '/\[i\](.*?)\[\/i\]/is', '/\[u\](.*?)\[\/u\]/is', '/\[url\](.*?)\[\/url\]/is', '/\[url\=(.*?)\](.*?)\[\/url\]/is', '/\[lainaus\](.*?)/is', '/\[lainaus "(.*?)"\](.*?)/is', '/\[\/lainaus\]/is', ); $replace = array( '<strong>$1</strong>', '<em>$1</em>', '<u>$1</u>', '<a href="$1">$1</a>', '<a href="$1">$2</a>', '<i><small>$1 kirjoitti:</small></i><br><div style="border-style:solid;border-width:1px;background:#E4E9FF;margin-left:8px">$2<br></div>', '<i><small><br>$1 kirjoitti:</small></i><br><div style="border-style:solid;border-width:1px;background:#E4E9FF;margin-left:8px">$2', '<br></div>', ); $var = preg_replace ($search, $replace, $var); return $var; } ?>
BBcode -koodi on nyt tälläinen.
Eli, kooditagien sisällä olisi väritys PHP koodille.
Suosittelen käyttämään GeSHi syntaksi värittäjää joka on tarkoitettu PHP:n kanssa käytettäväksi. Näin säästyt
siltä työltä että tarvitset tehdä jokaiselle eri kielelle oman BBcode tagin.
Tumettaja kirjoitti:
Näin säästyt
siltä työltä että tarvitset tehdä jokaiselle eri kielelle oman BBcode tagin.
Se tässä olisi tarkoitus - tehdä itse. Oppii samalla kun tekee, ja kun teen foorumia, niin haluaisin sen olevan kokonaan omaa käsialaa. ;)
Jos kerran haluat itse tehdä, niin koskiko kysymys sitä, että miten HTML:llä vaihdetaan tekstin väriä, vai?
Jos taas haluat tietää miten se "kannattaa" tehdä, niin hae se GeSHi, käy koodi läpi sisäistäen mitä siinä tehdään ja sitten koodaat sen itse.
Jos tekisi näin: Tekee ensin sen laatikon mihin koodi tulee. Sen jälkeen ottaa sen sisällön niistä koodi tageista ($1) ja laittaa sen muuttujaan esimerkiksi $varita, ja sitten echo higlight_string($varita);?
En näe miksei se toimisi, mutta luulin että haluat opetella tekemään sen "itse".
Grez kirjoitti:
En näe miksei se toimisi, mutta luulin että haluat opetella tekemään sen "itse".
Siis, en sitä väritys puolta, mutta en halua suoraan jotain valmis scriptiä.
EDIT: Miten otan muuttujaan sisällön? $varita = $1; tulostaa Parse error: parse error, expecting `T_VARIABLE' or `'$'' in C:\xampplite\htdocs\foorumi\bbcode.php on line, koska tuohan on numero...
MIB kirjoitti:
EDIT: Miten otan muuttujaan sisällön? $varita = $1; tulostaa Parse error: parse error, expecting `T_VARIABLE' or `'$'' in C:\xampplite\htdocs\foorumi\bbcode.php on line, koska tuohan on numero...
<?php $varita = ${1}; ?>
Kaikki säännölliseen lausekkeeseen sopivat merkkijonot saa preg_match_all-funktiolla.
Ei toimi, tulostaa 1. Vaikea juttu :s
Toimiipa hyvinkin jos käytät sitä oikein.
<?php $maara = preg_match_all($pattern, $subject, $matches); print_r($matches); ?>
Tarkoitin, että tuolla trilogin tavalla tulostuu vain 1 oikean sisällön sijaan.
Tuota sinun tapaa, Andu, en tajunnut mitä ajat takaa tuolla. :/
Koitin ottaa $1 muuttujaan ($varitatama = ${1};) ja värittää sen sitten Highlight_stringillä ($varitetty = highlight_string($varitatama);) ja laittaa tämän $varitetty muuttujan oikeaan paikkaan, mutta tulostaa sivun alkuun ensin 2x $1 ja sen jälkeen koodi laatikkoon 1.
Laita koodia näytille, miten olet sitä yrittänyt toteuttaa.
<?php $varita = ${1}; $varitatama = highlight_string("$varita"); function bbcode_format($var) { $search = array( '/\[b\](.*?)\[\/b\]/is', '/\[i\](.*?)\[\/i\]/is', '/\[u\](.*?)\[\/u\]/is', '/\[url\](.*?)\[\/url\]/is', '/\[url\=(.*?)\](.*?)\[\/url\]/is', '/\[lainaus\](.*?)/is', '/\[lainaus "(.*?)"\](.*?)/is', '/\[\/lainaus\]/is', '/\[koodi\](.*?)\[\/koodi\]/is' ); $replace = array( '<strong>$1</strong>', '<em>$1</em>', '<u>$1</u>', '<a href="$1">$1</a>', '<a href="$1">$2</a>', '<i><small>$1 kirjoitti:</small></i><br><div style="border-style:solid;border-width:1px;background:#E4E9FF;margin-left:8px">$2<br></div>', '<i><small><br>$1 kirjoitti:</small></i><br><div style="border-style:solid;border-width:1px;background:#E4E9FF;margin-left:8px">$2', '<br></div>', '<div style="border-style:solid;border-width:1px;background:white">'.$varitatama.'</div>' ); $var = preg_replace ($search, $replace, $var); return $var; } ?>
Ja näin myös
<?php function bbcode_format($var) { $search = array( '/\[b\](.*?)\[\/b\]/is', '/\[i\](.*?)\[\/i\]/is', '/\[u\](.*?)\[\/u\]/is', '/\[url\](.*?)\[\/url\]/is', '/\[url\=(.*?)\](.*?)\[\/url\]/is', '/\[lainaus\](.*?)/is', '/\[lainaus "(.*?)"\](.*?)/is', '/\[\/lainaus\]/is', '/\[koodi\](.*?)\[\/koodi\]/is' ); $replace = array( '<strong>$1</strong>', '<em>$1</em>', '<u>$1</u>', '<a href="$1">$1</a>', '<a href="$1">$2</a>', '<i><small>$1 kirjoitti:</small></i><br><div style="border-style:solid;border-width:1px;background:#E4E9FF;margin-left:8px">$2<br></div>', '<i><small><br>$1 kirjoitti:</small></i><br><div style="border-style:solid;border-width:1px;background:#E4E9FF;margin-left:8px">$2', '<br></div>', '<div style="border-style:solid;border-width:1px;background:white">'.highlight_string(${1}).'</div>' ); $var = preg_replace ($search, $replace, $var); return $var; } ?>
Jälkimmäinen on lähempänä oikeaa, oli kyllä kieltämättä aika kinkkinen juttu, mutta sain onnistumaan. Löysin putkan oppaasta, että PHP:n preg_replaceen
voi antaa funktioita, jonka läpi korvattava teksti ajetaan. Antaa koodin puhua puolestaan:
<?php function varitaPHP($s) { return '<div style="border-style:solid;border-width:1px;background:white">'. highlight_string($s, True). '</div>'; } function bbcode_format($var) { $search = array( '/\[phpp\](.*?)\[\/phpp\]/ise', ); $replace = array( "varitaPHP('\\1')", ); $var = preg_replace($search, $replace, $var); return $var; } ?>
Näin se toimii sitten tekstissä:
Väritetty PHP-koodi: [phpp]<?php echo 'foo'; ?>[/phpp]
Eli tässä lisättiin tuonne $search
-taulukon koodinkorvaajan perään 'e' -lippu, joka ajaa korvattavan tekstin funktion läpi. Lisäksi tehtiin erillinen funktio, joka kutsuu PHP-koodin värittäjää.
Edit. Jep, oli vähän ongelmia Putkan koodinväritystagien kanssa... Täällä on niin paljon aliaksia. :)
Anna style-määritteen sijaan class ja määrittele ulkoinen css-tiedosto. Nimeäkantamattomat lainaustagisi ovat rikki.
Eipä toimi, trilog. Ajattelin tämän olevan vähän helpompi juttu, mutta metsään meni. :/
MIB kirjoitti:
Eipä toimi, trilog. Ajattelin tämän olevan vähän helpompi juttu, mutta metsään meni. :/
Kyllä itselläni väritteli hyvin kun testailin...?
Miten kirjoitit tuon [phpp]...[/phpp]:n? Tai, oikeastaan mihin laitoit sen? Näytätkö kokonaan koodisi miten sait? :/ Minulla ei nyt tunnu sujuvan tämä..
MIB kirjoitti:
Miten kirjoitit tuon [phpp]...[/phpp]:n? Tai, oikeastaan mihin laitoit sen? Näytätkö kokonaan koodisi miten sait? :/ Minulla ei nyt tunnu sujuvan tämä..
Samalla tavallahan tuo menee kuin muidenkin tagien kanssa. Tuo minun on pelkistetty versio; lisäilet vain nuo parit rivit omaan koodiisi ja tuon varitaPHP
-funktion.
Nyt täytyy kysyä, että miten tuo 'e' lippu määrittää sen ajettavan funktion? Jos samassa tiedostossa on vaikka 50 funktiota, mistä se tietää mikä on oikea jos ei sitä mitenkään osoiteta sille? Eikä sitä funktiota tuossa mitenkään selvästi kutsutakkaan mun mielestä.
TeNDoLLA kirjoitti:
Nyt täytyy kysyä, että miten tuo 'e' lippu määrittää sen ajettavan funktion? Jos samassa tiedostossa on vaikka 50 funktiota, mistä se tietää mikä on oikea jos ei sitä mitenkään osoiteta sille? Eikä sitä funktiota tuossa mitenkään selvästi kutsutakkaan mun mielestä.
Vähän epäselvästi tosiaan kirjoitin tuon (itse asiassa sehän ajaa sen PHP-tulkin läpi), ks. https://www.ohjelmointiputka.net/oppaat/opas.
Kiitos selvennyksestä. En muuten äsken huomannutkaan, mutta kyllähän siellä tosiaan kutsutaankin tuota funktiota. Ei sattunut silmään kun se oli tuolla stringin "seassa".
Edit: Tuo e-lippu on ilmeisesti sama kuin eval()? Eli onko tuossa mahdollista, että kaikki mitä käyttäjä kirjoittaa ajetaan php tulkin läpi?
<?php echo \"Hello World!\"; ?>
Tämäkö on tarkoitus tulla koodista? :/ Ei nyt kyllä ihan toimi.
MIB kirjoitti:
<?php echo \"Hello World!\"; ?>Tämäkö on tarkoitus tulla koodista? :/ Ei nyt kyllä ihan toimi.
stripslashes
ja html_entity_decode
sitten tuonne funktioon (varitaPHP) jos tuollaisia tulee. Tarkoitus ja tulostus selviää em. codepad-pastesta.
Mihin kohtaan? :/
MIB kirjoitti:
Mihin kohtaan? :/
<?php function varitaPHP($s) { return '<div style="border-style:solid;border-width:1px;background:white">'. highlight_string(html_entity_decode(stripslashes($s)), True). '</div>'; } ?>
Jaa, tuonne :D Kiitos.
Jostain syystä se tekee alkuun ja loppuun tyhjät rivit... Miten nämä saisi pois? <nobr> -tageja koitin jo...
SELECT a.id, a.otsikko, v.lahettaja_id, v.aika, v.viesti FROM AiheetViimeisinViesti a LEFT JOIN viestit v ON a.viesti_id=v.viesti_id ORDER BY a.id
Miten saan lisättyä tähän aliaksen ai? Koitin laittaa tuonne FROM kohdan viestit v ON a.viesti_id=v.viesti_id:n perään aiheet ai, mutta ei toiminut. Miten kuuluisi laittaa?
Haluaisin sen siis, että ai aliaksella olevat tiedot haetaan aiheet taulusta.
tsuriga kirjoitti:
Tuolla ei kerrota, miten tehdään jos on enemmän noita aliaksia. Koitin tehdä esimerkkien mukaan, mutta tekee errorin.
Olet jäsentänyt lauseesi väärin. Et ilmeisesti ymmärrä kunnolla JOIN-lauseen syntaksia.
SELECT * FROM taulu AS alias LEFT JOIN taulu2 AS alias2 ON ehto2 LEFT JOIN taulu3 AS alias3 ON ehto3 WHERE ehto
Vaikka tuo AS taikasana onkin myslissä vapaaehtoinen niin sen käyttö on suositeltavaa selkeyden (ja portattavuuden?) kannalta. Useamman aliaksen käyttö ei eroa yhden käytöstä lainkaan, kuten yllä on esitetty.
Kun en kyselyillä saanut toimiin, niin tein FOR -silmukalla
for ($i = 0; $i < mysql_num_rows($haku); $i++) { $lahettaja = mysql_result($haku, $i, "lahettaja_id"); $otsikko = mysql_result($haku, $i, "otsikko"); $aika = mysql_result($haku, $i, "aika"); $aika2 = date("d.m.Y H:i:s", $aika); for ($i = 0; $i < mysql_num_rows($haku1); $i++) { $aloittaja = mysql_result($haku1, $i, "lahettaja"); $aikaa = mysql_result($haku1, $i, "aika"); $aloitettu = date("d.m.Y H:i:s", $aikaa); echo "<tr><td>$aloittaja</td><td>$otsikko</td><td>$aloitettu</td><td>$lahettaja</td><td>$aika2</td></tr>"; } }
Mitkä noi $haku ja $haku1 -kyselyt tuossa on?
Mielestäni aika erikoisesti toteutettu ja tuohan jää ikuiseen looppiin jos $haku1 palauttaa 2 - n riviä vähemmän kuin $haku.
$haku ja $haku1 ovat kyselyt, joilla haen tietoa eri tauluista. Sitä pitää vähän vielä parannella, koska se ei saa oikeaa aikaa viimeisimpään viestiin.
No sen nyt tajusinkin. Tarkoitin lähinnä: Mitkä ne kyselyt on? Ihan SQL-koodina.
Nykyisellään on vaikeaa kertoa miten tuon voisi tehdä kunnolla, kun ei voi tietää mitä se tekee.
...lisäksi vastausintoa lisäisi kummasti jos koodi olisi vielä koodiväritetty (php-koodi alkaa <?php ja loppuu ?>) ja sisennykset olisivat kunnossa... Ihan näin vinkkinä vain :)
No joo, Grez: Mulla tuli pieni virhe tossa ajatellessani tota..
JTS: Sisennykset oli kunnossa omassa lähdekoodissani, mutta lysähti tohon. Oisinhan mä tietenkin <?php ?> tagit voinut laittaa...
<?php require_once("settings.php"); $y = mysql_connect("$dbserver", "$dbuser", "$dbpw"); mysql_select_db("$db"); $kysely1 = "SELECT a.id, a.otsikko, a.lahettaja, v.aika, Max(v.aika) ViimeisinViesti FROM Aiheet a JOIN viestit v ON (v.aihe_id=a.id) GROUP BY a.id, a.otsikko ORDER BY Max(v.aika) DESC"; $haku1 = mysql_query($kysely1) or die(mysql_error()); $kysely = " SELECT a.id, a.otsikko, v.lahettaja_id, v.aika, v.viesti FROM AiheetViimeisinViesti a LEFT JOIN viestit v ON a.viesti_id=v.viesti_id ORDER BY a.id "; $haku = mysql_query($kysely) or die(mysql_error()); echo '<table class="teksti" width="95%" cellspacing="0">'; echo '<tr class="taulukkoyla"> <td width="40%"><b>Aiheen otsikko</b></td> <td><b>Aloittaja</b></td> <td><b>Viimeisin</b></td></tr>'; for ($i = 0; $i < mysql_num_rows($haku); $i++) { for ($i = 0; $i < mysql_num_rows($haku1); $i++) { $aloittaja = mysql_result($haku1, $i, "lahettaja"); $aikaa = mysql_result($haku1, $i, "aika"); $aloitettu = date("d.m.Y H:i:s", $aikaa); $aika = mysql_result($haku, $i, "aika"); $aika2 = date("d.m.Y H:i:s", $aika); $lahettaja = mysql_result($haku, $i, "lahettaja_id"); $otsikko = mysql_result($haku, $i, "otsikko"); $id = mysql_result($haku, $i, "id"); echo "<tr><td width='35%'><a href=\"index.php?sivu=alue&aiheid=$id\">$otsikko</a></td><td> <a href=\"index.php?sivu=profiili&tunnus=$aloittaja\">$aloittaja</a></td> <td><a href=\"index.php?sivu=profiili&tunnus=$lahettaja\">$lahettaja</a> / $aika2</td></tr>"; } } echo "</table>"; mysql_close($y); ?>
Tämmöinen, ei toimi tuo $aika2. Muut toimivat, vaikka aika hirveän näköinen sotku tuo onkin. En vaan keksi miten voisin tehdä samaan kyselyyn nuo...
Ongelma haun kanssa:
Tein tälläisen haun, mikä hakee viesteistä aikajärjestyksessä ne, joissa esiintyy kyseinen hakusana. Ongelmana on se, että jos samasta aiheesta löytyy useampi viesti, joissa on tämä hakusana, vain aloitusviestissä näkyy otsikko (siis, jos hakusana löytyy aloitusviestistä).
<?php require_once("ylaosa.php"); $hakusana = $_GET["hae"]; $hakukysely = " SELECT * FROM viestit WHERE viesti LIKE '%$hakusana%' ORDER BY aika DESC LIMIT 100"; $haku = mysql_query($hakukysely) or die(mysql_error()); $alue = "Yleinen keskustelu"; echo "<table>"; for ($i = 0; $i < mysql_num_rows($haku); $i++) { $otsikko = mysql_result($haku, $i, "otsikko"); $lahettaja = mysql_result($haku, $i, "lahettaja_id"); echo "<tr><td>$alue:</td><td>$otsikko</td></tr>"; } echo "</table>"; require_once("alaosa.php"); ?>
Tiedän ettette pidä siitä, että lähetän niin paljon kysymyksiä, joita pidätte päivänselvänä asiana (Olettehan te ohjelmoinneet kauemmin kuin minä. Ei minun ikääni millään mahdu niin paljon taitoa), mutta en ole saanut millään toimimaan.
Siispä, kysyn tuota ylläolevaa uusiksi.
Haluan tarkentaa kysymystä, joten miten tuon sinusta tulisi toimia? Oletamme, että kannassa on samassa langassa kaksi viestiä, joissa on sanana vaikkapa 'moikka'. Nyt jos teemme haun sanalle 'moikka', niin mitä tuon tulee tulostaa?
Lähettäjä1: aihe1 Lähettähä2: aihe1 Lähettäjä1: aihe5
Jokaisessa pitäisi lukea aiheen otsikko, vaikka ne samaan kuuluisivat. Tuo äskeinen tulostuu omalla skriptillä näin.
Lähettäjä1: aihe1 Lähettäjä2: Lähettäjä1: aihe5
<?php echo "<tr><td>$alue:</td><td>$otsikko</td></tr>"; ?>
Eihän tuolla koodilla ole mitenkään mahdollista saada pyydettyä tulostetta?
<?php require_once("ylaosa.php"); $hakusana = $_GET["hae"]; $hakukysely = " SELECT * FROM viestit WHERE viesti LIKE '%$hakusana%' ORDER BY aika DESC LIMIT 100"; $haku = mysql_query($hakukysely) or die(mysql_error()); echo "<div style=\"padding-left: 10px\">"; if(!empty($hakusana)) { echo "<table><tr><td><b>Keskusteluista löytyi:</b></td></tr><tr></tr><tr></tr>"; for ($i = 0; $i < mysql_num_rows($haku); $i++) { $otsikko = mysql_result($haku, $i, "otsikko"); $lahettaja = mysql_result($haku, $i, "lahettaja_id"); $aiheid = mysql_result($haku, $i, "aihe_id"); echo "<tr><td>$lahettaja kirjoitti viestin aiheeseen:</td><td><a href=\"alue.php?aiheid=$aiheid\">$otsikko</a></td></tr>"; } echo "</table>"; } else echo '<br><b>Et täyttänyt hakusanaa!</b> Sinun pitää täyttää se hakeaksesi tietoa.<br><br><form action="haku.php" method="GET"> <input type="name" name="hae"> <input type="submit" value="Hae"></form>'; echo "</div>"; require_once("alaosa.php"); ?>
Näinhän se on tehty: ei toimi. En ole varma, mutta taidan tietää mistä ongelmani johtuu. Katson tuolla PhpMyAdminilla mitä tietokannoissa lukee.. Luulen että olen vaivannut turhaan. Uskoisin, että vain aloitusviestissä lukee otsikko, ja muut ovat NULL arvolla.
Mun moka oli, en muistanut muuttaneeni vastauskoodia noin paljon, että ei kirjoita aiheen otsikkoa.
No, nyt se siis toimii, paitsi yhtä juttua lukuunottamatta:
Jos hakutuloksia ei löytynyt, se ei palauta mitään muuta kuin "Keskustelusta löytyi:" -tekstin. Muistaakseni mysql_num_rows:lla voi tarkistaa, mutta en muista miten se oli ja missä törmäsin siihen. Muuten, jos hakutuloksia ei löytynyt (mysql_num_rows), niin minkä arvon se palauttaa kyselystä?
Edit: Keksimpä jo miten teen sen.
Ja vielä kolmas viesti peräkkäin... (:s)
Nyt tarvitsisin sellaisen systeemin, että kun yhdelle sivulle otetaan vaan 15 uusinta aihetta, niin jos on yli, niin tulisi seuraava sivu jossa olisi seuraavat 15. Niinkuin Putkassa. Nyt ei ole yhtään hajua, miten tämä tehdään.
Osaisin varmaan tehdä loput, mutta sitä en, kun tulostus katkaistaan 15 jälkeen, niin seuraavalla sivulla jatkuisi 16 eteenpäin...
Oletko jo lukenut putkassa olevan koodivinkin tuollaisen systeemin toteutuksesta?
Hee, en olekkaan huomannut tuota. Kiitos vinkistä!
Miten saisin katkaistua yli 10 merkkiä pitkät merkinnät? Menee vähän huonosti tuo ulkoasu niin pitkillä sanoilla....
<?php $str = substr($str, 0, 10); ?>
Taikasana substr.
Ongelmana tuossa on, kun otan ensin uusimmasta viestistä 200 ensimmäistä merkkiä ja $str olisi ne 200 merkkiä, niin tuo katkaisisi sen 10 merkin pituiseksi. Siis, jos on vaikka teksti "Minä olen Pekka ja aaaaaaaaaasun maatilalla eläimieni kanssa.", niin tuo tummennettu sana katkaistaisiin, ja laitettaisiin <br> siihen 10:n merkin jälkeen, jolloin olisi
aaaaaaaaaa sun
Tajusittekos?
Oletko nyt ajatellut asian loppuun asti?
Minä olen Pekka ja aaaaaaaaaa sun maatilalla eläimieni kanssa.
Paremmin tarkoitukseen sopisi oikein sijoiteltu ­ eli tavuviiva, jonka kohdalta selain voi tarvittaessa tavuttaa sanan automaattisesti. Tämän tuki alkaa kai nyt olla jo käytettävällä tasolla, aiemmin monet selaimet eivät ymmärtäneet merkintää. Laatikkoa varten tyydyttävästi toimivan suomen tavutuksen saa aikaan säännöllisillä lausekkeilla muutamalla koodirivillä, kun hieman pohtii tavutussääntöjä.
Samaisilla lausekkeilla onnistuu myös haluamasi 10 merkin katkaisu. Tässä laitan siihen tavuviivan.
<?php $t = preg_replace('/\\w{10}(?=\\w)/', '\\0-', $t);
Edit. Kohtalaiseen tavutukseen riittää jopa tällainen:
<?php $vok = "aeiouyåäöAEIOUYÅÄÖ"; $kon = "bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ"; // Tavutetaan ennen konsonanttia, jos sen jälkeen tulee vokaali. // Suurin osa tavurajoista on näitä, mutta tiettyjen vokaaliparien väliin // pitäisi myös laittaa viiva, ja esim. maanalainen tavuttuu väärin. $t = preg_replace("/([$kon$vok])(?=[$kon][$vok])/", '\\0­', $t); // Katkotaan vielä varmuuden vuoksi liian pitkät kirjainjonot, // jotka eivät edellisellä katkenneet. $t = preg_replace('/\\w{10}(?=\\w)/', '\\0­', $t);
Kiitos, nyt on todella ärsyttävä ongelma.
Kun aiheita tulee foorumeille yleensä niin paljon, että niitä ei jaksa alkaa selata yhdellä sivulla, niin tuota Antin sivutus koodivinkkiä käytin.
Nyt pitäisi luoda toinen alue. Aiheissa on alue_id sarake, jolla viestit kuuluisi ohjata oikeaan paikkaan. Kysely, jossa ei ole sivutusta, toimii:
<?php require_once("yla.php"); require_once("ylaosa.php"); $ky = "SELECT * FROM aiheet WHERE alue_id = '2'"; $ha = mysql_query($ky); echo '<table class="teksti" width="95%" cellspacing="0">'; echo '<tr class="taulukkoyla"> <td width="50%"><b>Aiheen otsikko</b></td> <td width="20%"><b>Aloittaja</b></td> <td><b>Aloitusaika</b></td></tr>'; for ($i = 0; $i < mysql_num_rows($ha); $i++) { $otsikko = mysql_result($ha, $i, "otsikko"); $lahettaja = mysql_result($ha, $i, "lahettaja"); $aika = mysql_result($ha, $i, "aika"); $aikaa = date("d.m.Y H:i:s", $aika); $id = mysql_result($ha, $i, "id"); echo "<tr><td><a href=\"alue.php?aiheid=$id\">$otsikko</a></td><td>$lahettaja</td><td>$aikaa</td></tr>"; } echo "</table>"; ?> <div style="padding-left: 10px"> </div> <?php require_once("alaosa.php"); ?>
Mutta, tämä ei toimikkaan, mikä pitäisi saada kuntoon:
<?php require_once("yla.php"); require_once("ylaosa.php"); $vps = 15; // luetaan osoitteen mukana tullut sivunumero if (isset($_GET['sivu'])) { $sivu = $_GET['sivu']; } $sivu = intval($sivu); // haetaan näytettävät viestit tietokannasta $viestit = mysql_query("SELECT a.id, a.otsikko, a.lahettaja, a.alue_id, v.aika, Max(v.aika) ViimeisinViesti FROM Aiheet a JOIN viestit v ON (v.aihe_id=a.id) WHERE a.alue_id = '2' GROUP BY a.id, a.otsikko ORDER BY Max(v.aika) DESC LIMIT ".($sivu * $vps).", {$vps}"); // selvitetään viestien määrä $maara = mysql_result(mysql_query("SELECT COUNT(*) FROM aiheet"), 0); if ($maara > $vps) { echo '<p class="teksti" align="right">Sivut: '; for ($i = 0; $i < $maara / $vps; $i++) { if ($i <> 0) { echo " "; } // jos tämä sivu näytetään, tulostetaan sivun numero lihavoituna if ($sivu == $i) { echo "<b>".($i + 1)."</b>"; // muussa tapauksessa luodaan linkki toiselle sivulle } else { echo "<a href=\"{$_SERVER['PHP_SELF']}?sivu={$i}\">".($i + 1)."</a>"; } } } echo "</p>"; echo '<table class="teksti" width="95%" cellspacing="0">'; echo '<tr class="taulukkoyla"> <td width="50%"><b>Aiheen otsikko</b></td> <td width="20%"><b>Aloittaja</b></td> <td><b>Aloitusaika</b></td></tr>'; // tulostetaan tietokannasta luetut viestit for ($i = 0; $i < $vps; $i++) { // varmistetaan, että viimeisellä sivulle ei tule ylimääräistä if ($i + $sivu * $vps < $maara) { // tulostetaan viestin tiedot yksinkertaisesti muotoiltuna $aihe_id = mysql_result($viestit, $i, "id"); $aika = mysql_result($viestit, $i, "aika"); $aika2 = date("d.m.Y H:i:s", $aika); $nimi = mysql_result($viestit, $i, "lahettaja"); $otsikko = mysql_result($viestit, $i, "otsikko"); echo "<tr> <td><a href=\"alue.php?aiheid=$aihe_id\">$otsikko</a></td> <td><a href=\"ohjaus.php?tunnus=$nimi\">$nimi</a></td> <td>$aika2</td></tr>"; } } echo "</table>"; ?> <div style="padding-left: 10px"> </div> <?php require_once("alaosa.php"); ?>
Anteeksi jos vastaan hieman kuuseen, mutta kun haet aiheiden määrän, niin onkohan sittenkään tarkoituksesi hakea kaikki aiheet taulun aiheet, vai pelkästeen kyseisen foorumin. Eli jos olen oikeassa, niin pitäisi muuttaa $maara-kysely tälläiseksi:
select count(*) from aiheet where alue_id="haluamasi id"
Se auttoi kovasti :) Kiitos sinulle, nyt toimii kunnolla. Heh
Vielä yksi juttu, sitten on minun mielestä tämä foorumini valmis:
Tarvitsisi saada näkyviin viestien määrä eri alueilla (Niinkuin Putkassa), ja viimeisimmän viestin lähettäjä & aika per alue.
Näin saan tulostettua alueet ja aiheiden määrän per alue, mutta en noita muita, koska ne eivät ole samassa taulussa.
<?php require_once("yla.php"); require_once("ylaosa.php"); mysql_query("CREATE TABLE alueet( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, alue TEXT, tiedosto TEXT)"); $ky = "SELECT * FROM alueet"; $ha = mysql_query($ky) or die(mysql_error()); //Luodaksesi uuden aiheen, mene luoalue.php tiedostoon echo '<table class="teksti" width="95%" cellspacing="0"> <tr class="taulu"> <td><b>Alue</b></td><td><b>Aiheita / Viestejä</b></td><td><b>Uusin viesti</b></td> </tr>'; for ($i = 0; $i < mysql_num_rows($ha); $i++) { $alue = mysql_result($ha, $i, "alue"); $id = mysql_result($ha, $i, "id"); $ky2 = "SELECT * FROM aiheet WHERE alue_id = '$id'"; $ha2 = mysql_query($ky2) or die(mysql_error()); $a = mysql_num_rows($ha2); echo "<tr><td><a href=\"alueet.php?alue=$id\">$alue</a></td> <td>$a / Viestejä</td><td><br>Viimeisin viesti<br><br></td></tr>"; } echo "</table>"; require_once("alaosa.php"); ?>
Koska viestit yhdistetään aiheisiin aihe_id:n perusteella, ja aiheet alueisiin alue_id:n perusteella, niin en tiedä miten 'yhdistäisin' eri tauluista tietoa.
Ps. Noissa includetuissa sivuissa ei ole kuin ulkoasu & mysql_connect hömpät.
Tohon vielä lisään helpottamaan taulujen rakenteet:
alueet id (Alueen numero, 1, 2, 3 jne...) alue (Alueen nimi.) viestit viesti_id (Monesko viesti) aihe_id (Aiheen id, mihin on lähetetty) id (Lähettäjän id numero) lahettaja_id (Lähettäjän tunnus) aika (Milloin lähetetty) otsikko (Aiheen otsikko mihin lähetetty) viesti (Viesti) aiheet alue_id (Mihin alueeseen on, viitataan aluuet taulun id:seen) id (Monesko, 1, 2, 3... jne) otsikko (Aiheen otsikko) aika (Milloin aloitettu) lahettaja (Lähettäjän nimi) lahettaja_id (Lähettäjän id numero)
Osaisiko joku nyt auttaa? =)
Avainsana on sql:än join-kyselyt. Ideana on siis että yhdistetään monesta taulusta tietoa yhteen uuteen väliaikaiseen(temp) tauluun. Kun siis haluat hakea lahettaja_id:n ja aika kentän viestit taulusta aiheet-taulun alue_id:n avulla (tai jotain sinne päin XD). Oli mikä oli kyselysi pitää kuitenkin olla tälläinen:
select lahettaja_id,aika from viestit join aiheet on viestit.aihe_id=aiheet.id and aiheet.alue_id="haluamasi alue_id"
Sitten tosta vaan mysql_num_rows:lla viestien määrä.
Empä näin saanut toimimaan.
Tiedän miten saan kaikista alueista yhteismäärän, mutta ei auta tässä.
Koitin vääntää tuon sinun vinkin pohjalta, mutta ei onnistunut.
Nyt näyttää tältä:
<?php include("ylaosa.php"); $k = "SELECT COUNT(*) FROM viestit GROUP BY aihe_id"; $h = mysql_query($k) or die(mysql_error()); echo "".mysql_num_rows($h)."<br>"; include("alaosa.php"); ?>
(Tämän on tarkoitus vain hakea se viestien määrä aluksi, sillä hoksasin juuri, miten haen viimeisimmän viestin lähettäjän ja aiheen otsikon per alue.)
Edit: Heh, sain valmiiksi lisäämällä GROUP BY aihe_id:n kyselyn loppuun.
SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='1' GROUP BY aihe_id
Edit: Ja vähän vielä muuttamalla (oikeastaan palautin tuon jo123:n kyselyn), sain toimimaan niinkuin halusin.
<?php require_once("yla.php"); require_once("ylaosa.php"); mysql_query("CREATE TABLE alueet( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, alue TEXT, tiedosto TEXT)"); $ky = "SELECT * FROM alueet"; $ha = mysql_query($ky) or die(mysql_error()); //Luodaksesi uuden aiheen, mene luoalue.php tiedostoon echo '<table class="teksti" width="95%" cellspacing="0"> <tr class="taulukkoyla"> <td><b>Alue</b></td><td><b>Aiheita / Viestejä</b></td><td><b>Uusin viesti</b></td> </tr>'; for ($i = 0; $i < mysql_num_rows($ha); $i++) { $alue = mysql_result($ha, $i, "alue"); $id = mysql_result($ha, $i, "id"); $ky2 = "SELECT * FROM aiheet WHERE alue_id = '$id'"; $ha2 = mysql_query($ky2) or die(mysql_error()); $k = "SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$id'"; $h = mysql_query($k) or die(mysql_error()); $a = mysql_num_rows($ha2); $v = mysql_num_rows($h); echo "<tr><td><a href=\"alueet.php?alue=$id\">$alue</a></td> <td>$a / $v</td><td><br>Viimeisin viesti<br><br></td></tr>"; } echo "</table>"; require_once("alaosa.php"); ?>
No hyvä. Oikeastaan tuo kyselyni haki tietyn alueen kaikki viestit, joten se ei oikeastaan ollut aivan tarkasti se mitä halusit. Sillä sai kuitenkin haettua alueen viestien määrän, niin kuin itsekin jo huomasit. Kyselyä säätämällä saa sitten vielä haettua uusimman viestin ajan ja lähettäjän. ;)
Tuo toimii nyt noin, mutta tulikin mietittyä uudelleen sitä viimeisimmän viestin lähettäjää, aikaa ja otsikkoa. Se ei mennytkään ihan niin helposti kuin ajattelin.
Koitin laittaa näin:
SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$alue_id' GROUP BY aihe_id ORDER BY viestit.aika DESC LIMIT 1
Tämä vain sattuu näyttämään lähettäjän tiedot joka on aloittanut aiheen. Kylläkin näyttää silti siitä aiheesta mihin on vastattu viimeiseksi.
Osaisiko joku vielä auttaa? :D
Edit: Taas tuli kysyttyä, ennen kuin ajateltua. Otimpa vain tuon GROUP BY -jutun pois, niin se oli siinä.
Silti en saa niin, että näkyis jokaisessa alueessa uusin viesti. Hetki menee vielä varmaan vääntää.
Tuli tässä taas pieni ongelma, kun haku systeemissäni voi hakea joko erikseen jäsenistä tai keskusteluista tms. tai sitten kaikista. Ongelma on siinä, että miten haen kaikista? Koska, jäsenet ja keskustelut ovat eri tauluissa, niin siinä on se ongelma. SELECT * FROM voiko,taulut,erottaa,näin ORDER BY aika DESC?
Ei kuulu tehdä noin, et saa lainkaan järkeviä tuloksia. (Lue jostakin, kuinka monen taulun kyselyt toimivat.) Järkevintä on tehdä kaikki haut erikseen ja tulosta tulokset erikseen, koska eihän noissa tauluissa ole riittävästi yhteistä, jotta niistä voisi järkevästi tehdä saman haun.
Nojoo, tehdään sitten niin.
Nyt tuli toisenlainen "ongelma". Minun pitäisi lisätä noin 600 riviä tietoa tietokantaan. Jokainen rivi on erillainen, ja taulussa on kolme kohtaa.
Miten saisin tehtyä sellaise ns. listan joka sitten kirjoitetaan?
Voisiko tehdä niin, että kirjoitan tekstitiedostoon ensin (taino, ne on jo kirjoitettu) tiedot, sitten explodella erottelen, ja kirjoitan ne?
Voit toki tehdä noin, mutta kannatta olla sitten ihan varma mitä olet tekemässä, koska tuon kyselyryppään pitää onnistua oikein. Melkein suosittelen ensin preparoimaan koko roskan sopivaan muotoon vaikkapa valmiiksi kyselyiksi ja tulostamaan ne näytille.
Missä muodossa tallennettavat tiedot ovat?
Teuro kirjoitti:
Missä muodossa tallennettavat tiedot ovat?
Siis, ihan tekstinä on.
Sanoinkin väärin, pitäisi täyttää numero ja nimi tauluun..
Elikä tyyliin:
15|Juha 20|Pete . . .
Jos näin, niin tuosta pitäisi sitten muodostaa n kyselyä, jotka ajetaan luupissa kantaan. 300 riviä taitaa olla niin pieni määrä, että normaali file(string) + explode(erotin, rivi) voisi olla sopiva parivaljakko, jolla tehtävän saisi suoritettua. Mahdollisesti data kannattaa siivota mysql_real_escape_string(string) funktiolla turvallisemmaksi?
Tämä nyt ei ole se koodi, mutta tähän tyyliin?
<?php $akuankat = file("akuankat.txt"); for ($i = 0; $i < $viestimaara; $i++) { $tiedot = explode("|", $akuankat[$i], 2); //erotellaan tiedot omiin muuttujiinsa $numero = $tiedot[0]; $nimi = $tiedot[1]; mysql_query("INSERT INTO taskukirjat(numero, nimi) VALUES('$numero', '$nimi')") or die(mysql_error()); } ?>
Tein tollaisen kerran...
Viestimäärä on tuntematon muuttuja. Tuossahan ajat sitten koko roskan laakista kantaan sen kummemmin tutustumatta sisältöön etukäteen, joka voisi olla ihan järkevää. Lisäki numerokenttä lienee (INT) tyyppinen, jolloin hipsuja ei ole tarkoitus käyttää.
Jäi mun copy pastesta se viestimaara pois...
Joo, numero on INT tyyppinen. Miten se kuuluisi sitten tehdä?
<?php $akuankat = file("akuankat.txt"); $viestimaara = count($akuankat); for ($i = 0; $i < $viestimaara; $i++) { $tiedot = explode("|", $akuankat[$i]); //erotellaan tiedot omiin muuttujiinsa $numero = $tiedot[0]; $nimi = $tiedot[1]; $kysely[] = "INSERT INTO taskukirjat(numero, nimi) VALUES($numero, '$nimi')"; } for($a = 0; $a < count($kysely); $a++){ echo $kysely[$a] . "<br />"; } ?>
Kiitos :)
Nyt kun tuon sain tehtyä (muutettua Teuron esimerkistä), niin tuli toinen juttu:
Kun minulla on monta aluetta foorumilla, niin selkeyttäisi lukemista, kun olisi niillä <tr> tageilla taustaväri. Niinkuin täälläkin, joka toinen on värillisellä pohjalla.
Joskus onnistuin säätämään jotain niin, että tulisi, mutta se oli niin pahaa siansaksaa, että huhhuh.
<?php $a = 0; while($rivi = mysql_fetch_array($tulos)){ echo"<tr>"; $vari = ($a % 2 == 0) ? 'punainen' : 'vihrea'; echo"<td class=\"$vari\">".$rivi['otsikko']."</td>"; $a++; echo"</tr>"; }
Ei niin kamalan hankalaa eihän?
Kiitos sulle taas. Pitänee varmaan tutustua paremmin WHILE ja FOR silmukoihin.
Mullapa onkin tänään paljon kysymyksiä mielessä.
Kun tuossa ajv:n koodivinkissä käytetään sessioneja, niin minun pitäisi saada muutettua ne kekseiksi.
Koitin näin. Se näyttäisi kirjaavan tuon id:n ylös, mutta se ei päästä sisään.
Keksiin siis menee se id, mutta ei kirjaudu sisään.
<?php include("config.php"); //muuta config.php:n polku oikeaksi //avataan yhteys tietokantaan $lnk = mysql_connect($db_server,$db_user,$db_passwd) or die ("Yhteys tietokantaan epäonnistui"); mysql_select_db($db_db,$lnk) or die ("Tietokannan valitseminen epäonnistui"); //käyttäjä on oletuksena false. Älä varsinkaan poista, ellet tiedä mitä teet :) $user = false; /* SISÄÄNKIRJAUTUMINEN */ if(isset($_POST['tunnus']) && isset($_POST['salasana'])){ //muuttujat turvallisesti talteen $tunnus = get_magic_quotes_gpc() ? $_POST['tunnus'] : mysql_real_escape_string($_POST['tunnus']); $salasana = get_magic_quotes_gpc() ? $_POST['salasana'] : mysql_real_escape_string($_POST['salasana']); $salasana = md5($salasana); //luodaan käyttäjäkohtainen uniikki id $istuntotunnus = md5(uniqid("")); //lisätään istunto tietokantaan käyttäjän tietoihin mysql_query("UPDATE {$tbl_users} SET istunto = '{$istuntotunnus}' WHERE tunnus = '{$tunnus}' AND salasana = '{$salasana}'",$lnk) or die (mysql_error()); if(mysql_affected_rows($lnk) == 1){ setcookie("log_key", "$istuntotunnus"); echo "Katsotaan onko kirjauduttu (Päivitä, näkyykö cryptattu id?): " . $_COOKIE["log_key"] . ""; } } /* ULOSKIRJAUTUMINEN */ if(isset($_REQUEST['logout'])){ setcookie("log_key", ""); setcookie("log_key", "", time() - 60 * 10); echo "Logget out"; } /* KÄYTTÄJÄN TUNNISTUS */ if(isset($_COOKIE['log_key'])){ //HAETAAN KÄYTTÄJÄN TIEDOT $sql = "SELECT id, tunnus, DATE_FORMAT(last_load,'%d.%m.%y %h:%i:%s') AS last_load FROM {$tbl_users} WHERE istunto = '".mysql_real_escape_string($_COOKIE['log_key'])."'"; $sql = mysql_query($sql,$lnk); if($sql && mysql_num_rows($sql) == 1){ $user = mysql_fetch_assoc($sql); mysql_query("UPDATE {$tbl_users} SET last_load = NOW() WHERE id = ".$user['id'], $lnk); } } mysql_query("CREATE TABLE IF NOT EXISTS `{$tbl_users}` ( id int(11) NOT NULL auto_increment, tunnus varchar(50) default NULL, salasana varchar(32) default NULL, oikeanimi TEXT, email varchar(60) default NULL, ika INT, kotisivu TEXT, kuvaus TEXT, last_load timestamp(14) NOT NULL, istunto varchar(32) default NULL, PRIMARY KEY (id), UNIQUE KEY istunto (istunto) )",$lnk);
Ongelma taitanee johtua tuosta käyttäjän tunnistuksesta.
Katsopa mitä noihin erilaisiin muuttujiin on tallentunut, sen jälkeen askel kerrallaan katsomaan missä kohdin menee metsään. Taulun rakenne lienee oikein, jos olet ajanut tuon ajv:n scriptin läpi virheittä.
Sisään kirjautuessa teet taas kerran suoraan kantaan ajamisen SQL-lauseella, jonka sisällöstä ei ole tietoa. Tulosta se ja katso onko sisältö oikein. Samalla tyylillä kaikki muutkin muuttujat läpi. Jokaisen mysql_query(string) funktion jälkeen olisi hyvä olla echo mysql_error(), joka kertoo suoraan varsinaiset syntaksivirheet.
Kehitysvaiheessa kannattaa tulostaa mahdollisimman monen muuttujan arvo näytille, koska monasti virhe löytyy sillä tavalla helpommin.
Mikään kysely ei tee virhettä, kirjautuessa kaikki tiedot kirjataan oikein kantaan, mutta käyttäjän tunnistus uupuu.
Sitä en saa mistään...
<?php include("config.php"); //muuta config.php:n polku oikeaksi //avataan yhteys tietokantaan $lnk = mysql_connect($db_server,$db_user,$db_passwd) or die (mysql_error()); mysql_select_db($db_db,$lnk) or die (mysql_error()); //käyttäjä on oletuksena false. Älä varsinkaan poista, ellet tiedä mitä teet :) $user = false; /* SISÄÄNKIRJAUTUMINEN */ if(isset($_POST['tunnus']) && isset($_POST['salasana'])){ //muuttujat turvallisesti talteen $tunnus = get_magic_quotes_gpc() ? $_POST['tunnus'] : mysql_real_escape_string($_POST['tunnus']); $salasana = get_magic_quotes_gpc() ? $_POST['salasana'] : mysql_real_escape_string($_POST['salasana']); $salasana = md5($salasana); //luodaan käyttäjäkohtainen uniikki id $istuntotunnus = md5(uniqid("")); //lisätään istunto tietokantaan käyttäjän tietoihin mysql_query("UPDATE {$tbl_users} SET istunto = '{$istuntotunnus}' WHERE tunnus = '{$tunnus}' AND salasana = '{$salasana}'",$lnk) or die (mysql_error()); if(mysql_affected_rows($lnk) == 1){ setcookie("log_key", "$istuntotunnus"); echo "Katsotaan onko kirjauduttu (Päivitä, näkyykö cryptattu id?): " . $_COOKIE["log_key"] . ""; } } /* ULOSKIRJAUTUMINEN */ if(isset($_REQUEST['logout'])){ setcookie("log_key", ""); setcookie("log_key", "", time() - 60 * 10); echo "Logget out"; } /* KÄYTTÄJÄN TUNNISTUS */ if(isset($_COOKIE['log_key'])){ //HAETAAN KÄYTTÄJÄN TIEDOT $sql = "SELECT id, tunnus, DATE_FORMAT(last_load,'%d.%m.%y %h:%i:%s') AS last_load FROM {$tbl_users} WHERE istunto = '".mysql_real_escape_string($_COOKIE['log_key'])."'"; $sql = mysql_query($sql,$lnk) or die(mysql_error()); if($sql && mysql_num_rows($sql) == 1){ $user = mysql_fetch_assoc($sql); mysql_query("UPDATE {$tbl_users} SET last_load = NOW() WHERE id = ".$user['id'], $lnk) or die(mysql_error()); } } //Jos ei ole taulua, luodaan se mysql_query("CREATE TABLE IF NOT EXISTS `{$tbl_users}` ( id int(11) NOT NULL auto_increment, tunnus varchar(50) default NULL, salasana varchar(32) default NULL, oikeanimi TEXT, email varchar(60) default NULL, ika INT, kotisivu TEXT, kuvaus TEXT, last_load timestamp(14) NOT NULL, istunto varchar(32) default NULL, PRIMARY KEY (id), UNIQUE KEY istunto (istunto) )",$lnk);
Nyt on noin. Tuossa käyttäjän tunnistus kohdassa uskoisin sen virheen olevan, mutta en tiedä mikä se on.
Minkätakia tallennat käyttäjän tiedot aina omaan tauluun? Eikö se mene niin, että taulujen määrä ei saa lisääntyä vaikka tiedon määrä kasvaa? Eli voisithan vain tehdä taulun nimeltä "kayttajat" ja yhdessä tietueessa olisi yhden käyttäjän tiedot. Samoin tuo istuntotunnisteen tallentaminen kantaa on minusta hieman turhaa eikö ihan vain istuntojen käyttö olisi parempi tapa... Ja sen käyttäjän tunnistuksen voisi tehdä vaikka näin:
<?php $sql = "SELECT * FROM kayttajat WHERE tunnus = '{$tunnus}' AND salasana = '{$salasana}'"; $tulos = mysql_query($sql,$yhteys); if (mysql_fetch_assoc($tulos)) { echo "Sisällä ollaan!"; } ?>
Tässähän yksinkertaisesti tehdään select-haku ja tarkistetaan löytyykö annetuilla tunnus-salasana-parilla yhtään riviä... Kannattaisi käyttää myös jotain suolaa salasanoissa ja itse käyttäisin myös SHA1-tiivistealgoritmia...
Ei käyttäjän tietoja tallenneta omaan tauluun, vaan jokainen käyttäjä on oma tietueensa taulussa kayttajat. Minulla on siis itselläni juurikin sama scripti käytössä hieman muokattuna tosin.
Toni: Ei siellä ole jokaiselle omaa taulua. Myös tuo sinun tunnistuksesi on ihan sama tehtynä toisella tavalla kuin minun; Tuo palauttaa true/false mutta minun numeron 0/1.
Teuro, miten sinun eroaa tuosta koodivinkistä? =)
Muuntelin myös vähän, ihan kokeiluksi:
<?php include("config.php"); //muuta config.php:n polku oikeaksi //avataan yhteys tietokantaan $lnk = mysql_connect($db_server,$db_user,$db_passwd) or die (mysql_error()); mysql_select_db($db_db,$lnk) or die (mysql_error()); //käyttäjä on oletuksena false. Älä varsinkaan poista, ellet tiedä mitä teet :) $user = false; /* SISÄÄNKIRJAUTUMINEN */ if(isset($_POST['tunnus']) && isset($_POST['salasana'])){ //muuttujat turvallisesti talteen $tunnus = get_magic_quotes_gpc() ? $_POST['tunnus'] : mysql_real_escape_string($_POST['tunnus']); $salasana = get_magic_quotes_gpc() ? $_POST['salasana'] : mysql_real_escape_string($_POST['salasana']); $salasana = md5($salasana); //luodaan käyttäjäkohtainen uniikki id $istuntotunnus = md5(uniqid("")); //lisätään istunto tietokantaan käyttäjän tietoihin mysql_query("UPDATE {$tbl_users} SET istunto = '{$istuntotunnus}' WHERE tunnus = '{$tunnus}' AND salasana = '{$salasana}'",$lnk) or die (mysql_error()); if(mysql_affected_rows($lnk) == 1){ setcookie("log_key", "$istuntotunnus"); echo "Katsotaan onko kirjauduttu (Päivitä, näkyykö cryptattu id?): " . $_COOKIE["log_key"] . ""; } } /* ULOSKIRJAUTUMINEN */ if(isset($_REQUEST['logout'])){ setcookie("log_key", ""); setcookie("log_key", "", time() - 60 * 10); echo "Logget out<br />"; } if(!isset($_COOKIE["log_key"])) { echo "Ei ole kirjauduttu<br />"; } /* KÄYTTÄJÄN TUNNISTUS */ if(isset($_COOKIE['log_key'])){ //HAETAAN KÄYTTÄJÄN TIEDOT $sql = "SELECT id, tunnus, DATE_FORMAT(last_load,'%d.%m.%y %h:%i:%s') AS last_load FROM {$tbl_users} WHERE istunto = '".mysql_real_escape_string($_COOKIE['log_key'])."'"; $sql = mysql_query($sql,$lnk) or die(mysql_error()); if($sql && mysql_num_rows($sql) == 1){ $user = mysql_fetch_assoc($sql); mysql_query("UPDATE {$tbl_users} SET last_load = NOW() WHERE id = ".$user['id'], $lnk) or die(mysql_error()); } } //Jos ei ole taulua, luodaan se mysql_query("CREATE TABLE IF NOT EXISTS `{$tbl_users}` ( id int(11) NOT NULL auto_increment, tunnus varchar(50) default NULL, salasana varchar(32) default NULL, oikeanimi TEXT, email varchar(60) default NULL, ika INT, kotisivu TEXT, kuvaus TEXT, last_load timestamp(14) NOT NULL, istunto varchar(32) default NULL, PRIMARY KEY (id), UNIQUE KEY istunto (istunto) )",$lnk);
Siltikään ei toimi.
Miteköhän olet sitten tallentanut nuo tiedot? Ihmettelen edelleen sitä, että tuossa update-kyselyssä sinulla on taulun nimen paikalla muuttuja $tbl_users eli silloin tuo taulun nimi on vaihtuva? Samoin luot tuossa samaisessa koodissa uuden taulun uutta käyttäjää varten...
Luepa tuo ajv:n vinkki läpi. require('config.php'); sisältää tietokannan asetukset, muun muassa käyttäjätaulun nimen ($tbl_user). Tuon viimeisen SQL lauseen voi toki poistaakin, ei se mitään uutta taulua luo, koska sellainen on jo olemassa. Lisäksi lauseessa todetaan explisiittisesti IF NOT EXISTS, joka siis tarkoittaa, että jos taulua ei ole olemassa.
Tutkis tuota ajv:n koodivinkkiä, niin tiedät mitä tuo $tbl_users tarkoittaa. Vilkaise sitä config.php:tä.
Edit: Teuro ehtikin ensiksi... Mutta, sitä ihan oikeaa ongelmaa jos edetään...
Teuro kirjoitti:
Luepa tuo ajv:n vinkki läpi. require('config.php'); sisältää tietokannan asetukset, muun muassa käyttäjätaulun nimen ($tbl_user). Tuon viimeisen SQL lauseen voi toki poistaakin, ei se mitään uutta taulua luo, koska sellainen on jo olemassa. Lisäksi lauseessa todetaan explisiittisesti IF NOT EXISTS, joka siis tarkoittaa, että jos taulua ei ole olemassa.
No siinä tapauksessa...
Joo, no palataankos ihan siihen ongelmaan?
Tiedättekö miksi ei toimi? :/ Minä en keksi ainakaan mitään syytä siihen.
Tuossa käyttäjän tunnistuksessa on se ongelma. Se ei saa tuohon $user tauluun tietoja...
En nyt ole hetkeen seurannut tätä ketjua, mutta heitänpä tähän jotain kuitenkin jos tuota lähti debuggaamaan, niin kannattaa varmistaa:
1. Että mitä tuolla $_COOKIE['log_key']:ssa on sisältönä ennen tuon kyselyn tekemistä.
2. Katsoa löytyykö kannasta varmasti vastaava tieto.
3. Ajaa tuo sun kyselys suoraan jostain SQL clientistä ja katsoa mitä palautuu vai palautuuko mitään, jospa noilla pääsis jo jäljille missä ongelma piilee.
Luultavasti se ei mene tuon sun if -lauseen sisälle, koska se sun ehtos ei jostain syystä toteudu ja sen takia, user on edelleen false tuon kyselynkin jälkeen.
Voit myös kokeilla tuota sun iffin sisällä olevaa ehtoa var_dumpilla juuri ennen sitä if lausetta ja kattoa mitä siihen ehtoon tulee (true vai false)
<?php var_dump($sql && mysql_num_rows($sql) == 1); ?>
Palauttaa "bool(false)" kun on tuossa kirjautumiskyselyn edessä, mutta siellä käyttäjätunnistuskohdassa kyselyn suorittamisen jälkeen/tai sen edessä ei palauta mitään.
Keksissä on sisältönä md5-hassattu "uniqid".
Sen verran sain tietoon, että virhe tulee siitä, että käyttäjän tunnistuksessa arvo on $sql:ssä 0 eli false. Tutkin mistä tulee...
Edit: Täällä Putkassahan pystyy määrittämään, kirjautuuko sessioneilla vai ei, niin heittääkö koodi tunnukset sitten keksiin ja niiden kanssa sitten kirjautuu?
Nyt tämä menee mielestäni vähän hankalaksi, kun ei tuo onnistu.
Ongelma on nähtävästi tuossa "istuntotunnuksessa".
Koodi stoppaa tähän kyselyyn:
<?php $sql = "SELECT id, tunnus, DATE_FORMAT(last_load,'%d.%m.%y %h:%i:%s') AS last_load FROM {$tbl_users} WHERE istunto = '".mysql_real_escape_string($_COOKIE['log_key'])."'"; ?>
Kun sen laittaa näin
<?php $sql = "SELECT id, tunnus, DATE_FORMAT(last_load,'%d.%m.%y %h:%i:%s') AS last_load FROM {$tbl_users} WHERE tunnus = '$tunnus' AND salasana = '$salasana'"; ?>
... Se kirjaa tunnuksen last_loadit sun muut, mutta tämä ei kuitenkaan toimi oikein.
Kun sivulta poistuu, tiedot nollaantuvat (Ei kannassa). Eli tulos on se, että log_keyn ja istunnon (kannassa) uniqid:t eivät ole samat.
Tuon keksijutun sain toimimaan, mutta viestin lähetyksessä on ongelmia.
Toisaalta olisi hyvä, että liian pitkiä viestejä ei kirjoitettaisi, mutta en haluaisi sen kuitenkaan tulostavan tätä errororia, "Got a packet bigger than 'max_allowed_packet' bytes".
Tiedän miten saan oman errorin tuon tilalle, mutta paljonkohan tuo max_allowed_packet on?
Laitoin kasan kirjaimia viestiin, ja teki tuon errorin.
mysql_query("SET @@session.max_allowed_packed=xxxxx");
Näin saa muutettua sitä?
MIB kirjoitti:
Tiedän miten saan oman errorin tuon tilalle, mutta paljonkohan tuo max_allowed_packet on?
Oletuksena palvelimen on 1MB ja asiaksohjelman 16MB.
MIB kirjoitti:
mysql_query("SET @@session.max_allowed_packed=xxxxx");Näin saa muutettua sitä?
Pikaisen Googletuksen jälkeen, sitä ei nähdäkseni voi muuttaa lennosta.
http://dev.mysql.com/doc/refman/5.1/en/packet-too-large.html
http://www.vbulletin.com/forum/showpost.php?p=621869&postcount=2
Okei, kiitos tiedosta.
Koitan asentaa tässä SMTP ohjelmaa Xamppliten seuraksi, vaikuttaa tosin aika toivottomalta. Tarkistankin, olisiko Xamppissa jo itsessään SMTP ohjelma...
Muuten, kun tein tuommoisen viestin muokkaussysteemin, niin haluaisin tehdä myös niin kuin täällä Putkassa, että tunnin sisällä vain voi muokata viestiään.
Jos aika olisi 1245663507 milloin viesti on lähetetty, niin voinko verrata aikaa niin, että lisää tuohon 3600, niin tuleeko siitä silloin oikea aika?
Luulisin, mutta en ole ihan perillä siitä mitkä kohdat tuosta sarjasta vastaa mitäkin yksikköä.
Edit: Ja kun aika on haettu kannasta tietyn viestin kohdalta, niin vertaus menee näin: (?)
Mutta, kun tuossa on tuo If-lause, niin miten päin tuon merkin kuuluisi olla? :D
Nyt tökkii vähäsen, en muista miten sen kuuluisi olla...
Edit: Joo, näin se toimii ;)
Edit (Taas kerran):
Niin, vielä sellainen, että jos aiheeseen on vastattu ennen kuin muokkausaika on umpeutunut, niin ei pystyisi muokkaamaan viestiä.
Miten tämä kannattaisi tehdä? Viestit on ryhmitelty aihe_id:n mukaan.
Toiseen kysymykseen saat etsiä ratkaisun itse, mutta haluat siis lomakkeen näkyville, mikäli aikaa on kulunut lähetyksestä vähemmän kuin tunti? Silloin otat viestin lähetyksen yhteydessä tallennetun aikaleima, johon lisäät sopivasti aikaa, jonka jälkeen vertaat nykyistä aikaleimaa laskettuun aikaleimaan.
Sen sainkin tehtyä, mutta katsos tuo vika edit kohta. :D
Katsot onko kyseisen henkilön viimeisin lähetetty viesti kyseisen langan viimeinen viesti.
Vai kannattaako minun laskea kaikki viestit siitä viestiketjusta ja sitten katsoa, että jos kyseisen viestin id on pienmpi kuin total määrä, niin on vastattu, muutoin näytetään taas se muokkauslomake?
Tämä olisi minusta helpompi toteuttaa, ainakin näen sen selvästi päässäni miten se menisi.
Eli Teuron esimerkin mukaan viesti_id olisi sen viestin numero (tuohon tulisi muuttuja), ja viimeisin olisi viestien yhteismäärä aiheessa?
Ei myöskään haittaa, että jos toiseen aiheeseen vastataan siinä välissä, tuo toimii silti?
MIB kirjoitti:
Vai kannattaako minun laskea kaikki viestit siitä viestiketjusta ja sitten katsoa, että jos kyseisen viestin id on pienmpi kuin total määrä, niin on vastattu, muutoin näytetään taas se muokkauslomake?
Jos viesteillä on automaagisesti kasvava indeksointi, niin tuo malli ei toimi mitenkään, koska viimeistään toisessa langassa jokaisen viestin id on suurempi, kuin langassa olevien viestien määrä.
MIB kirjoitti:
Ei myöskään haittaa, että jos toiseen aiheeseen vastataan siinä välissä, tuo toimii silti?
Miten toinen lanka, jota ei edes käsitellä tässä kyselyssä voisi vaikuttaa tuohon?
Teuro kirjoitti:
Jos viesteillä on automaagisesti kasvava indeksointi, niin tuo malli ei toimi mitenkään, koska viimeistään toisessa langassa jokaisen viestin id on suurempi, kuin langassa olevien viestien määrä.
Okei, no heitetään tämä idea mereen.
Teuro kirjoitti:
Miten toinen lanka, jota ei edes käsitellä tässä kyselyssä voisi vaikuttaa tuohon?
Ajattelin vähän sekavasti. Kauppareissu auttoi tässä asiassa, nyt sain toimimaan tuon sinun esimerkin, vähän kantapään kautta :)
<?php $yhteys = mysql_connect("localhost", "root", ""); mysql_select_db("forum"); $id = $_GET["id"]; $kysely = "SELECT * FROM viestit WHERE aihe_id = '".$_GET["aihe"]."' ORDER BY aika DESC LIMIT 1"; $hae = mysql_query($kysely) or die(mysql_error()); for ($i = 0; $i < mysql_num_rows($hae); $i++) { $vika = mysql_result($hae, $i, "viesti_id"); if ($id !== $vika) { echo "Viestiin on vastattu"; }else { echo "Viestiin ei ole vastattu"; } } mysql_close($yhteys); ?>
Voisi sen varmaan helpomminkin tehdä.. :D Sanokaa vain, miten tuon voisi paremmin tehdä. Mielestäni tuo kyllä on 10 arvoinen siihen verrattuna, mitä osaan :D
Hei,
Olen nyt säätämässä profiilisivua tässänäin, mutta tuli yksi ongelma
Sivulla on ensin kaikenlaisia tietoja käyttäjästä, käytännössä samat kuin Putkassa noihin kuviin asti, johon ongelmani liittyykin.
Olen käyttänyt Antin koodivinkkiä apuna ympyrädiagrammiin, ja se pitäisi asettaa sivun alareunaan.
Ongelmana on se, että se sanoo "Headers already sent...", koska sivulla tulostetaan tavaraa ennen kuvaa. Miten saisin tämän kuvan sivun alareunaan?
Mahdatko käyttää GD kirjastoa kuvan generointiin? Mikäli näin kannattaa itse kuvan piirto tehdä omassa tiedostossaan, jossa otsikot laitetaan heti tiedoston alussa kuntoon. Itse sivulla, jonne kuvan haluat voit laittaa ihan normaalin kuva tagin, jossa src kohta on kuvan generoivan tiedoston osoite.
<?php /* kuva.php */ /* Antin GD-opas */ //lähetetään tunniste selaimelle header("Content-type: image/png"); //luodaan 200x100-pikselin kokoinen kuva $kuva=imagecreate(200,100); //määritetään taustaväri ja kaksi muuta väriä $tausta=imagecolorallocate($kuva, 255, 255, 255); $musta=imagecolorallocate($kuva,0,0,0); $sininen=imagecolorallocate($kuva,0,0,255); //piirretään kehykset, teksti ja viiva imagerectangle($kuva,0,0,199,99,$musta); imagestring($kuva,2,10,10,"GD-kirjasto toimii!",$sininen); imageline($kuva,10,24,130,80,$sininen); //lähetetään kuva PNG-muodossa imagepng($kuva); //poistetaan kuva muistista imagedestroy($kuva); ?>
<?php /* profiili.php */ echo "<img src=\"kuva.php\" alt=\"viestien aluejakauma\" />"; ?>
Empä tullut ajatelleeksi, että voi laittaa noin... :D Kiitos avusta.
Toisena olisi sellainen ongelma, että kun pitää hakea viestien määrä per käyttäjä per alue, niin tulee ongelmia.
Viestit taulussa ei viitata missään kohdin alueisiin. Viesteissä on aihe_id joka viittaa aiheeseen ja aihe taulussa on alue_id, joka viittaa alueeseen.
Tältä näyttää toivoton yritykseni:
<?php //kuvan alustaminen $leveys=400;$korkeus=230; header ("Content-type: image/png"); $im = @ImageCreate ($leveys, $korkeus) or die ("GD-kirjaston käyttäminen ei onnistu!"); $valkoinen = ImageColorAllocate ($im, 255, 255, 255); $musta=ImageColorAllocate ($im, 0, 0, 0); $y = mysql_connect ("localhost", "root", ""); mysql_select_db("forum"); $haku = mysql_query(" SELECT v.viestit, a.alue FROM alueet AS a LEFT JOIN viestit AS v WHERE id = '".$_GET["id"]."'"); $nso = mysql_num_rows($haku); $yk = "100"; //kuvaajan tiedot $otsikko="Viestien aluejakautuma"; $arvo[0][0]=$nso; $arvo[0][1]="Ns. ja -o"; $arvo[1][0]=$yk; $arvo[1][1]="Yleinen k."; $yksikko=""; //arvojen yhteismäärä ja värien määritys for ($i=0;$i<count($arvo);$i++) { $yht=$yht+$arvo[$i][0]; $arvo[$i][2]=ImageColorAllocate ($im, $i*60,($i+1)*60,($i+2)*60); } //kehykset ImageRectangle($im,1,1,$leveys-1,$korkeus-1,$musta); ImageRectangle($im,$leveys-150,40,$leveys-10, 40+count($arvo)*(ImageFontHeight(2)+4),$musta); //otsikko $opituus=ImageFontWidth(5)*strlen($otsikko); $okohta=$leveys/2-$opituus/2; ImageString($im,5,$okohta,5,$otsikko,$musta); //kuvion piirtäminen $vkulma=0; for ($i=0;$i<count($arvo);$i++) { ImageFilledRectangle($im,$leveys-145,43+$i*(ImageFontHeight(2)+4), $leveys-138,50+$i*(ImageFontHeight(2)+4),$arvo[$i][2]); ImageString($im,2,$leveys-135,40+$i*(ImageFontHeight(2)+4), $arvo[$i][1]." (".$arvo[$i][0].$yksikko.")",$musta); $kulma=($arvo[$i][0]/$yht)*360; ImageFilledArc($im,120,120,180,180,$vkulma, $vkulma+$kulma,$arvo[$i][2],IMG_ARC_PIE); $vkulma=$kulma+$vkulma; } ImageArc($im,120,120,180,180,0,360,$musta); //kuva PNG-muotoon ImagePNG ($im); ?>
Koitin myös kyselynä tälläistä:
SELECT v.id, ai.alue_id, al.id FROM viestit AS v LEFT JOIN aiheet AS ai ON v.id=ai.lahettaja_id LEFT JOIN alueet AS al ON ai.alue_id=al.id WHERE id = '".$_GET["id"]."'";
Mutta, miten minä tässä nyt sitten laskisin nuo arvot... :S
Teuro kirjoitti:
<?php $a = 0; while($rivi = mysql_fetch_array($tulos)){ echo"<tr>"; $vari = ($a % 2 == 0) ? 'punainen' : 'vihrea'; echo"<td class=\"$vari\">".$rivi['otsikko']."</td>"; $a++; echo"</tr>"; }Ei niin kamalan hankalaa eihän?
Kokeilin tätä niin, että täytin kaikki kohdat oikein.
Laitoin vain classin tilalle bgcolor ja nuo värit kuntoon.
Se ei vain toiminut. :/ Kaikki meni siksi väriksi mikä on punaisen kohdalla.
<?php require_once("yla.php"); require_once("ylaosa.php"); mysql_query("CREATE TABLE alueet( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, alue TEXT)"); $ky = "SELECT * FROM alueet"; $ha = mysql_query($ky) or die(mysql_error()); //Luodaksesi uuden aiheen, mene luoalue.php tiedostoon echo '<table class="teksti" width="95%" cellspacing="0">'; echo "Keskustelu<br><br>"; echo '<tr class="taulukkoyla"> <td><b>Alue</b></td><td><b>Aiheita / Viestejä</b></td><td><b>Uusin viesti</b></td></tr>'; for ($i = 0; $i < mysql_num_rows($ha); $i++) { $alue = mysql_result($ha, $i, "alue"); $id = mysql_result($ha, $i, "id"); $ky2 = "SELECT * FROM aiheet WHERE alue_id = '$id'"; $ha2 = mysql_query($ky2) or die(mysql_error()); $k = "SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$id'"; $h = mysql_query($k) or die(mysql_error()); $a = mysql_num_rows($ha2); $v = mysql_num_rows($h); $k = "SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$alue_id' ORDER BY viestit.aika DESC LIMIT 1"; $h = mysql_query($k) or die(mysql_error()); $hh = mysql_query("SELECT * FROM viestit WHERE alue = '$id' ORDER BY aika DESC LIMIT 1"); while ($rii = mysql_fetch_assoc($hh)) { $ao = $rii["otsikko"]; $aol = $rii["aihe_id"]; $aa = date("d.m.Y H:i:s", $rii["aika"]); $al = $rii["lahettaja_id"]; $aal = $rii["alue"]; $ali = $rii["id"]; } $a = 0; while($rivi = mysql_fetch_array($ha)){ $vari = ($a % 2 == 0) ? 'EAEAEA' : 'FFFFFF'; $vikaviesti = "<a href=\"alue.php?aiheid=$aol&alue=$aal\">$ao</a><br>$aa<br><a href=\"profiili.php?id=$ali\">$al</a>"; echo "<tr bgcolor=\"$vari\"><td><a href=\"alueet.php?alue=$id\">$alue</a></td> <td>$a / $v</td><td><br>$vikaviesti<br></td></tr>"; $a++; } } echo "</table>"; require_once("alaosa.php"); ?>
Kaikki muu toimii oikein.
$vari = ($a % 2 == 0) ? 'EAEAEA' : 'FFFFFF';
=>
$vari = ($a % 2 == 0) ? '#EAEAEA' : '#FFFFFF';
:)
Ei se siitä kyllä johdu. Ongelma on se, että se tulostaa vain ensimmäisen alueen.
Mitä tulee tulostukseen seuraavalla koodilla?
<?php /* Laita tähän tietokannan asetukset */ $alueet = mysql_query("SELECT alue, id FROM alueet ORDER BY id"); while($rivi = mysql_fetch_array($alueet)){ echo "Alue = " . $rivi['alue'] . " id = " . $rivi['id'] . "<br />"; } ?>
Tulee tulostukseen kaikki alueet ja niiden id numerot? Mikäli ei tule tarkista tietokannan alueet taulu huolellisesti läpi, että siellä ei ole mitään virheitä. Sitten aja seuraava koodinpätkä läpi. Tässä on muutoin sama kysely, mutta jokaisen alueen alapuolelle pitäisi tulostua alueella olevat viestit.
<?php /* Laita tähän tietokannan asetukset */ $alueet = mysql_query(" SELECT alue, id FROM alueet ORDER BY id"); while($rivi = mysql_fetch_array($alueet)){ echo "Alue = " . $rivi['alue'] . " id = ".$rivi['id']."<br />"; $viestit = mysql_query(" SELECT otsikko FROM viestit, aiheet WHERE viestit.id = $rivi['id']"); while($tiedot = mysql_fecth_array($viesit)){ echo $tiedot['otsikko'] . "<br />"; } } ?>
Mikäli ei hirmuisia typoja tullut, niin noiden kahden koodipätkän pitäisi tulostaa kaikki kannassa olevat alueet ja niiden alle otsikot.
Taulussa ei ole mitään ongelmia, kaikki on pilkun tarkalleen oikein.
Tuo ensimmäinen koodisi toimii (Tulostaa alueet 1 ja 2 + nimet), mutta tuo toinen tulostaa alueet 1 2 ja uudelleen 1. Alueita onkin yhteensä 2.
Se toimii myös näin:
<?php $y = mysql_connect("localhost", "root", ""); mysql_select_db("forum"); $alueet = mysql_query("SELECT alue, id FROM alueet ORDER BY id"); $a = 0; echo "<table>"; while($rivi = mysql_fetch_array($alueet)){ $vari = ($a % 2 == 0) ? '#EAEAEA' : '#FFFFFF'; echo "<tr bgcolor=\"$vari\"><td>Alue = " . $rivi['alue'] . " id = " . $rivi['id'] . "</td></tr>"; $a++; } echo "</table>"; mysql_close($y); ?>
.. joka on hyvä asia. Mutta tuon kun laittaa for silmukan sisään, niin eipä enään toimikkaan: Kaikki tulostuvat kahdesti:
<?php require_once("yla.php"); require_once("ylaosa.php"); $ky = "SELECT * FROM alueet"; $ha = mysql_query($ky) or die(mysql_error()); //Luodaksesi uuden aiheen, mene luoalue.php tiedostoon echo '<table class="teksti" width="95%" cellspacing="0">'; echo "Keskustelu<br><br>"; echo '<tr class="taulukkoyla"> <td><b>Alue</b></td><td><b>Aiheita / Viestejä</b></td><td><b>Uusin viesti</b></td></tr>'; for ($i = 0; $i < mysql_num_rows($ha); $i++) { $alue = mysql_result($ha, $i, "alue"); $id = mysql_result($ha, $i, "id"); $ky2 = "SELECT * FROM aiheet WHERE alue_id = '$id'"; $ha2 = mysql_query($ky2) or die(mysql_error()); $k = "SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$id'"; $h = mysql_query($k) or die(mysql_error()); $a = mysql_num_rows($ha2); $v = mysql_num_rows($h); $k = "SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$alue_id' ORDER BY viestit.aika DESC LIMIT 1"; $h = mysql_query($k) or die(mysql_error()); $hh = mysql_query("SELECT * FROM viestit WHERE alue = '$id' ORDER BY aika DESC LIMIT 1"); while ($rii = mysql_fetch_assoc($hh)) { $ao = $rii["otsikko"]; $aol = $rii["aihe_id"]; $aa = date("d.m.Y H:i:s", $rii["aika"]); $al = $rii["lahettaja_id"]; $aal = $rii["alue"]; $ali = $rii["id"]; } /* $a = mysql_num_rows($ha); while($rivi = mysql_fetch_assoc($ha)){ $vari = ($a % 2 == 0) ? '#EAEAEA' : '#FFFFFF'; $a++; } $vikaviesti = "<a href=\"alue.php?aiheid=$aol&alue=$aal\">$ao</a><br>$aa<br><a href=\"profiili.php?id=$ali\">$al</a>"; echo "<tr bgcolor=\"$vari\"><td><a href=\"alueet.php?alue=$id\">$alue</a></td> <td>$a / $v</td><td><br>$vikaviesti</td></tr>"; }*/ $alueet = mysql_query("SELECT alue, id FROM alueet ORDER BY id"); $a = 0; while($rivi = mysql_fetch_array($alueet)){ $vari = ($a % 2 == 0) ? '#EAEAEA' : '#FFFFFF'; $vikaviesti = "<a href=\"alue.php?aiheid=$aol&alue=$aal\">$ao</a><br>$aa<br><a href=\"profiili.php?id=$ali\">$al</a>"; echo "<tr bgcolor=\"$vari\"><td><a href=\"alueet.php?alue=$id\">$alue</a></td> <td>$a / $v</td><td><br>$vikaviesti</td></tr>"; $a++; } } echo "</table>"; require_once("alaosa.php"); ?>
Kaikki toimii, kuten pitääkin kun koodi on näin: (Miinus siitä noi värit sitten...)
<?php require_once("yla.php"); require_once("ylaosa.php"); $ky = "SELECT * FROM alueet"; $ha = mysql_query($ky) or die(mysql_error()); //Luodaksesi uuden aiheen, mene luoalue.php tiedostoon echo '<table class="teksti" width="95%" cellspacing="0">'; echo "Keskustelu<br><br>"; echo '<tr class="taulukkoyla"> <td><b>Alue</b></td><td><b>Aiheita / Viestejä</b></td><td><b>Uusin viesti</b></td></tr>'; for ($i = 0; $i < mysql_num_rows($ha); $i++) { $alue = mysql_result($ha, $i, "alue"); $id = mysql_result($ha, $i, "id"); $ky2 = "SELECT * FROM aiheet WHERE alue_id = '$id'"; $ha2 = mysql_query($ky2) or die(mysql_error()); $k = "SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$id'"; $h = mysql_query($k) or die(mysql_error()); $a = mysql_num_rows($ha2); $v = mysql_num_rows($h); $k = "SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$alue_id' ORDER BY viestit.aika DESC LIMIT 1"; $h = mysql_query($k) or die(mysql_error()); $hh = mysql_query("SELECT * FROM viestit WHERE alue = '$id' ORDER BY aika DESC LIMIT 1"); while ($rii = mysql_fetch_assoc($hh)) { $ao = $rii["otsikko"]; $aol = $rii["aihe_id"]; $aa = date("d.m.Y H:i:s", $rii["aika"]); $al = $rii["lahettaja_id"]; $aal = $rii["alue"]; $ali = $rii["id"]; } $vikaviesti = "<a href=\"alue.php?aiheid=$aol&alue=$aal\">$ao</a><br>$aa<br><a href=\"profiili.php?id=$ali\">$al</a>"; echo "<tr bgcolor=\"$vari\"><td><a href=\"alueet.php?alue=$id\">$alue</a></td> <td>$a / $v</td><td><br>$vikaviesti</td></tr>"; } echo "</table>"; require_once("alaosa.php"); ?>
Alemmassa while silmukassa oli typo siellä luki $rivi, vaikka piti lukea $tiedot. Kokeilepa nyt uudelleen tuota. Lisäksi kannattaa jättää kaikkia ulkopuolinen tauhka pois ja keskittyä saamaan oikeat tulokset esiin. Lopuksi vielä sellainen kommentti, että nimeä muuttujat paremmin ja laita kyselyyn vain ne kentät, joita aiot käyttää jatkossa.
Ei siis kannata hakea kaikkia kenttiä kannasta, mikäli käyttää vain kahta niistä. Lisäksi samlla voi kyselyssä muotoilla esimerkiksi päivämäärät oikeaan muotoon jo valmiiksi.
Teuro kirjoitti:
Lopuksi vielä sellainen kommentti, että nimeä muuttujat paremmin ja laita kyselyyn vain ne kentät, joita aiot käyttää jatkossa.
:D Hehe. Ne ovat kyllä kaikki lyhenteitä siitä mitä ne tekevät. Arvasin, että joku vielä sanoo siitä. :D
Joo, tajusin kyllä korjata tuon itse kuin luin sitä, mutta se tekee silti erroria. Tuloksena on:
Alue = alue1 id = 1 Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampplite\htdocs\foorumi\testii.php on line 26 Alue = alue2 id = 2 Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampplite\htdocs\foorumi\testii.php on line 26
Kun koodista oli virheet korjattuna:
<?php $y = mysql_connect("localhost", "root", ""); mysql_select_db("forum"); $alueet = mysql_query(" SELECT alue, id FROM alueet ORDER BY id"); while($rivi = mysql_fetch_array($alueet)){ echo "Alue = " . $rivi['alue'] . " id = ".$rivi['id']."<br />"; $viestit = mysql_query(" SELECT otsikko FROM viestit, aiheet WHERE viestit.id = '".$rivi['id']."'"); while($tiedot = mysql_fetch_array($viesit)){ echo $tiedot['otsikko'] . "<br />"; } } mysql_close($y); ?>
Vieläkään et ole oppinut jo satoja viestejä sitten neuvottua asiaa: tarkista kyselyiden virheet ja tulosta mysql_error()-funktion palauttama ilmoitus.
Kyllä ne on katsottu.
Se sanoo "Column 'otsikko' in field list is ambiguous" (Jäi mainitsematta viime viestistä). Ongelma ei poistu vaikka tuota kyselyä muokkaisin niin, että hakee vain yhdestä taulusta..
MIB kirjoitti:
Kyllä ne on katsottu.
Se sanoo "Column 'otsikko' in field list is ambiguous" (Jäi mainitsematta viime viestistä). Ongelma ei poistu vaikka tuota kyselyä muokkaisin niin, että hakee vain yhdestä taulusta..
Ihan varmasti poistuu tuo kyseinen virhe, jos haet vain yhdestä taulusta, koska tuo error kertoo, että haettu kenttä ei ole yksiselitteinen. Samassa taulussa ei siis voi olla kahta identtistä kenttää, joten tuota virhettä ei voi tulla haettaessa yhdestä taulusta tietoa.
Anteeksi, mun moka.
Siis, se poistuu, mutta nuo muut mitä tuossa mainitsin ylempänä eivät poistu.
Ongelma on tuossa toisessa WHILE silmukassa ilmoitusten mukaan.
Nyt tämän pitäisi olla kaikkien osien oikein:
<?php $y = mysql_connect("localhost", "root", ""); mysql_select_db("forum"); $alueet = mysql_query(" SELECT alue, id FROM alueet ORDER BY id") or die(mysql_error()); while($rivi = mysql_fetch_array($alueet)){ echo "Alue = " . $rivi['alue'] . " id = ".$rivi['id']."<br />"; $viestit = mysql_query(" SELECT otsikko FROM viestit WHERE alue = '".$rivi['id']."'") or die(mysql_error()); while($tiedot = mysql_fetch_array($viesit)){ echo $tiedot['otsikko'] . "<br />"; } } mysql_close($y); ?>
No kyselyssä numeraalien ympärille ei kuulu laittaa hipsuja, muuten tuo näyttää ihan oikealta.
Jotenkin musta alkaa tuntumaan siltä, että yrität samaan aikaan rakentaa kamalan montaa asiaa. Se eittämättä sekoittaa monelta osin ajattelua, joten voisin jopa suositella, että seuraavaksi suunnittelet ja rajaat ongelman osiksi, jonka jälkeen ratkot ongelmat yksi kerrallaan.
Nyt ei kyllä onnistu. :/
Lähin, mitä saan aikaan, näyttää tältä:
ALUE: AIHETA / VIESTEJÄ: VIIMEISIN: Alue1 Aiheta / Viestejä Viimeisin Alue1 Aiheta / Viestejä Viimeisin Alue2 Aiheta / Viestejä Viimeisin Alue2 Aiheta / Viestejä Viimeisin
Jossa aiheta ja viestejä arvot ovat ihan päin kuusta.
Sulla on typo tuolla toisessa while silmukassa, $viesit --> $viestit.
TeNDoLLA kirjoitti:
Sulla on typo tuolla toisessa while silmukassa, $viesit --> $viestit.
Onneksi täällä on tarkkasilmäisiä :) No, kyllähän se nyt toimii, paitsi sitä taustaväri juttua en saa millä toimimaan. :( Osaisitko auttaa tässäkin? :D
Pistäppä se koodin pätkä vielä kertaalleen missä se värin tulostus tapahtuu ja millanen seon tällä hetkellä. Miks sulla muuten on <br> tuolla tulostuksessa yhden <tr> tagin sisällä?
<?php require_once("yla.php"); require_once("ylaosa.php"); $ky = "SELECT * FROM alueet"; $ha = mysql_query($ky) or die(mysql_error()); //Luodaksesi uuden aiheen, mene luoalue.php tiedostoon echo '<table class="teksti" width="95%" cellspacing="0">'; echo "Keskustelu<br><br>"; echo '<tr class="taulukkoyla"> <td><b>Alue</b></td><td><b>Aiheita / Viestejä</b></td><td><b>Uusin viesti</b></td></tr>'; for ($i = 0; $i < mysql_num_rows($ha); $i++) { $alue = mysql_result($ha, $i, "alue"); $id = mysql_result($ha, $i, "id"); $ky2 = "SELECT * FROM aiheet WHERE alue_id = '$id'"; $ha2 = mysql_query($ky2) or die(mysql_error()); $k = "SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$id'"; $h = mysql_query($k) or die(mysql_error()); $a = mysql_num_rows($ha2); $v = mysql_num_rows($h); $k = "SELECT * FROM viestit JOIN aiheet ON viestit.aihe_id=aiheet.id AND aiheet.alue_id='$alue_id' ORDER BY viestit.aika DESC LIMIT 1"; $h = mysql_query($k) or die(mysql_error()); $hh = mysql_query("SELECT * FROM viestit WHERE alue = '$id' ORDER BY aika DESC LIMIT 1"); while ($rii = mysql_fetch_assoc($hh)) { $ao = $rii["otsikko"]; $aol = $rii["aihe_id"]; $aa = date("d.m.Y H:i:s", $rii["aika"]); $al = $rii["lahettaja_id"]; $aal = $rii["alue"]; $ali = $rii["id"]; } $vikaviesti = "<a href=\"alue.php?aiheid=$aol&alue=$aal\">$ao</a><br>$aa<br><a href=\"profiili.php?id=$ali\">$al</a>"; $a = 0; while($rivi = mysql_fetch_array($ha)){ $vari = ($a % 2 == 0) ? '#EAEAEA' : '#FFFFFF'; echo "<tr bgcolor=\"$vari\">"; echo "<td ><a href=\"alueet.php?alue=$id\">$alue</a></td> <td>$a / $v</td><td><br>$vikaviesti</td>"; $a++; echo "</tr>"; } } echo "</table>"; require_once("alaosa.php"); ?>
Tämä näyttää kaiken ihan päin kuusta. Näkyy vain yksi alue (missä id 1) ja siinä on viestit ja aiheet ihan väärin (Siis, tuossa aihetta / viesiä kohdassa).
Jesh, sain tuon toimimaan. :)
Sellainen juttu vielä, että jos haluaisin linkeiksi myös http:// alkuiset, mutta en niitä joissa on pelkkä http://, niin miten tämä pitäisi tehdä? :/
Tällä hetkellä olen näin koittanut:
<?php function varitaPHP($s) { return '<div style="border-style:solid;border-width:1px;background:white">'. highlight_string(html_entity_decode(stripslashes($s)), True). '</div>'; } function bbcode_format($var) { $search = array( '/\http://(.*?)/is', '/\[b\](.*?)\[\/b\]/is', '/\[i\](.*?)\[\/i\]/is', '/\[u\](.*?)\[\/u\]/is', '/\[url\](.*?)\[\/url\]/is', '/\[url\=(.*?)\](.*?)\[\/url\]/is', '/\[lainaus\](.*?)/is', '/\[lainaus "(.*?)"\](.*?)/is', '/\[\/lainaus\]/is', '/\[koodiphp\](.*?)\[\/koodiphp\]/ise' ); $replace = array( '<a href="$1">$1</a>', '<strong>$1</strong>', '<em>$1</em>', '<u>$1</u>', '<a href="$1">$1</a>', '<a href="$1">$2</a>', '<i><small>$1 kirjoitti:</small></i><br><div style="border-style:solid;border-width:1px;background:#E4E9FF;margin-left:8px">$2<br></div>', '<i><small><br>$1 kirjoitti:</small></i><br><div style="border-style:solid;border-width:1px;background:#E4E9FF;margin-left:8px">$2', '<br></div>', "varitaPHP('\\1')" ); $var = preg_replace($search, $replace, $var); return $var; } ?>
MIB kirjoitti:
Sellainen juttu vielä, että jos haluaisin linkeiksi myös http:// alkuiset, mutta en niitä joissa on pelkkä http://, niin miten tämä pitäisi tehdä? :/
$search = array( '/\http://(.*?)/is',
=>
$search = array( '/(http:\/\/.+?)$/is',
Kiitos tuosta, vaikka jouduinkin ottamaan se pois. :/ Koko viesti menee linkiksi, kun tuolla ei ole lopetustagia.
Ohho, aivan, pahoitteluni. Yksi vaihtoehto on korvata tuo .+?
=> [^ ]+
, jolloin se matchaa välilöyntiin asti. Tai sitten Internetistä etsii jonkun regexp:n linkkien parsintaan.
EDIT:
Löysin tällaisen regexp:n:
<?php $search = '/((((https?|ftp):\/\/)|www\.)(([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|net|org|info|biz|gov|name|edu|coop|[a-zA-Z][a-zA-Z]))(:[0-9]+)?((\/|\?)[^ "]*[^ ,;\.:">)])?)+?/is'; $replace = '<a href="\\1">\\1</a>'; echo preg_replace($search, $replace, 'http://www.google.com/, hyvä hakukone');
Nyt tämä ei tee yhtikäs mitään. :o
Empäs huomannutkaan tuota koodinpätkää. :) Kyllä se toimii, kiitos siitä.
Kohta laitan demon nettiin.
Foorumi on nyt valmiina osoitteessa http://kamuweb.jouluserver.com/foorumi/
Ulkoasua en jaksanut vääntää, niin käytän yksinkertaistettua versiota Putkan ulkoasusta, jos se kelpaa Antille?
Jos kirjoittaisitte bugit sinne yleisen keskustelun alueelle, jos niitä ilmenee. :D
Uhhuh, ei tekisi mieli postata näin montaa viestiä peräkkäin, mutta jos muokkaan tuota, niin ei se sieltä ylös nouse ja kukaan ei huomaa mitään, joten pakko tehdä näinkin kivulias toimenpide.
Asiaan:
Tein tässä asennusohjelmaa tähän foorumiin, missä täytetään kaikki MySQL tiedot ja luodaan taulut sun muut.
Ongelmana on se, että miten tallennan nämä MySQL tiedot, eli MySQL serveri, tietokannan nimi, käyttäjätunnus ja salasana? Tietokantaan niitä ei tietenkään voi tallentaa.
Yhtenä ajatuksena tuli tekstitiedosto mieleen, mutta eikös tämä ole vähän turvatonta vaikka salasana olisi kryptattu?
Kysymys: Miten sinä sen tekisit?
Useissa PHP-skripteissä salasanat ovat selkokielisinä skriptin seassa. Tallenna ihan PHP-tiedostona, jonka voit includettaa suoraan skriptissäsi?
Turvallisintahan tietysti olisi tallentaa tiedosto vielä jonnekkin www document rootin ulkopuolelle, mistä sitä ei varmasti serveri maailmalle tarjoilisi, mutta mitenpä tuollaisen polun, johon PHP:tä ajavalla käyttäjätunnuksella olisi kirjoitusoikeus, tietäisi varmasti?
Vastaukseni kysymykseen miten itse tekisit olisi siis, että tallentaisin PHP-skriptinä.
Jos et tallenna suoraan $muuttuja = "arvo"; -tyyliin, muista, että PHP-tulkki voi valittaa virheellisistä riveistä ja paljastaa ne selkokielisinä selaimen suuntaan. Siis joko kommenttimerkkien /* */ väliin tai validina PHP:nä.
Asetustiedostona (.ini, .yaml, jne.) www-rootin ulkopuolelle. Asennuksessa sitten tiedustellaan tuota asetustiedoston polkua jossei automaagisesti löydetä sopivaa hakemistoa.
tsuriga kirjoitti:
Asennuksessa sitten tiedustellaan tuota asetustiedoston polkua jossei automaagisesti löydetä sopivaa hakemistoa.
Ai niin, ajattelin että tuota hakemistotietoa ei voisi tallentaa mihinkään, mutta hyvinhän sen voi tallentaa normaaliin tekstitiedostoon www-rootin allekin, kun kukaan ei selaimella voisi sitä itse salasanatiedostoa kuitenkaan onkia esille, vaikka sen hakemistopolun tietäisikin.
Tuo on kyllä turvallisempi tapa. :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.