Home Events! Entrance Everyone Wiki Search Login Register

Welcome, Guest. Please login or register. - Thinking of joining the forum??
November 21, 2024 - @557.20 (what is this?)
Forum activity rating: Three Stars Posts: 38/1k.beats Unread Topics | Unread Replies | My Stuff | Random Topic | Recent Posts    Start New Topic
News: :happy: Open the all windows! Your mind needs storms and air! :happy:

+  MelonLand Forum
|-+  World Wild Web
| |-+  ✁ ∙ Web Crafting
| | |-+  ☔︎ ∙ I need Help!
| | | |-+  php heck: making a search engine


« previous next »
Pages: [1] Print
Author Topic: php heck: making a search engine  (Read 1973 times)
cinni
Full Member ⚓︎
***


believe in your dreams <3

⛺︎ My Room
SpaceHey: Friend Me!
StatusCafe: cinni

View Profile WWW

First 1000 Members!OG! Joined 2021!
« on: January 26, 2022 @454.98 »

im still a big n00b to php so i'm at the mercy of other's kindness to help me :ozwomp:

i'm working on a curated archive of early 00's pixel websites (cough cough https://archive.cinni.net/) and wanted to implement a search engine for images on the site. at first i was using this tutorial which works fine BUT it doesn't easily search multiple directories. the issue is i plan to have many, many folders and having a big chunk of code per folder seems very bloated. i tried to make the $directory variable an array (like one of the comments suggest) but i haven't had any luck getting that to work since i dont know enough php :<

THEN a kind soul on the yesterweb discord provided me with the following code (that i sliiiiightly altered) which is able to search multiple directories but multiple word search terms like "hello kitty" would pull up every image with the term "hello" & "kitty" instead of filtering ONLY "hello kitty" in the file name. if you try it out yourself you'll notice it'll pull up each hello kitty gif twice.

Code
<form action="" method="POST">
 <label for="search-terms">enter search terms</label>
 <input type="text" name="search-terms" id="search-terms" value=''>
 <input type="submit" name="submit" value="Search"/>
</form>

<?php
// Comment out PHP error reporting
// ini_set('display_errors', 1);
// ini_set('display_startup_errors', 1);
// error_reporting(E_ALL);

if ($_SERVER['REQUEST_METHOD'] === 'POST':wink: {
 $original_search = $_POST['search-terms'];

 $altered_search = strtolower($original_search);
 $altered_search = trim($altered_search);

 $search_terms = explode(" ", $altered_search);
 $search_terms_amount = count($search_terms);

 $images = [];

 $directories = ["img/", "test/"];
 $filetypes = ["jpg", "jpeg", "bmp", "png", "gif"];


 if (empty($original_search) === false) {
  /* Loop through our array of directories to search */
  foreach ($directories as $dir) :
   /* If the directory exists, look through it */
   if ( is_dir($dir) ) {
    if ( $open = opendir($dir) ) {
     /* Look at each file */
     $file = [];
     while (($file['original_name'] = readdir($open)) !== false) {
      $file['lowercase_name'] = strtolower($file['original_name']);
      $position= strpos($file['lowercase_name'], ".":wink:;
      $file['extension'] = substr($file['lowercase_name'], $position + 1); // get the file extension
      $file['extension'] = strtolower($file['extension']);

      /* Check if the file name matches any of our search terms */
      for ($i = 0; $i < $search_terms_amount; $i++) :
       if (strpos($file['original_name'], $search_terms[$i]) !== false) {
        /* Check if the filetype matches any of our desired extensions */
        foreach ($filetypes as $extension) :
         if ($file['extension'] == $extension) {
          array_push($images, $file); // add the file name to our array of found files
          ?>
          <div class="search-result">
           <div class="img-result"><img src="<?php echo $dir . $file['original_name']; ?>"></div>
           <div class="title-result"><p><?php echo $file['original_name']; ?></p></div>
          </div><br>
         <?php } // file extension matching
        endforeach; // file extension loop
       } // file name matches search terms
      endfor; // loop through all search terms
     } // while loop through every file in directory
    } // opendir($dir)
    closedir($open);
   } // is_dir($dir)
  endforeach; // directory loop
 } // empty($original_search)
} // if a search has been submitted
?>
</div>
<br><br>
<div style="display:block;">
<?php
if (count($images) == 0) { 
 /*echo "No results found for this search."; */
} else { 
  //for each search term, echo that search term
foreach ($search_terms as $key => $term) {
   
echo count($images) . " results found for ''$term'' ";
}
}
?>

if... someone could point me in the right direction of how to solve this @_@ i would like the search engine to pull images from multiple directories AND be able to filter out maybe like, up to 3 search terms. this isn't *super* necessary and if i have a janky search engine then so be it, buuuut i am thanking you in advance for any insight :ozwomp:
Logged

TAS_1K
Casual Poster
*


⛺︎ My Room

View Profile

First 1000 Members!Joined 2022!
« Reply #1 on: January 26, 2022 @723.34 »

Code
<form action="" method="POST">
 <label for="search-terms">enter search terms</label>
 <input type="text" name="search-terms" id="search-terms" value=''>
 <input type="submit" name="submit" value="Search"/>
</form>

<?php
// Comment out PHP error reporting
// ini_set('display_errors', 1);
// ini_set('display_startup_errors', 1);
// error_reporting(E_ALL);

$images = [];
$search_terms = [];
$termsWithoutResult = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST':wink: {
 if ($_POST['search_terms']) {
  $original_search = $_POST['search-terms'];

  $altered_search = strtolower($original_search);
  $altered_search = trim($altered_search);
 
  $search_terms = explode(" ", $altered_search);
  $search_terms_amount = count($search_terms);
 }

 function doSearch($terms) {
  $directories = ["img/", "test/"];
  $filetypes = ["jpg", "jpeg", "bmp", "png", "gif"];

  if (count($terms) === 0) {
   return [];
  }

  $output = [];

  foreach ($directories as $dir) {
   $iterator = new DirectoryIterator($dir);

   foreach ($iterator as $file) {
    if ($file->isDot()) {
     continue;
    }

    $name = strtolower($file->getFilename());
    $extension = strtolower($file->getExtension());

    $term = getTermMatchingFilename($name, $terms);

    if ($term !== false && in_array($extension, $filetypes, true)) {
     $output[$term] = [
       'original_name' => $name,
       'extension' => $extension
     ];
    }
   }
  }

  return $output;
 }

 function getTermMatchingFilename(string $filename, array $terms) {
  foreach ($terms as $term) {
   if ($filename === $term || strpos($term, $filename) !== false) {
    return $term;
   }
  }

  return false;
 }

 $images = doSearch($search_terms);

 $termsWithoutResult = array_filter($search_terms, function ($term) use ($images) {
  return array_key_exists($term, $images);
 });
}
?>

<?php if (count($termsWithoutResult)): ?>
 <?php printf('No results for the following term(s): %s', implode(', ', $termsWithoutResult)); ?>
<?php endif; ?>

<?php foreach ($images as $term => $files): ?>
 <?php printf('%d results for %s', count($files), $term); ?>

 <?php foreach ($files as $file): ?>
  <div class="search-result">
   <div class="img-result">
    <img src="<?php echo $dir . $file['original_name']; ?>">
   </div>
   <div class="title-result">
    <p><?php echo $file['original_name']; ?></p>
   </div>
   <br>
  </div>
 <?php endforeach; ?>
<?php endforeach; ?>

I did a couple things here - first off, since you're always referencing the $images and $search_terms variables in your output, I added some defaults for those for cases where the page is first requested, which will be a GET request usually.

When it is a POST request, we'll first check for the existence of the search_terms field just to be sure it exists. If so we'll go ahead with unpacking that string into an array.

Then the bulk of the logic's been moved into the doSearch() function. It uses something called a guard clause to return early if for some reason we got something like an empty string and there are no terms in the array. In that case it just gives you an empty array - if there are no terms to search, there's no images to match.

Then it goes on to loop over all the directories you've specified. I removed the is_dir() check because presumably since you control the array of directories, these should always exist. If they might not always exist though, then that check can go back up to the beginning of the foreach loop.

Next we create a DirectoryIterator and loop over it. If we're dealing with a dot file, we skip to the next one - in case you're unfamiliar, these files are something in UNIX filesystems, basically it is a reference to the current directory (.) and the parent directory (..).

Otherwise we'll get the name and extension similar to how you did before, and check if the name and extension belong to the terms and extensions arrays respectively. If so we add the current file to our output array.

Finally once we've iterated over everything, it returns the output array. So whenever a POST request is made we'll call this function and get an array of some sort.

Haven't tested this code yet so let me know if you run into any errors and I'm happy to help or fix anything I might have foobared in the process. It's still pretty early so I might've missed something.

edit: Made some more changes, mainly around filename matching and how the "number of results" or "there are no results for blank" bits are output.
« Last Edit: January 26, 2022 @817.00 by TAS_1K » Logged
ellievoyyd
Casual Poster ⚓︎
*


Webmistress of Cybergrunge.net - Futa - she/her

⛺︎ My Room

View Profile WWW

First 1000 Members!Joined 2022!
« Reply #2 on: February 22, 2022 @256.30 »

nice!



* cinni_nice.png (9.35 kB, 395x58 - viewed 279 times.)
Logged

== Official WebMistress of Cybergrunge.net ==
Pages: [1] Print 
« previous next »
 

Vaguely similar topics! (3)

MelonEngine - Mini Three.js Game Engine

Started by MelooonBoard ✁ ∙ Web Crafting

Replies: 1
Views: 2319
Last post February 22, 2022 @261.66
by ellievoyyd
Virtual worlds: where the heck do I start?

Started by MemoryBoard ☔︎ ∙ I need Help!

Replies: 5
Views: 2553
Last post June 08, 2023 @27.16
by Melooon
Daniel's Network Search (Discontinued)

Started by MelooonBoard ⚛︎ ∙ MelonLand Projects

Replies: 3
Views: 2482
Last post March 19, 2022 @479.06
by Karius

Melonking.Net © Always and ever was! SMF 2.0.19 | SMF © 2021, Simple Machines | Terms and Policies Forum Guide | Rules | RSS | WAP | Mobile


MelonLand Badges and Other Melon Sites!

MelonLand Project! Visit the MelonLand Forum! Support the Forum
Visit Melonking.Net! Visit the Gif Gallery! Pixel Sea TamaNOTchi