این راهنما نحوه ساخت یک بکند بلیتینگ رویداد مبتنی بر NFT مقیاس‌پذیر در PHP با استفاده از Symfony Messenger برای مدیریت تاخیر بلاک چین به صورت ایمن و قابل اعتماد را نشان می‌دهد.این راهنما نحوه ساخت یک بکند بلیتینگ رویداد مبتنی بر NFT مقیاس‌پذیر در PHP با استفاده از Symfony Messenger برای مدیریت تاخیر بلاک چین به صورت ایمن و قابل اعتماد را نشان می‌دهد.

ساخت سیستم غیرمتمرکز بلیط‌فروشی رویداد Web3 با Symfony 7.4

تلاقی وب 3 و فریم‌ورک‌های سنتی وب جایی است که کاربرد واقعی آغاز می‌شود. در حالی که چرخه‌های هیجانی می‌آیند و می‌روند، کاربرد توکن غیر قابل تعویض (NFT) برای تأیید مالکیت — به‌ویژه در بلیط رویدادها — همچنان یک مورد استفاده قوی باقی می‌ماند.

در این مقاله، ما ستون فقرات یک سیستم بلیط رویداد غیرمتمرکز را با استفاده از Symfony 7.4 و PHP 8.3 خواهیم ساخت. ما فراتر از آموزش‌های پایه حرکت می‌کنیم و یک معماری سطح تولید را پیاده‌سازی می‌کنیم که ماهیت ناهمزمان تراکنش‌های بلاک چین را با استفاده از کامپوننت Symfony Messenger مدیریت می‌کند.

معماری

رویکرد "ارشد" تصدیق می‌کند که PHP یک فرآیند طولانی‌مدت مانند Node.js نیست. بنابراین، ما به رویدادهای بلاک چین به‌صورت real-time در یک کنترلر گوش نمی‌دهیم. در عوض، از یک رویکرد ترکیبی استفاده می‌کنیم:

  1. تعامل مستقیم (نوشتن): ما از Symfony Messenger برای انتقال تراکنش‌های "Minting" به یک worker استفاده می‌کنیم و از تایم‌اوت HTTP جلوگیری می‌کنیم.
  2. نظرسنجی RPC (خواندن): ما از دستورات زمان‌بندی‌شده برای تأیید وضعیت on-chain استفاده می‌کنیم.
  3. قرارداد هوشمند: ما یک قرارداد استاندارد ERC-721 مستقر شده بر روی یک زنجیره سازگار با EVM (اتریوم، Polygon، Base) را فرض می‌کنیم.

پیش‌نیازها و پشته

  • PHP: 8.3+
  • Symfony: 7.4 (LTS)
  • گره بلاک چین: Infura، Alchemy یا یک گره محلی Hardhat.

بسیاری از کتابخانه‌های PHP وب 3 رها شده یا تایپ ضعیفی دارند. در حالی که web3p/web3.php معروف‌ترین است، تکیه کامل بر آن می‌تواند به دلیل شکاف‌های نگهداری خطرناک باشد.

برای این راهنما، ما از web3p/web3.php (نسخه ^0.3) برای کدگذاری ABI استفاده خواهیم کرد اما از HttpClient بومی Symfony برای انتقال واقعی JSON-RPC بهره خواهیم برد. این به ما کنترل کامل بر روی تایم‌اوت‌ها، تلاش‌های مجدد و ثبت وقایع می‌دهد — که برای برنامه‌های تولید حیاتی است.

راه‌اندازی پروژه

ابتدا، بیایید وابستگی‌ها را نصب کنیم. ما به runtime Symfony، کلاینت HTTP و کتابخانه وب 3 نیاز داریم.

composer create-project symfony/skeleton:"7.4.*" decentralized-ticketing cd decentralized-ticketing composer require symfony/http-client symfony/messenger symfony/uid web3p/web3.php

اطمینان حاصل کنید که composer.json شما ثبات را منعکس می‌کند:

{ "require": { "php": ">=8.3", "symfony/http-client": "7.4.*", "symfony/messenger": "7.4.*", "symfony/uid": "7.4.*", "web3p/web3.php": "^0.3.0" } }

سرویس بلاک چین

ما به یک سرویس قوی برای صحبت با بلاک چین نیاز داریم. ما یک EthereumService ایجاد خواهیم کرد که فراخوانی‌های JSON-RPC را پوشش می‌دهد.

