webForumDet fria alternativet

Sökmotor!!?

PHPur PHP

13 svar · 633 visningar · startad av Guldstrand

Medlem sedan juli 20041 271 inlägg
Frågan#1

Jag undrar ifall det är möjligt att skapa en sökmotor som söker efter filer i en speciell mapp på en server!? (Lite svårt att förklara.)

Mappen innehåller över 130.000 filer, och jag skulle vilja skapa en sökmotor på en hemsida som söker efter en speciell fil genom att skriva in hela eller delar av filnamnet etc.

Är tacksam ifall någon kan tipsa om ett färdigt script som fungerar enligt ovan. :r

Medlem sedan jan. 20021 122 inlägg
#2

En kombination av scandir() och in_array borde kunna åstadkomma det. Prestanda vet jag dock inget om med en sådan stor array.

Medlem sedan juli 20041 271 inlägg
#3

pettsson skrev:

En kombination av scandir() och in_array borde kunna åstadkomma det. Prestanda vet jag dock inget om med en sådan stor array.

Eh..? Hur menar du då? :r

Hade uppskattat lite exempelkod.

Medlem sedan juli 20041 271 inlägg
#4

Behöver fortfarande hjälp med detta script. :r

Medlem sedan sep. 20011 086 inlägg
#5

Nåt sånt här:

$word = "ordDuVillSökaPå";
$dir = scandir("Mappen/du/vill/leta/i");
for($i = 0; $i < count($dir); ++$i)
    if(strstr($dir[$i], $word))  //Kör stristr() om du vill ignorera om det är en versal/gemen
        echo $dir[$i];

Om du inte skulle ha PHP5 så kan du använda

function scandir($path, $sort_order = 0)
{
  $ret = array();
  $dir = dir($path);
  while($ret[] = $dir->read()) ;
  $dir->close();
  $sort_order ? rsort($ret) : sort($ret);
  return $ret;
}
Medlem sedan juli 20041 271 inlägg
#6

pimme skrev:

Nåt sånt här:

$word = "ordDuVillSökaPå";
$dir = scandir("Mappen/du/vill/leta/i");
for($i = 0; $i < count($dir); ++$i)
    if(strstr($dir[$i], $word))  //Kör stristr() om du vill ignorera om det är en versal/gemen
        echo $dir[$i];

Om du inte skulle ha PHP5 så kan du använda

function scandir($path, $sort_order = 0)
{
  $ret = array();
  $dir = dir($path);
  while($ret[] = $dir->read()) ;
  $dir->close();
  $sort_order ? rsort($ret) : sort($ret);
  return $ret;
}

Tack för hjälpen, men jag förstår fortfarande inte hur jag ska lösa detta. :r

Hade uppskattat ifall Du kunde sätta ihop koden till ett komplett script, som jag sedan kan modifera själv m.m.

Medlem sedan maj 2004451 inlägg
#7

Roligt att iterera genom 130 000 filer. Är inte filerna sorterade på något sätt i filsystemet. En binär sökning vore kanske möjlig.

Medlem sedan sep. 20011 086 inlägg
#8

Nej, filerna är inte sorterade i filsystemet, inte efter filnamn iaf.

Medlem sedan sep. 20011 086 inlägg
#9

I det här fallet kan man ta bort raden

$sort_order ? rsort($ret) : sort($ret);

Men jag la till den eftersom jag ville efterlikna hur scandir() i PHP5 fungerar.

Medlem sedan maj 2004451 inlägg
#10

Tänkte att när filerna var sorterade skulle det ju gå att använda en binär sökning. Men det gäller ju bara om man vill söka på början av filnamnen.

Guldstrand:
Här kommer ett exempel med en vanlig html-form:

<?php

function scandir4($path, $sort_order = 0)
{
  $ret = array();
  $dir = dir($path);
  while($ret[] = $dir->read());

  $dir->close();
  $sort_order ? rsort($ret) : sort($ret);
  return $ret;

}

function search($term,$directory,$case_sensitive=true)
{
	$hits = array();
	if ($case_sensitive=true): $instr ="strstr"; else: $instr="stristr"; endif;
	
	$dir = scandir4($directory);
	
	for($i = 0; $i < count($dir); ++$i)
	{
	    if($instr($dir[$i], $term))
	    $hits[] = $dir[$i];
	}
	return $hits;
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="sv" xml:lang="sv">
<head>
<title>Katalogsökning</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>

<form action="<?php echo $PHP_SELF; ?>" method="post">
	<label for="term">Sökord</label>
	<input id="term" name="term" type="text" />
	<label for="dir">Katalog</label>
	<input id="dir" name="directory" type="text" />
	<label for="case">Skiftlägeskänslig</label>
	<input id="case" name="case_sensitive" type="checkbox" value="on" />
	<button type="submit" name="submit" value="set">Sök</button>
</form>
<?php
echo $_POST['directory'];
if (isset($_POST['submit']) && isset($_POST['term']) && isset($_POST['directory']))
{
	if($_POST['case_sensitive'] != "on"): $cs = false; else: $cs=true; endif;

	$hits = search($_POST['term'],$_POST['directory'], false);

	if (!empty($hits))
	{
		echo "<ul>";
		foreach($hits as $i)
		{
			echo "<li>".$i."</li>";	
		}
		echo "</ul>";
	}
	else
	{
	echo "<p>Inga träffar</p>";
	}
}
elseif (isset($_POST['submit']))
{
	echo "<p>Både katalog och sökord behövs.</p>";
}

?>

</body>
</html>

Katalognamnet man skriver in blir relativt skriptets plats.

Medlem sedan sep. 20011 086 inlägg
#11

Tinwëlint skrev:

Tänkte att när filerna var sorterade skulle det ju gå att använda en binär sökning. Men det gäller ju bara om man vill söka på början av filnamnen.

Jo, men om man vill söka på andra delar av filnamnet så funkar det ju inte.
Dock, den största prestandaförlusten man gör är att det tar mer kraft att sortera och sen binärsöka, än att göra en loop som går igenom arrayen element för element.
Och, eftersom du i din search() inte använder dig av att arrayen är sorterad, så är det mycket onödigt att köra [r]sort(). :)

Medlem sedan juli 20041 271 inlägg
#12

Tinwëlint skrev:

Tänkte att när filerna var sorterade skulle det ju gå att använda en binär sökning. Men det gäller ju bara om man vill söka på början av filnamnen.

Guldstrand:
Här kommer ett exempel med en vanlig html-form:

<?php

function scandir4($path, $sort_order = 0)
{
  $ret = array();
  $dir = dir($path);
  while($ret[] = $dir->read());

  $dir->close();
  $sort_order ? rsort($ret) : sort($ret);
  return $ret;

}

function search($term,$directory,$case_sensitive=true)
{
	$hits = array();
	if ($case_sensitive=true): $instr ="strstr"; else: $instr="stristr"; endif;
	
	$dir = scandir4($directory);
	
	for($i = 0; $i < count($dir); ++$i)
	{
	    if($instr($dir[$i], $term))
	    $hits[] = $dir[$i];
	}
	return $hits;
}


?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="sv" xml:lang="sv">
<head>
<title>Katalogsökning</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>

<form action="<?php echo $PHP_SELF; ?>" method="post">
	<label for="term">Sökord</label>
	<input id="term" name="term" type="text" />
	<label for="dir">Katalog</label>
	<input id="dir" name="directory" type="text" />
	<label for="case">Skiftlägeskänslig</label>
	<input id="case" name="case_sensitive" type="checkbox" value="on" />
	<button type="submit" name="submit" value="set">Sök</button>
</form>
<?php
echo $_POST['directory'];
if (isset($_POST['submit']) && isset($_POST['term']) && isset($_POST['directory']))
{
	if($_POST['case_sensitive'] != "on"): $cs = false; else: $cs=true; endif;

	$hits = search($_POST['term'],$_POST['directory'], false);

	if (!empty($hits))
	{
		echo "<ul>";
		foreach($hits as $i)
		{
			echo "<li>".$i."</li>";	
		}
		echo "</ul>";
	}
	else
	{
	echo "<p>Inga träffar</p>";
	}
}
elseif (isset($_POST['submit']))
{
	echo "<p>Både katalog och sökord behövs.</p>";
}

?>

</body>
</html>

Katalognamnet man skriver in blir relativt skriptets plats.

Tack så hemskt mycket för koden, men den verkar inte fungera. :r

1. Scriptet ska hämta information + fil från en annan dator
(Vill att scriptet (via internet) ska söka igenom en speciell mapp på min kompis dator.)
2. Man ska kunna ladda ner filen

Svårt att förklara.

Medlem sedan maj 2004451 inlägg
#13

För att koppla upp till en annan server krävs en massa andra funktioner som inte jag har någon vidare koll på (kanske fsockopen() är en bit på väg) Någon annan kanske vet hur man gör.

Att kunna ladda ner filen är inget problem egentligen. Bara att länka till den med hjälp av sökvägen till katalogen och filnamnet (när man väl har fått det att fungera).
Ungefär att ändra den här biten:

    if (!empty($hits))
    {
        echo "<ul>";
        foreach($hits as $i)
        {
            echo "<li>".$i."</li>";    
        }
        echo "</ul>";
    }

såhär:

    if (!empty($hits))
    {
        echo "<ul>";
        foreach($hits as $i)
        {
            echo "<li><a href=\".$_POST['directory'].$i."\">".$i."</li>";    
        }
        echo "</ul>";
    }

Pimme, det har du rätt i. Följde bara ditt första exempel
:)

P.S.

scandir4() bör nog ändras som Pimme säger till:

function scandir4($path)
{
  $ret = array();
  $dir = dir($path);
  while($ret[] = $dir->read());
  $dir->close();
  return $ret;
}

r1: länk till fsockopen()
r2: P.S.

Medlem sedan juli 20041 271 inlägg
#14

Nu förstår jag verkligen ingenting... :r

Men jag uppskattar all hjälp jag kan få.

130 ms totalt · 3 externa anrop · v20260731065814-full.4bcf49fe
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
128 ms — hämta tråd, inlägg och bilagor (db)