Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Rake Php Plus Laravel Package

donatello-za/rake-php-plus

A dependency-free PHP implementation of RAKE (Rapid Automatic Keyword Extraction) for extracting keywords and key phrases from text. Includes stopword lists, multi-language support, customizable scoring, and straightforward integration into existing projects.

Deep Wiki
Context7

Getting Started

Install with Composer:

composer require donatello-za/rake-php-plus

The package is framework-agnostic, so in Laravel you typically use it directly from a service class, job, or controller rather than through a facade.

Minimal extraction:

use DonatelloZa\RakePlus\RakePlus;

$text = 'Laravel queues make background jobs manageable. '
      . 'Queue workers process jobs and retry failed jobs automatically.';

$rake = RakePlus::create($text, 'en_US');

$keywords = $rake->keywords();   // ranked phrases
$scores   = $rake->scores();     // phrase => score

First places to look:

  • The RakePlus class for the public API and tunable options.
  • The bundled stopword files for supported language codes.
  • keywords() for a ranked list, and scores() when you need the underlying RAKE score.
  • Setter methods for minimum/maximum phrase length, word count, delimiters, regex, and stopwords.

A good first use case: extracting tags or suggested keywords from support tickets, CMS articles, product descriptions, or uploaded documents.

$tags = RakePlus::create($ticket->body, 'en_US')->keywords(10);

Start with the defaults, inspect the output on real content, then tune stopwords and phrase-length settings.

Implementation Patterns

Wrap extraction in an application service

Keep RAKE configuration in one place so results stay consistent across controllers, jobs, and commands.

namespace App\Services;

use DonatelloZa\RakePlus\RakePlus;

final class KeywordExtractor
{
    public function extract(string $text, ?string $locale = null, int $limit = 15): array
    {
        $locale = $this->normalizeLocale($locale ?? config('app.locale'));

        $rake = RakePlus::create($text, $locale);

        $rake->setMinWords(1);
        $rake->setMaxWords(4);
        $rake->setMinLength(3);

        return $rake->keywords($limit);
    }

    private function normalizeLocale(string $locale): string
    {
        return match ($locale) {
            'en' => 'en_US',
            'de' => 'de_DE',
            'fr' => 'fr_FR',
            'es' => 'es_ES',
            'it' => 'it_IT',
            'nl' => 'nl_NL',
            'pt' => 'pt_PT',
            default => $locale,
        };
    }
}

Validate the exact language keys against the bundled stopword files in the installed version.

Return ranked results with scores

Use keywords() when you only need phrases. Use scores() when you want to apply your own threshold, compare relative importance, or combine RAKE with other signals.

$rake = RakePlus::create($article->body, 'en_US');
$scores = $rake->scores();

arsort($scores);

$strong = array_filter(
    $scores,
    fn (float $score) => $score >= 2.0
);

RAKE scores are relative to the text being processed. A score of 2.0 in one document is not directly comparable to 2.0 in another. Use scores for ranking within a document, not as an absolute quality metric across documents.

Tune phrase boundaries deliberately

The defaults are reasonable, but different content types benefit from different settings.

$rake = RakePlus::create($productDescription, 'en_US');

$rake->setMinWords(1);   // allow single-word keywords
$rake->setMaxWords(3);   // keep tags concise
$rake->setMinLength(3);  // drop very short tokens
$rake->setMaxLength(40); // avoid very long phrases

For tag suggestion, 1–3 words usually works well. For topic modelling or document summarisation, allow longer phrases.

Add domain stopwords without losing defaults

Custom stopwords are especially important for product names, internal jargon, and boilerplate language.

$rake = RakePlus::create($text, 'en_US');

$stopwords = $rake->getStopwords();
$stopwords = array_merge($stopwords, [
    'lorem',
    'ipsum',
    'click',
    'here',
]);

$rake->setStopwords($stopwords);

If you replace stopwords rather than merge them, extraction quality will often degrade because common grammatical words start appearing in phrases.

Chunk long documents and aggregate results

RAKE works on sentence-level co-occurrence. Very large documents dilute phrase relationships and increase memory use. Process paragraphs or sections separately, then merge results.

$totals = [];

foreach ($chunks as $chunk) {
    $rake = RakePlus::create($chunk, $locale);

    foreach ($rake->scores() as $phrase => $score) {
        $totals[$phrase] = ($totals[$phrase] ?? 0) + $score;
    }
}

arsort($totals);
$top = array_slice($totals, 0, 20, true);

This is a pragmatic aggregation, not a mathematically exact merge of RAKE scores, but it works well for long articles and document collections.

Persist extracted keywords

Store keywords in a JSON column or a pivot table, depending on whether you need filtering and joins.

// Migration
$table->json('keywords')->nullable();
// Model
protected $casts = [
    'keywords' => 'array',
];
// Job or observer
$article->update([
    'keywords' => app(KeywordExtractor::class)
        ->extract($article->body, 'en_US', 20),
]);

Run extraction in a queued job when the text is large or when extraction happens on save.

Normalise input before extraction

RAKE expects plain text. Strip HTML, decode entities, collapse whitespace, and remove control characters.

$plain = trim(preg_replace('/\s+/', ' ', strip_tags($html)));
$keywords = RakePlus::create($plain, 'en_US')->keywords(15);

If your content contains Markdown, URLs, code blocks, or emoji-heavy text, remove or replace those constructs first. Otherwise they will influence delimiters and phrase boundaries.

Use custom delimiters and regex for unusual content

The package exposes sentence delimiters, word delimiters, and regex configuration. Adjust these when working with content that does not follow normal prose conventions.

$rake = RakePlus::create($text, 'en_US');

$rake->setSentenceDelimiters(['.', '!', '?', "\n"]);
$rake->setWordDelimiters([' ', "\t", '-', '/']);

Use this sparingly. Over-customising delimiters can merge phrases that should remain separate or split terms that should stay together.

Integrate with search and recommendations

A practical pattern is to use RAKE as one signal among several.

  • Index RAKE keywords in a search engine as a lightweight keywords field.
  • Use top keywords to prefill tag inputs in an admin UI.
  • Combine RAKE results with existing taxonomy terms, embeddings, or manual tags.
  • Use scores to order suggested tags, not to decide truth.

Gotchas and Tips

RAKE is not semantic

It is a statistical phrase extraction algorithm based on word co-occurrence and stopwords. It does not understand synonyms, entities, or intent. “Laravel queue” and “Laravel queues” may appear as separate phrases. Do not expect stemming or lemmatisation unless you preprocess the text yourself.

Stopword quality dominates output

Most poor results come from stopword mismatches, not from the algorithm itself. Review the bundled list for your language, then add domain-specific boilerplate. Common additions include site names, call-to-action phrases, product category names, and legal disclaimers.

Language codes must match bundled files

Use exact locale keys supported by the installed package. If you pass an unsupported code, verify whether the package falls back to English or fails. Map application locales such as en, pt-BR, or fr_CA to supported values in one place.

setMinWords() and setMinLength() are different

  • Word settings control the number of words in a phrase.
  • Length settings control character length.

Confusing them leads to either single common words leaking through or useful multi-word phrases being discarded.

Replacing stopwords can remove defaults

setStopwords() replaces the active list. Always merge with getStopwords() first if you want to preserve built-in behaviour. This is the most common cause of sudden quality regressions after adding a few custom terms.

Case and punctuation handling should be verified

Check how your installed version returns phrases, especially for capitalised names and hyphenated terms. If you need stable database keys, normalise consistently before storing or comparing:

$key = mb_strtolower(trim($phrase));

Do not assume output is already normalised across versions.

Empty or short text produces weak results

Very short inputs may return no keywords or only single words. Guard against empty arrays before rendering tag UIs or writing to the database.

$keywords = RakePlus::create($text, 'en_US')->keywords(10);
$keywords = array_values(array_filter($keywords));

Avoid sharing a mutable RAKE instance

Create a fresh instance per text or per request. Setters mutate instance state, so reusing a configured instance across different locales or content types can produce surprising results.

Cache extracted results, not raw text

Extraction is CPU-bound but not usually a bottleneck for small texts. For large documents or batch imports, cache the final keywords in the model or a dedicated table. Re-running extraction on every page load is unnecessary.

Test with fixture text

Add a small set of representative fixtures: short text, long article, non-English text, HTML-heavy content, and text containing only stopwords. Assert on stable properties such as “contains this phrase” or “does not contain stopwords” rather than exact score values, which are sensitive to configuration.

$keywords = app(KeywordExtractor::class)->extract($fixture, 'en_US');

$this->assertContains('queue workers', $keywords);
$this->assertNotContains('the', $keywords);

Tune against your own corpus

Do not copy settings from a blog post. Start with defaults, inspect real output, then adjust max words, min length, and domain stopwords. Keep the configuration in a config file so changes are reviewable and testable.

Use it as a component, not a complete solution

RAKE is excellent for fast, dependency-free keyword extraction. For production search, tagging, or recommendations, pair it with manual review, existing taxonomy rules, or a second ranking signal. Treat its output as candidate keywords, not final labels.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core