//src/Service/Web3/EthereumService.php namespace App\Service\Web3; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Web3\Utils; class EthereumService { private const JSON_RPC_VERSION = '2.0'; public function __construct( private HttpClientInterface $client, #[Autowire(env: 'BLOCKCHAIN_RPC_URL')] private string $rpcUrl, #[Autowire(env: 'SMART_CONTRACT_ADDRESS')] private string $contractAddress, #[Autowire(env: 'WALLET_PRIVATE_KEY')] private string $privateKey ) {} /** * Reads the owner of a specific Ticket ID (ERC-721 ownerOf). */ public function getTicketOwner(int $tokenId): ?string { // Function signature for ownerOf(uint256) is 0x6352211e // We pad the tokenId to 64 chars (32 bytes) $data = '0x6352211e' . str_pad(Utils::toHex($tokenId, true), 64, '0', STR_PAD_LEFT); $response = $this->callRpc('eth_call', [ [ 'to' => $this->contractAddress, 'data' => $data ], 'latest' ]); if (empty($response['result']) || $response['result'] === '0x') { return null; } // Decode the address (last 40 chars of the 64-char result) return '0x' . substr($response['result'], -40); } /** * Sends a raw JSON-RPC request using Symfony HttpClient. * This offers better observability than standard libraries. */ private function callRpc(string $method, array $params): array { $response = $this->client->request('POST', $this->rpcUrl, [ 'json' => [ 'jsonrpc' => self::JSON_RPC_VERSION, 'method' => $method, 'params' => $params, 'id' => random_int(1, 9999) ] ]); $data = $response->toArray(); if (isset($data['error'])) { throw new \RuntimeException('RPC Error: ' . $data['error']['message']); } return $data; } }

یک تست محلی را با دسترسی به getTicketOwner با یک شناسه ضرب شده شناخته‌شده اجرا کنید. اگر یک آدرس 0x دریافت کردید، اتصال RPC شما کار می‌کند.

ضرب ناهمزمان با Messenger

تراکنش‌های بلاک چین کند هستند (15 ثانیه تا چند دقیقه). هرگز کاربر را مجبور نکنید که برای تأیید بلوک در یک درخواست مرورگر منتظر بماند. ما از Symfony Messenger برای مدیریت این موضوع در پس‌زمینه استفاده خواهیم کرد.

پیام

//src/Message/MintTicketMessage.php: namespace App\Message; use Symfony\Component\Uid\Uuid; readonly class MintTicketMessage { public function __construct( public Uuid $ticketId, public string $userWalletAddress, public string $metadataUri ) {} }

هندلر

اینجا جایی است که جادو اتفاق می‌افتد. ما از کمک‌کننده کتابخانه web3p/web3.php برای امضای محلی یک تراکنش استفاده خواهیم کرد.

توجه: در یک محیط با امنیت بالا، شما از یک سرویس مدیریت کلید (KMS) یا یک enclave امضای جداگانه استفاده خواهید کرد. برای این مقاله، ما به صورت محلی امضا می‌کنیم.

//src/MessageHandler/MintTicketHandler.php namespace App\MessageHandler; use App\Message\MintTicketMessage; use App\Service\Web3\EthereumService; use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Web3\Contract; use Web3\Providers\HttpProvider; use Web3\RequestManagers\HttpRequestManager; use Web3p\EthereumTx\Transaction; #[AsMessageHandler] class MintTicketHandler { public function __construct( private EthereumService $ethereumService, // Our custom service private LoggerInterface $logger, #[Autowire(env: 'BLOCKCHAIN_RPC_URL')] private string $rpcUrl, #[Autowire(env: 'WALLET_PRIVATE_KEY')] private string $privateKey, #[Autowire(env: 'SMART_CONTRACT_ADDRESS')] private string $contractAddress ) {} public function __invoke(MintTicketMessage $message): void { $this->logger->info("Starting mint process for Ticket {$message->ticketId}"); // 1. Prepare Transaction Data (mintTo function) // detailed implementation of raw transaction signing usually goes here. // For brevity, we simulate the logic flow: try { // Logic to get current nonce and gas price via EthereumService // $nonce = ... // $gasPrice = ... // Sign transaction offline to prevent key exposure over network // $tx = new Transaction([...]); // $signedTx = '0x' . $tx->sign($this->privateKey); // Broadcast // $txHash = $this->ethereumService->sendRawTransaction($signedTx); // In a real app, you would save $txHash to the database entity here $this->logger->info("Mint transaction broadcast successfully."); } catch (\Throwable $e) { $this->logger->error("Minting failed: " . $e->getMessage()); // Symfony Messenger will automatically retry based on config throw $e; } } }

کنترلر

کنترلر نازک باقی می‌ماند. درخواست را می‌پذیرد، ورودی را اعتبارسنجی می‌کند، یک موجودیت بلیط "در انتظار" در پایگاه داده شما ایجاد می‌کند (برای اختصار حذف شده) و پیام را ارسال می‌کند.

//src/Controller/TicketController.php: namespace App\Controller; use App\Message\MintTicketMessage; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Uid\Uuid; #[Route('/api/v1/tickets')] class TicketController extends AbstractController { #[Route('/mint', methods: ['POST'])] public function mint(Request $request, MessageBusInterface $bus): JsonResponse { $payload = $request->getPayload(); $walletAddress = $payload->get('wallet_address'); // 1. Basic Validation if (!$walletAddress || !str_starts_with($walletAddress, '0x')) { return $this->json(['error' => 'Invalid wallet address'], 400); } // 2. Generate Internal ID $ticketId = Uuid::v7(); // 3. Dispatch Message (Fire and Forget) $bus->dispatch(new MintTicketMessage( $ticketId, $walletAddress, 'https://api.myapp.com/metadata/' . $ticketId->toRfc4122() )); // 4. Respond immediately return $this->json([ 'status' => 'processing', 'ticket_id' => $ticketId->toRfc4122(), 'message' => 'Minting request queued. Check status later.' ], 202); } }

پیکربندی و راهنمای سبک

با پیروی از سبک Symfony 7.4، ما از تایپ دقیق و ویژگی‌ها استفاده می‌کنیم. اطمینان حاصل کنید که messenger.yaml شما برای انتقال async پیکربندی شده است.

#config/packages/messenger.yaml: framework: messenger: transports: async: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' retry_strategy: max_retries: 3 delay: 1000 multiplier: 2 routing: 'App\Message\MintTicketMessage': async

تأیید

برای تأیید این که این پیاده‌سازی بدون استقرار در Mainnet کار می‌کند:

گره محلی: یک بلاک چین محلی با استفاده از Hardhat یا Anvil (Foundry) اجرا کنید.

npx hardhat node

محیط: .env.local خود را تنظیم کنید تا به localhost اشاره کند.

BLOCKCHAIN_RPC_URL="http://127.0.0.1:8545" WALLET_PRIVATE_KEY="<one of the test keys provided by hardhat>" SMART_CONTRACT_ADDRESS="<deployed contract address>" MESSENGER_TRANSPORT_DSN="doctrine://default"

مصرف: worker را شروع کنید.

php bin/console messenger:consume async -vv

درخواست:

curl -X POST https://localhost:8000/api/v1/tickets/mint \ -H "Content-Type: application/json" \ -d '{"wallet_address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"}'

باید ببینید که worker پیام را پردازش می‌کند و، اگر منطق امضای تراکنش خام را به طور کامل پیاده‌سازی کرده‌اید، یک هش تراکنش در کنسول Hardhat شما ظاهر می‌شود.

نتیجه‌گیری

ساخت برنامه‌های وب 3 در PHP نیاز به یک تغییر در ذهنیت دارد. شما فقط در حال ساخت یک برنامه CRUD نیستید؛ شما در حال ساخت یک هماهنگ‌کننده برای حالت غیرمتمرکز هستید.

با استفاده از Symfony 7.4، ما از موارد زیر بهره بردیم:

  • HttpClient برای ارتباط RPC قابل اعتماد و قابل کنترل.
  • Messenger برای مدیریت واقعیت ناهمزمان بلاک چین‌ها.
  • ویژگی‌های PHP 8.3 برای کد تمیز و خوانا.

این معماری مقیاس‌پذیر است. چه در حال فروش 10 بلیط باشید یا 10000، صف پیام به عنوان یک بافر عمل می‌کند و اطمینان حاصل می‌کند که nonce های تراکنش شما با هم تصادم نمی‌کنند و سرور شما متوقف نمی‌شود.

آماده برای مقیاس‌بندی زیرساخت وب 3 خود هستید؟

یکپارچه‌سازی بلاک چین نیاز به دقت دارد. اگر به کمک برای حسابرسی قرارداد هوشمند تعاملات خود یا مقیاس‌بندی مصرف‌کنندگان پیام Symfony خود نیاز دارید، با ما در تماس باشید.

\

فرصت‌ های بازار
لوگو 4
4 قیمت لحظه ای(4)
$0.02013
$0.02013$0.02013
+2.33%
USD
نمودار قیمت لحظه ای 4 (4)
سلب مسئولیت: مطالب بازنشرشده در این وب‌ سایت از منابع عمومی گردآوری شده‌ اند و صرفاً به‌ منظور اطلاع‌ رسانی ارائه می‌ شوند. این مطالب لزوماً بازتاب‌ دهنده دیدگاه‌ ها یا مواضع MEXC نیستند. کلیه حقوق مادی و معنوی آثار متعلق به نویسندگان اصلی است. در صورت مشاهده هرگونه محتوای ناقض حقوق اشخاص ثالث، لطفاً از طریق آدرس ایمیل service@support.mexc.com با ما تماس بگیرید تا مورد بررسی و حذف قرار گیرد.MEXC هیچ‌ گونه تضمینی نسبت به دقت، جامعیت یا به‌ روزبودن اطلاعات ارائه‌ شده ندارد و مسئولیتی در قبال هرگونه اقدام یا تصمیم‌ گیری مبتنی بر این اطلاعات نمی‌ پذیرد. همچنین، محتوای منتشرشده نباید به‌عنوان توصیه مالی، حقوقی یا حرفه‌ ای تلقی شود و به منزله پیشنهاد یا تأیید رسمی از سوی MEXC نیست.