PHP code example of uzbek / laravel-sms

1. Go to this page and download the library: Download uzbek/laravel-sms library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

uzbek / laravel-sms example snippets


use Uzbek\Sms\Facades\Sms;

$message = Sms::to('+998901234567')->text('Salom!')->send();

$message->successful;        // bool — the pipeline never throws on transport errors
$message->providerMessageId; // for status checks
$message->errorMessage;      // set when failed

// Fluent — the main API
Sms::to('+998901234567')
    ->text('Salom!')
    ->from('4546')            // sender/nickname override
    ->otp()                   // OTP flag (TextUp tariff)
    ->useFallback('playmobile')
    ->send();

// Every entry point resolves the same drivers:
sms()->send($phone, $text);                    // helper, default provider
sms('playmobile')->to($phone)->text($t)->send();
app(\Uzbek\Sms\Contracts\Driver::class);       // DI, default provider
EskizSms::to($phone)->text($t)->send();        // per-provider facades

use Uzbek\Sms\Data\OutboundMessage;

Sms::many(OutboundMessage::sameText(['+99890...', '+99891...'], 'Bir matn'))->send();

Sms::many([
    new OutboundMessage('+99890...', 'Birinchi'),
    new OutboundMessage('+99891...', 'Ikkinchi'),
])->send();   // Collection<SentMessage>, input order preserved

$message->segments();       // SegmentInfo: encoding, length, segments, perSegment
$message->cost();           // segments × price_per_segment config; null without a price
$message->updateStatus(DeliveryStatus::Delivered);  // dispatches DeliveryStatusUpdated → syncs sms_logs
$message->refreshStatus();  // polls the provider (ChecksDeliveryStatus), then updateStatus()

Sms::to($phone)->text($t)->queue();                        // default queue
Sms::to($phone)->text($t)->queue('sms');                   // named queue
Sms::to($phone)->text($t)->later(now()->addMinutes(10));   // delayed
Sms::many($messages)->later(now()->setTime(9, 0), 'sms');  // campaign at 09:00

Sms::to($phone)->text("Kod: {$code}")->dedupe("otp:{$userId}", 300)->send();  // or ->queue()

use Uzbek\Sms\Enums\OtpStatus;

Sms::otp()->send('+998901234567');                          // default provider + template
Sms::otp()->send($phone, provider: 'playmobile');
Sms::otp()->send($phone, template: 'Sizning :app kodingiz: :code', params: ['app' => 'MyShop']);
Sms::otp()->send($phone, template: 'sms.otp', locale: 'ru'); // translation key = localized

match (Sms::otp()->verify($phone, $input)) {
    OtpStatus::Valid => '...',            // consumed, replay impossible
    OtpStatus::Invalid => '...',          // wrong code, attempts left
    OtpStatus::TooManyAttempts => '...',  // locked out, code discarded
    OtpStatus::Expired => '...',          // no active code
};

class OrderShipped extends Notification
{
    public function via(object $n): array { return ['sms']; }

    public function toSms(object $n): string|SmsMessage
    {
        return 'Buyurtma jo\'natildi!';   // default provider
        // or:
        return \Uzbek\Sms\Notifications\SmsMessage::create('Kod: 1234')
            ->provider('playmobile')->from('3700')->otp()->useFallback('eskiz');
    }
}

// config/sms.php
'templates' => [
    'enforce' => false,
    'list' => ['welcome' => 'Xush kelibsiz, :name!'],
],

Sms::to($phone)->template('welcome', ['name' => 'Ali'])->send();

Sms::to($phone)->text($t)->useFallback('playmobile')->send();          // on failure, retry via playmobile
Sms::to($phone)->text($t)->useFallback('playmobile', fn ($m) => ...)->send(); // custom predicate
Sms::to($phone)->text($t)->withoutFallback()->send();

'providers' => ['eskiz' => [
    // ...
    'retry' => ['times' => 3, 'sleep' => 200],                  // transient 5xx/timeout retries; 4xx never retried
    'circuit_breaker' => ['threshold' => 5, 'cooldown' => 60],  // N consecutive failures → fast-fail, fallback takes over
    'bulk' => ['chunk' => 500, 'per_second' => 100],            // split + pace sendMany()
]],

'providers' => ['eskiz' => [
    'prefixes' => [
        'allowed' => [],          // non-empty = only these prefixes
        'blocked' => ['99833'],   // always rejected; wins over allowed
    ],
]],

final class DatabasePrefixRules implements \Uzbek\Sms\Contracts\PrefixRules
{
    public function allowlist(string $provider): array { return $this->load($provider)['allowed']; }
    public function blocklist(string $provider): array { return $this->load($provider)['blocked']; }

    private function load(string $provider): array
    {
        return cache()->remember("sms-prefixes:{$provider}", 60, fn () => [/* query */]);
    }
}

// global or per provider (per-provider wins):
'prefix_rules' => \App\Sms\DatabasePrefixRules::class,

final class EskizWebhookHandler implements \Uzbek\Sms\Contracts\WebhookHandler
{
    /** @param list<DeliveryReport> $reports */
    public function handle(Request $request, Driver $driver, array $reports): void { /* ... */ }
}

'providers' => ['eskiz' => ['webhook_handler' => \App\Sms\EskizWebhookHandler::class]],

sms('eskiz')->balance()->amount;   // Eskiz implements ChecksBalance; PlayMobile is mixed pre/postpaid — no endpoint
// ESKIZ_LOW_BALANCE_THRESHOLD set → balance() below it dispatches LowBalanceDetected

Sms::health('eskiz');   // HealthStatus: healthy true/false/null-unknown + message; never throws
Sms::health();          // all providers; per-provider 'health_check' => FQCN overrides the built-in probe

Sms::stats(from: now()->subMonth(), provider: 'eskiz');
// StatsReport: total, byStatus, deliveryRate, totalCost, totalSegments
// needs database logging; missing table → available=false + message, no exception

sms('eskiz', ['email' => $other, 'password' => $pass])->send(...);   // runtime credentials
Sms::to($phone)->text($t)->as(['email' => $e, 'password' => $p])->send();

'drivers' => ['acme' => \App\Sms\AcmeDriver::class],    // alias (or override a built-in)
'providers' => ['acme' => ['driver' => 'acme', /* ... */]],
// or skip the alias: 'driver' => \App\Sms\AcmeDriver::class

$driver = sms('eskiz');
$driver instanceof ChecksDeliveryStatus;  // checkStatus()
$driver instanceof ChecksBalance;         // balance()
$driver instanceof HandlesWebhooks;       // webhook intake

'config_overrides' => \Uzbek\Sms\Config\DatabaseProviderConfigOverrides::class,
'config_overrides_ttl' => 60,   // cache seconds; flush('eskiz') applies edits immediately

SmsProviderOverride::create(['provider' => 'eskiz', 'config' => ['from' => '5555']]);

Sms::fake();   // every provider becomes a recorder: no HTTP, no events, no log rows

Sms::assertSent(fn ($m) => $m->phone === '+998901234567' && str_contains($m->text, 'kod'));
Sms::assertSentCount(1);
Sms::assertSentTo('998901234567');   // digit-based
Sms::assertNothingSent();
Sms::sent();                          // Collection<SentMessage>

$message = Sms::to($phone)->text($t)->debug()->send();
$message->debug;   // request/response/fallback/exception trace, credentials redacted
bash
composer vendor:publish --tag=sms-config
php artisan vendor:publish --tag=sms-migrations   # only for database logging
php artisan migrate
bash
php artisan vendor:publish --tag=sms-overrides-migration && php artisan migrate