Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Hakukone-koodi

Sivun loppuun

Macro [22.10.2009 17:07:33]

#

Morjensta kaikki!

Teen sivuilleni hakukonetta, ja kiinnostaisi tietää miten saan tulostettu kohdan sivusta kuten Google. Eli, ei käyttäjälle varmaan sano mitään, jos tulostetaan vain, että "Sivulta xxx löytyi hakusana xxx". Sillä pitäisi nähdä siis, että mitä muuta sisältöä siellä on.

Tässä tämä minun härvelini:

<?php
$folder = opendir(".");
$word = "auto kana teksti";
$words = explode(" ", $word);
$loytyneet = 0;
$loytyi = "";

$dontshow = array("haku.php", "eisaanayttaa.php");

//Käydään jokainen tiedosto läpi
while($info = readdir($folder)) {
	//Jos $info on ., .. tai arrayssa, niin ohitetaa
	if($info == "." OR $info == ".." OR in_array($info, $dontshow)) continue;

	//Tiedoston sisältö on $file muuttujassa
	$file = file_get_contents($info);

	//Käydään niin monta kertaa läpi, kuin hakusanoja on
	for($i = 0; $i < sizeof($words); $i++) {
		$kierrokset = sizeof($words);

		if($tiedosto == 0) {
			$loytyi .= "<p>\nTiedostosta $info löytyi seuraavat hakusanat:<ul>\n";
			$tiedosto = 1;
		}

		if($i == $kierrokset - 1) $tiedosto = 2;

		if(strpos($file, $words[$i]) !== false) {
			//Löytyi
			$loytyi .= "<li>" . $words[$i] . "</li>\n";

			if($viime != $info) $loytyneet++;
		}

		if($tiedosto == 2)
			$loytyi .= "</ul>\n</p>\n\n";

		$viime = $info;
	}

	$tiedosto = 0;
}

echo "<p><h3>Löytyi $loytyneet hakutulosta</h3></p>\n\n$loytyi";
?>

Tuo nyt listaa hakutulokset tähän tyyliin:

Löytyi 2 hakutulosta

Tiedostosta auto.txt löytyi seuraavat hakusanat:

	auto
	teksti

Tiedostosta lol.php löytyi seuraavat hakusanat:

	kana

Tiedostosta testi.txt löytyi seuraavat hakusanat:

	auto
	kana
	teksti

Metabolix [22.10.2009 19:09:30]

#

Ota vaikka talteen strpos-funktion ilmoittama kohta ja leikkaa substr-funktiolla tämän ympäriltä sata merkkiä kumpaankin suuntaan.

Teuro [22.10.2009 19:37:27]

#

Jollakin tavalla pitäisi siis tunnistaa tekstimassasta lause. Lause alkaa isolla alkukirjaimella, sekä päättyy pisteeseen. Onko se sinusta riittävän säännöllinen, jotta esimerkiksi säännöllinen lauseke voisi olla ratkaisu? Toisaalta, kuten äskeisestä lauseesta huomattiin, niin lause voi päättyä myös kysymysmerkkiin. Ehkä parempi hakea kuitenkin haettu sana ja siitä vaikka juuri 100 merkkiä taakse- ja eteenpäin.

Metabolix [22.10.2009 19:38:34]

#

Voit etsiä pisteet (muista myös kysymysmerkki ja huutomerkki!) strpos- ja strrpos-funktioilla. Funktiolle voi antaa parametriksi kohdan, josta haku alkaa. Toistamalla hakua pari kertaa saat useamman virkkeen.

Edit. Jaha, poistit viestisi. ^^

Macro [22.10.2009 20:05:06]

#

Jep, ehdin poistamaan kun tajusin virheeni. Sellainen kysymys vielä, että jos sivulla lukee esimerkiksi [b]moi[/b], niin miten voin säännöllisillä lausekkeilla hakea tuon [b]-tagien sisällön? En ole koskaan oikein ymmärtänyt tätä logiikkaa. (Piti laittaa välilyönnit tuonne tageihin, kun menee muuten paksuksi =))

Metabolix [22.10.2009 20:07:28]

#

Säännöllisistä lausekkeista on hyvä opas.

Macro [22.10.2009 20:19:54]

#

Tiedän, että täällä on sellainen.

[otsikko]Kanala[/otsikko]
kana

Tuollainen sivu, ja tälläinen koodi:

<?php
echo preg_replace("/\[otsikko\](.*?)\[\/otsikko\]/is", "$1", $sivu);

Tulostaa Kanala kana, kun pitäisi tulla Kanala. Jos muutan $1:n $2:ksi, niin tulee "kana".

Teuro [22.10.2009 20:27:56]

#

Tuo lopettaa lukemisen juurikin tuon [/otsikko] jälkeen, joten kana ei "mahdu" tuohon lausekkeeseen. Lisää lausekkeen loppuun vaikka .+, jolloin tuon tulisi toimia ihan oikein.

Metabolix [22.10.2009 20:31:34]

#

Korvaat säännöllisen lausekkeen mukaisen kohdan tekstistä ja tulostat syntyneen tekstin. Säännöllinen lauseke on aivan oikein (lähes; \-merkit pitäisi oikeastaan kirjoittaa kahtena, koska \\ muuttuu \:ksi jo normaalissa PHP:n tekstinkäsittelyssä ja \ on osa säännöllistä lauseketta). Esimerkkisi toimii käytännössä näin:

<?php
echo str_replace("[otsikko]Kanala[/otsikko]", "Kanala", $sivu);

Lausekkeen löytämä kohta korvataan siis uudella, ja lopuksi koko teksti (myös lausekkeen ulkopuoliset osat) tulostetaan.

