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

Substringy Laravel Package

tcb13/substringy

Substringy is a small PHP utility for working with substrings through a clean, fluent API. It provides helpers to extract text before, after, or between delimiters, along with common string slicing and search operations, making everyday string manipulation simpler in Laravel and standalone PHP proje...

Deep Wiki
Context7

Getting Started

The package metadata doesn't point at a repository, so the first five minutes should be spent reading the installed source rather than guessing at the API.

composer require tcb13/substringy
composer show tcb13/substringy          # version, deps, autoload namespace
ls vendor/tcb13/substringy/src         # usually one or two small classes

Three things to confirm before writing any application code:

  1. Which Stringy it extends. composer show will reveal either danielstjules/stringy (abandoned) or a maintained fork such as voku/stringy / statamic/stringy. That determines the base API you inherit and whether PHP 8.2+ will emit deprecations.
  2. The exact class name and namespace. tcb13/substringy is small enough that the whole public surface is a single file — read the method list once and you're done.
  3. Method names for missing-delimiter behaviour. Every substring helper has to decide what to return when the delimiter isn't found; the README rarely spells this out, the source always does.

A realistic first use case is pulling a field out of an unstructured line without hand-rolling preg_match offsets:

use Tcb13\Substringy\Substringy; // verify exact casing in src/ first

$line = 'GET /api/users/42?debug=1 HTTP/1.1';

$path = Substringy::create($line)
    ->between(' ', ' ')          // '/api/users/42?debug=1'
    ->before('?');               // '/api/users/42'

Substringy::create($string) is the Stringy static factory and is the preferred entry point because it handles null and sets up UTF-8 correctly. new Substringy($string) works too, but you lose the null-coalescing.

Implementation Patterns

Wrap at the boundary, chain in the middle. Instantiate once where the string enters your domain — a log line, a scraped href, a query value — then chain. Each Stringy call returns a new instance, so a chain is a single readable pipeline:

$user = Substringy::create($request->header('Referer'))
    ->afterLast('/')
    ->before('?')
    ->toLowerCase()
    ->toString();

Cast with ->toString() or (string) $s at the edge of your code so the rest of the app deals in plain strings, not Stringy objects.

Use it for delimiter-driven extraction, not for regex you already know. The package earns its place on the "I need the bit between these two markers" cases: between(), after(), before(), last-occurrence variants, and whatever extract()/cut()-style helpers the class exposes for capture groups. For anything with variable structure, a real preg_match with named groups will be clearer.

Laravel integration. Don't mix it with Illuminate\Support\Str — they're separate fluent APIs with overlapping method names and different semantics. Bridge at one point and be consistent:

// app/Support/Text.php
function text(?string $s): Substringy
{
    return Substringy::create((string) $s, 'UTF-8');
}

Then use it inside parsers, Artisan import commands, and Blade-free presentation code. Typical wins: parsing access logs in a command, normalising imported CSV columns, slicing fixed-format report output, extracting IDs out of URLs in a redirect map.

Multi-byte by default. Stringy operates on characters, not bytes, when given an encoding. That's exactly what you want for user input and file names. Pass 'UTF-8' explicitly in the factory rather than relying on mb_internal_encoding(), so behaviour doesn't change between CLI and web requests.

Build a domain subclass. Because it's a Stringy subclass, you can extend it with your own helpers (toSlug, maskEmail, extractOrderId) and keep the fluent chaining intact:

final class Sku extends Substringy
{
    public function family(): self
    {
        return $this->before('-'); // 'ACME-0042-BLK' -> 'ACME'
    }
}

Gotchas and Tips

  • Case-sensitive namespaces will bite you. SubStringy vs Substringy in a use statement works on macOS/Windows and explodes in Linux CI. Copy the class name from the file, not from memory.
  • Check what a missing delimiter returns before you branch on it. Some Stringy methods return the original string when the needle isn't there, others return ''. Truthiness checks like if ($result) are unreliable; compare explicitly or guard with ->contains().
  • null never survives the constructor. Stringy normalises null to ''. If downstream code distinguishes "absent" from "empty", you must track that flag yourself before wrapping.
  • The abandoned base is the real risk. If composer.json requires danielstjules/stringy, expect deprecation noise on PHP 8.1+ and a stalled dependency tree. Mitigate with a Composer alias/replacement to voku/stringy if the API matches, or vendor a copy. Check composer why-not php 8.3 early.
  • Debugging prints nothing useful. var_dump($s) shows the object's internals; use var_dump($s->toString()) or dump((string) $s). Half the "the method returned garbage" reports are really "I looked at the wrong layer".
  • Escape your regex delimiters. If you use the pattern-taking helpers, wrap patterns in a delimiter other than / when the subject is a path or URL, and add the u modifier for UTF-8 subjects.
  • Performance profile is fine until it isn't. One object allocation per call is irrelevant in request handling, but in a 500k-row import the allocation churn shows up. Profile before optimising; if it matters, do a single preg_match or native strpos/substr in the hot loop and keep Substringy for the readable outer layer.
  • Verify create() returns static, not self. If the inherited factory is hard-coded to self, YourSubclass::create($s) will hand you a base Substringy and your custom methods will error with "call to undefined method". Override create() in your subclass if so.
  • Extension points worth knowing: subclassing for domain helpers, and Stringy's encoding parameter. There is very little else — 17 stars means no plugin system and thin tests, so pin the version in composer.json and add your own test covering whichever methods you actually rely on.
  • If autoload fails after install, run composer dump-autoload before filing a bug; PSR-4 mismatches in small packages are usually stale autoload files, not broken code.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin