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

Sms Counter Php Laravel Package

instasent/sms-counter-php

A PHP library for accurately counting SMS messages and calculating message parts, with support for GSM 7-bit and Unicode characters, concatenation, and encoding detection. Useful for estimating SMS costs and validating message length in PHP applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What the package is: A single-purpose, framework-agnostic PHP utility that classifies a message body as GSM 03.38 (7-bit) or UCS-2, counts characters/remaining capacity, and computes single vs. multipart segment counts against the standard thresholds (160/153 GSM-7, 70/67 UCS-2). It is not a Laravel package — no service provider, facade, config, or publishable assets. It is a library we call from our own code.

Architecture fit: Good fit as an internal domain utility, not as an infrastructure dependency. It slots naturally into the pre-send boundary of any SMS path (notification, job, form validation, cost preview) and is stateless, so it is safe in queued workers and long-running Octane processes. Because it has no framework coupling and (presumably) no runtime dependencies, it does not distort our architecture — it becomes a leaf node behind an interface we own.

Integration feasibility: High, and low-effort. composer require plus a thin adapter class is measured in hours, not days. The work is not "integrate the library," it is "decide where segment counting is authoritative and enforce it consistently."

Technical risk: Low code risk, medium supply-chain risk.

  • Code risk is genuinely low: the problem domain is bounded, the rules are public (3GPP TS 23.038 / 23.040), and the surface area is small enough to audit in an afternoon and fork in a day if needed. MIT license permits that.
  • Supply-chain risk is the real issue: last release 2019-06-06, 49 stars, unknown single-maintainer activity. No evidence of a PHP 8.x support declaration, CI matrix, or security response process. Deprecation warnings or subtle behavioural drift on modern PHP (8.2/8.3/8.4) are plausible.
  • Correctness risk sits in the edge cases, not the happy path: GSM-7 extension characters (e.g. { } [ ] € ^ \ ~ |) consume two septets and change segment math; emoji and ZWJ sequences are multiple UTF-16 code units under UCS-2; national language shift tables and non-GSM characters can flip an entire message to UCS-2 and roughly halve capacity. The cost of a wrong answer is a silent 2x message bill or an unexpected split — which is exactly the failure the library exists to prevent.
  • Mitigation: pin the version, wrap it, and validate its output against a golden dataset of real messages rather than trusting it.

Key questions to resolve before adoption:

  1. Which PHP versions are actually supported/tested, and does it emit deprecations on our target runtime?
  2. Does it expose encoding, segment count, and remaining characters separately, or only a single total — and does it distinguish single-part capacity from per-segment capacity after the first?
  3. How does it treat GSM-7 extension characters, and does it count them as 2 septets in segment math (not just character count)?
  4. How are emoji, surrogate pairs, ZWJ sequences, and combining marks handled — UTF-16 code units or grapheme clusters? (Carrier behaviour is code-unit based; anything grapheme-based will undercount.)
  5. Does it account for the 6–7 byte UDH overhead in concatenated messages, and does it assume 8-bit reference numbers?
  6. Test coverage: are there tests we can inspect and extend? Is behaviour specified anywhere beyond the README?
  7. Is it stateless and free of globals/static caches? (Required for Octane and queued workers.)
  8. Who maintains it, and what is our fallback if it is abandoned — fork to a private package, or vendor the source into app/Support?

Integration Approach

Stack fit: Laravel-idiomatic but not Laravel-native. Treat it as a third-party algorithm behind a first-party contract. Do not let Instasent\... namespaces leak into controllers, jobs, or notifications; that is the difference between a one-day swap and a one-week migration if the library dies.

Recommended shape:

  • Define App\Contracts\SmsSegmentCounter with a single method returning a value object (encoding, segments, length, remaining, perSegmentLimit).
  • Implement InstasentSmsSegmentCounter as the adapter; bind it in AppServiceProvider.
  • Add a SmsSegments validation rule for FormRequests and a SmsCostEstimator service built on top of the counter for admin/preview surfaces.
  • Log sms.segments and sms.encoding as metrics on every send so drift vs. carrier billing is observable — this is the only reliable way to catch an edge-case miscount in production.

Migration path: There is nothing to migrate from unless we currently hardcode strlen()/mb_strlen() checks or rely on the gateway's own segmentation. If we do, catalogue those call sites first; they are the real scope. Adoption is additive: no schema change, no data migration, no breaking API change.

Compatibility: Pure-PHP, no extensions or services required, so it runs anywhere our app runs. The genuine compatibility question is PHP version and Laravel version — the package predates Laravel 8+, but since it has no framework integration, Laravel compatibility is effectively a non-issue; only the PHP runtime matters. Verify under our exact PHP minor with E_ALL before committing.

Sequencing:

  1. Spike (0.5 day): run the library against a golden dataset (ASCII, accents, €, emoji, mixed, empty, 160/161/306/307-char boundaries) and diff against carrier-reported segment counts from historical sends.
  2. Wrap (0.5 day): contract + adapter + container binding + unit tests pinned to the golden dataset.
  3. Enforce (1–2 days): wire the validation rule into outbound SMS entry points; add cost estimation to the admin/preview surface.
  4. Observe (ongoing): emit segment metrics and reconcile against gateway invoices monthly.
  5. Contingency: if step 1 fails or the package is abandoned, fork the source into a private packages/ or reimplement — the algorithm is fully specified and the effort is small and known.

Operational Impact

Maintenance: Very low ongoing effort, but no upstream momentum to lean on. Plan for a soft fork posture: pin the exact version, keep the adapter thin, and budget ~1 day/quarter (or on PHP upgrades) to verify behaviour. If the maintainer goes quiet — the likely scenario given the 2019 release — we own it. That is acceptable only because the codebase is small enough to own.

Support: Community-only, no SLA, no vendor to escalate to. Internal ownership must be explicit: name a code owner for the adapter and the golden dataset. The dataset is the real asset here, not the library.

Scaling: Effectively free. Counting is O(n) on message length (tens to hundreds of bytes), no I/O, no allocations of note, no caching layer needed. It will not be a bottleneck at any plausible volume; calling it per message in a bulk-send loop of 100k is still negligible. Safe under Octane provided it is stateless (verify).

Failure modes and blast radius:

  • Undercount (most dangerous): we quote one segment, the carrier bills two or the message splits mid-word. Silent, revenue-visible, and discovered on the invoice. Mitigated by metric reconciliation, not by unit tests alone.
  • Overcount: conservative — mild cost-estimate inflation, low harm.
  • Encoding misclassification: a single non-GSM character drops capacity from 160 to 70. If the library's GSM table is stale or its extension handling is wrong, this flips silently in both directions.
  • PHP upgrade breakage: deprecation notices in logs, or changed behaviour with no changelog to consult. Mitigated by pinning and a CI matrix test.
  • Abandonment: no security patches. Blast radius is bounded — a local utility with no network or data access — so this is a maintenance annoyance, not an incident.
  • Trust boundary: never let the count be the sole gate on send. Keep gateway-level rejection handling and per-message cost caps as the backstop.

Ramp-up: Hours for any Laravel developer. The concept (GSM-7 vs UCS-2, 160/153 and 70/67) is the only learning curve, and it is well documented publicly. The adapter pattern means a new engineer never needs to read the library source unless debugging an edge case.

TPM recommendation: Adopt as a wrapped, pinned utility with a golden-dataset test and segment-level metrics — provided the spike passes for PHP 8.x and emoji/extension-character handling matches carrier behaviour. Do not adopt it as a trusted dependency without that validation, and do not adopt it at all if we only need a rough estimate in one place; the rules are simple enough to implement inline. The value here is consistency across every send path, not the algorithm itself.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums