Метод toUri()
у Laravel перетворює обробку рядкових URL у гнучку маніпуляцію з URI, що дозволяє динамічно додавати й змінювати параметри за допомогою ланцюжкових викликів методів
Традиційна обробка URL передбачає складну маніпуляцію рядками та логіку парсингу:
$text = 'Завітайте {https://api.service.com/endpoint} для доступу до даних.';
preg_match('/\{(.*?)\}/', $text, $matches);
$baseUrl = $matches[1];
$finalUrl = $baseUrl . '?' . http_build_query($params);
Новий підхід спрощує це завдання, перетворюючи складні операції на легко читабельні та зрозумілі завдяки допоміжним рядковим методам Laravel
$uri = str($text)->between('{', '}')->toUri();
$finalUrl = $uri->withQuery(['key' => 'value'])->value();
Ось всебічна система сповіщень, що демонструє різні сценарії маніпуляції з URI:
class NotificationService
{
public function processEmailTemplate(string $template, User $user): string
{
$actionUrl = str($template)
->between('[ACTION_URL]', '[/ACTION_URL]')
->toUri();
if ($user->hasRole('premium')) {
$actionUrl = $actionUrl
->withQuery(['tier' => 'premium'])
->withQuery(['features' => 'advanced'])
->withFragment('dashboard');
} else {
$actionUrl = $actionUrl
->withQuery(['tier' => 'basic'])
->withQuery(['upgrade' => 'available']);
}
$trackingUrl = $actionUrl
->withQuery(['utm_source' => 'email'])
->withQuery(['utm_campaign' => 'user_engagement'])
->withQuery(['user_id' => $user->id]);
return str($template)->replace(
'[ACTION_URL]' . str($template)->between('[ACTION_URL]', '[/ACTION_URL]') . '[/ACTION_URL]',
$trackingUrl->value()
);
}
public function generateApiEndpoints(array $baseUrls, array $parameters): array
{
$endpoints = [];
foreach ($baseUrls as $service => $url) {
$uri = str($url)->toUri();
$uri = $uri->withQuery(['api_version' => $parameters['version'] ?? 'v1'])
->withQuery(['format' => $parameters['format'] ?? 'json']);
if (isset($parameters['auth_token'])) {
$uri = $uri->withQuery(['token' => $parameters['auth_token']]);
}
if (isset($parameters['timeout'])) {
$uri = $uri->withQuery(['timeout' => $parameters['timeout']]);
}
$endpoints[$service] = $uri->value();
}
return $endpoints;
}
public function buildDownloadLinks(Collection $files, string $baseTemplate): Collection
{
return $files->map(function ($file) use ($baseTemplate) {
$downloadUri = str($baseTemplate)
->replace('{FILE_ID}', $file->id)
->toUri();
$downloadUri = $downloadUri
->withQuery(['expires' => now()->addHours(24)->timestamp])
->withQuery(['signature' => $this->generateSignature($file)])
->withQuery(['download' => 'true']);
if ($file->requires_authentication) {
$downloadUri = $downloadUri->withQuery(['auth' => 'required']);
}
return [
'file_id' => $file->id,
'name' => $file->name,
'download_url' => $downloadUri->value(),
'expires_at' => now()->addHours(24)->toISOString()
];
});
}
public function createWebhookUrls(string $configTemplate, array $webhookData): array
{
$webhooks = [];
foreach ($webhookData as $event => $endpoint) {
$webhookUri = str($configTemplate)
->replace('{ENDPOINT}', $endpoint)
->toUri();
$webhookUri = $webhookUri
->withQuery(['event' => $event])
->withQuery(['secret' => $this->generateWebhookSecret()])
->withQuery(['version' => '2024-07']);
if ($event === 'payment_completed') {
$webhookUri = $webhookUri
->withQuery(['priority' => 'high'])
->withQuery(['retry_count' => '3']);
}
$webhooks[$event] = [
'url' => $webhookUri->value(),
'secret' => $this->generateWebhookSecret(),
'events' => [$event]
];
}
return $webhooks;
}
private function generateSignature($file): string
{
return hash_hmac('sha256', $file->id . $file->name, config('app.key'));
}
private function generateWebhookSecret(): string
{
return 'whsec_' . bin2hex(random_bytes(24));
}
}
class RedirectController extends Controller
{
public function buildRedirectUrl(Request $request): string
{
$baseRedirect = 'https://app.example.com/dashboard';
$redirectUri = str($baseRedirect)->toUri();
if ($request->has('campaign')) {
$redirectUri = $redirectUri->withQuery(['utm_campaign' => $request->input('campaign')]);
}
if ($request->has('source')) {
$redirectUri = $redirectUri->withQuery(['utm_source' => $request->input('source')]);
}
if (auth()->check()) {
$redirectUri = $redirectUri
->withQuery(['user' => auth()->id()])
->withFragment('welcome');
} else {
$redirectUri = $redirectUri->withFragment('login');
}
return $redirectUri->value();
}
}
Метод toUri()
спрощує маніпуляцію з URL, зберігаючи при цьому конвенції гнучкого інтерфейсу Laravel, що робить складне створення URI читабельним та легким у підтримці