juanantoniodelgado/stopwords
A Laravel/PHP package for working with stopwords. Detect and remove common filler words from text across multiple languages, with a simple API for cleaning, filtering, and analyzing strings in your applications.
composer require juanantoniodelgado/stopwords
composer.json (autoload.psr-4) and the src/ directory before writing any code — this is a small, single-maintainer library, so the exact class name and method signatures are the contract you'll bind against. Typical shape:
use Juanantoniodelgado\StopWords\StopWords;
$stop = new StopWords('en'); // verify supported locale codes
$clean = $stop->remove('This is a basic test of the library');
// => "basic test library"
AppServiceProvider so you're not new-ing the class in controllers (see Patterns below).Bind a configured instance per locale. Wrap the vendor class so the rest of your app never imports it directly:
// app/Services/Text/StopWordFilter.php
namespace App\Services\Text;
use Juanantoniodelgado\StopWords\StopWords;
class StopWordFilter
{
public function __construct(private string $locale = 'en') {}
public function clean(string $text): string
{
return (new StopWords($this->locale))->remove($text);
}
}
// AppServiceProvider::register()
$this->app->bind(StopWordFilter::class, fn () =>
new StopWordFilter(config('services.stopwords.locale', 'en'))
);
Build a normalization pipeline. The library removes stopwords; it does not lowercase, strip punctuation, or normalize Unicode. Chain your own steps before calling it:
$text = mb_strtolower($text, 'UTF-8');
$text = preg_replace('/[^\p{L}\p{N}\s]/u', ' ', $text);
$text = preg_replace('/\s+/u', ' ', $text);
$filtered = app(StopWordFilter::class)->clean($text);
Locale selection before removal. If you accept multilingual input, detect the language (e.g. palladius/php-eloquent style detectors, or a simple fallback) and instantiate the matching stopword list. Mismatching locale silently degrades results — the filter simply finds nothing to remove.
Cache the constructed instance. The stopword list is loaded per instantiation; bind as singleton per locale or memoize in a small factory keyed by locale to avoid re-parsing the list on every request.
Queued bulk processing. For large imports or backfills, do the removal in a job and chunk the source:
Article::whereNull('indexed_at')->chunkById(500, function ($articles) {
foreach ($articles as $article) {
$article->update([
'search_body' => app(StopWordFilter::class)->clean($article->body),
'indexed_at' => now(),
]);
}
});
Search-index integration. Feed the cleaned text into Laravel Scout / TNTSearch / Meilisearch as the "toSearchableArray" payload, but keep the raw text for display. Stopword removal belongs in the index, never in the stored document.
Pair with stemming. Stopword removal and stemming are complementary — apply removal first, then a stemmer (e.g. wamania/php-stemmer) for a clean token set:
$tokens = array_filter(explode(' ', $filtered));
$stems = array_map(fn ($t) => $stemmer->stem($t), $tokens);
ServiceProvider or facade in the package — you own all wiring and config. Don't assume config/stopwords.php exists.The won't be removed but the will. Lowercase and strip punctuation yourself first.mbstring is available and use mb_* / /u regex flags. Accented-language lists (Spanish, French, German) will break with byte-oriented string ops."The It" can reduce to an empty string. Guard downstream consumers (search analyzers, keyword extractors) against blank output.IT, Will, May). Scope the filter to body text only."juanantoniodelgado/stopwords": "0.1.*" or an exact tag) so a future release can't silently change behavior. Consider vendoring the language files if the project matters long-term.array_diff against a custom blacklist) and keep the package for the built-in languages.composer show juanantoniodelgado/stopwords will tell you the installed version and license.How can I help you explore Laravel packages today?