Sinun pitäisi siis käyttää preg_match(_all)-funktiota, jolla vain poimitaan osuma(t) tekstistä. Oppaasta valitettavasti puuttuvat nämä käytännölliset esimerkit, joissa funktion löytämä teksti otettaisiin talteen.

<?php
// Haetaan kaikki osumat; jos yksi riittää, ota _all pois.
if (preg_match_all('/lause/', $sivu, $osumat, PREG_SET_ORDER)) {
  foreach ($osumat as $osuma) {
    // $osuma[0] == koko osuma, "[otsikko]Kanala[/otsikko]"
    // $osuma[1] == ensimmäinen sulkulauseke, "Kanala"
  }
}

Macro [23.10.2009 08:05:07]

#

Jee, kiitos Metabolix! Nyt se toimii hienosti =)

Macro [23.10.2009 21:36:08]

#

No, nyt toimii vielä paremmin. =) Silti olisi vielä kysymys: Miten saan formin menemään osoitteeseen index.php?sivu=haku&hakusana­=formistatullutgettieto? Menee aina vain index.php?hakusana=xxx.

Grez [23.10.2009 21:51:28]

#

Jos sulla on <form method="get" action="index.php?mitävaandiipadaapaa">, niin silloin kaikki actionissa ?-merkin jälkeen oleva korvataan sillä, mitä formilta tulee.

Eli jos haluat siihen muita tietoja, niin lisää ne formille

<form method="get" action="index.php">
  <input type="hidden" name="sivu" value="haku" />
  <input type="text" name="hakusana" /><input type="submit" value="Hae" />
</form>

Macro [24.10.2009 00:18:30]

#

Kiitos Grez =)

Macro [24.10.2009 09:52:08]

#

Pitää vielä kysyä, että mitä teen tälle, että saan sen hakemaan tietoa myös alihakemistoista?

<?php
//Hakusanat erotettuna välilyönnillä
$hakusana = explode(" ", $_GET["hakusana"]);
//Löytyneitä sivuja
$loytynyt = 0;
//Näitä sivuja ei käsitellä
$ei = array("haku.php", "index.php");


$hakemisto = opendir(".");

while($info = readdir($hakemisto)) {
	if($info == "." OR $info == ".." OR in_array($info, $ei)) continue;

	//Haetaan $file muuttujaan $info tiedoston sisältö
	$file = file_get_contents($info);
	$sivunnimi = explode(".", $info);

	//Haetaan sivun otsikko
	if (preg_match_all('/\[otsikko\](.*?)\[\/otsikko\]/is', $file, $osumat, PREG_SET_ORDER)) {
		foreach ($osumat as $osuma) {
			$otsikko = $osuma[1];
		}
	}

	//Jos otsikko oli tyhjä, tai sen pituus oli nolla merkkiä
	if(empty($otsikko) || strlen($otsikko) <= 0) $otsikko = "Unnamed site";

	$file_lower = strtolower($file);

	for($b = 0; $b < sizeof($hakusana); $b++) {
		if(strpos($file_lower, strtolower($hakusana[$b])) !== false) {
			$sanansijainti = strpos($file_lower, strtolower($hakusana[$b]));

			$sijainti = $sanansijainti - 75;

			$kooste = substr($file, $sijainti, 150);
			$kooste = str_replace($hakusana[$b], "<b>" . $hakusana[$b] . "</b>", $kooste);
			$kooste = preg_replace('/\[otsikko\](.*?)\[\/otsikko\]/is', '', $kooste);

			$sisalto .= "<p>\n";
			$sisalto .= "<a style=\"color: #8C0707\" href=\"index.php?act=" . $sivunnimi[0] . "\">$otsikko:</a>\n<ul>\n";
			$sisalto .= "$kooste...";
			$sisalto .= "<br><font style=\"color: green; font-size: 9pt\">http://" . $_SERVER["SERVER_NAME"] . "/MPS/$info</font></ul>\n</p>\n\n";
		}
	}
	$otsikko = "";
}

if(strlen($_GET["hakusana"]) >= 1) {
	if($loytynyt == 0) echo "Ei yhtään tulosta hakusanalla " . $_GET["hakusana"] . "<br>";
	else if($loytynyt == 1) echo "$loytynyt hakutulos löytynyt:<br>";
	else echo "$loytynyt hakutulosta löytynyt:<br>";
}

echo $sisalto;
?>

Nyt tuo antaa vaan 403 virheilmoituksen, kun tulee hakemisto vastaan (Tuo file_get_contents-rivi).

Metabolix [24.10.2009 12:44:02]

#

Rekursiivisella funktiolla. Kannattaa lukea rekursio-opas, siellä on itse asiassa aivan samanlainen esimerkki.

<?php
function hae_tiedostot($polku, &$taulukko = null) {
  if ($taulukko === null) {
    $uloin = true;
    $taulukko = array();
  }
  $hakemisto = opendir($polku);
  while ($info = readdir($hakemisto)) {
    if ($info == '.' || $info == '..') continue;
    if (is_dir($info)) {
      hae_tiedostot("$polku/$info", $taulukko);
    } else {
      $taulukko[] = "$polku/$info";
    }
  }
  closedir($hakemisto);
  if ($uloin) {
    return $taulukko;
  }
}

$tiedostot = hae_tiedostot(".");
foreach ($tiedostot as $polku) {
  $nimi = basename($polku);
  $hakemisto = dirname($polku);
  echo "Tiedosto $nimi on hakemistossa $hakemisto; koko polku on $polku.\n";
  // file_get_contents($polku);
}

Macro [24.10.2009 16:31:31]

#

Hei, kiitos taas! =)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta