คู่มือนี้แสดงวิธีการสร้างแบ็กเอนด์ระบบขายตั๋วกิจกรรมแบบ NFT ที่ปรับขนาดได้ใน PHP โดยใช้ Symfony Messenger เพื่อจัดการความล่าช้าของบล็อกเชนอย่างปลอดภัยและเชื่อถือได้คู่มือนี้แสดงวิธีการสร้างแบ็กเอนด์ระบบขายตั๋วกิจกรรมแบบ NFT ที่ปรับขนาดได้ใน PHP โดยใช้ Symfony Messenger เพื่อจัดการความล่าช้าของบล็อกเชนอย่างปลอดภัยและเชื่อถือได้

การสร้างระบบตั๋วกิจกรรมแบบกระจายอำนาจ Web3 ด้วย Symfony 7.4

2025/12/22 01:43
5 นาทีในการอ่าน

จุดตัดระหว่าง Web3 และเฟรมเวิร์กเว็บแบบดั้งเดิมคือจุดที่ประโยชน์ในโลกแห่งความเป็นจริงเริ่มต้นขึ้น แม้ว่ารอบของความนิยมจะมาและไป แต่ประโยชน์ของ Non-Fungible Tokens (NFTs) สำหรับการตรวจสอบความเป็นเจ้าของ — โดยเฉพาะในการจำหน่ายตั๋วเข้างาน — ยังคงเป็นกรณีการใช้งานที่มั่นคง

ในบทความนี้ เราจะสร้างโครงสร้างพื้นฐานของ ระบบตั๋วเข้างานแบบกระจายศูนย์ โดยใช้ Symfony 7.4 และ PHP 8.3 เราจะก้าวข้ามบทเรียนพื้นฐานและนำสถาปัตยกรรมระดับโปรดักชันมาใช้ที่จัดการกับธรรมชาติแบบอะซิงโครนัสของธุรกรรมบล็อกเชนโดยใช้คอมโพเนนต์ Symfony Messenger

สถาปัตยกรรม

แนวทาง "ระดับอาวุโส" ยอมรับว่า PHP ไม่ใช่โปรเซสที่ทำงานยาวนานเหมือน Node.js ดังนั้นเราจึงไม่ฟังเหตุการณ์บล็อกเชนแบบเรียลไทม์ภายในคอนโทรลเลอร์ เราใช้แนวทางแบบผสมแทน:

  1. การโต้ตอบโดยตรง (เขียน): เราใช้ Symfony Messenger เพื่อถ่ายโอนธุรกรรม "Minting" ไปยังเวิร์กเกอร์ เพื่อป้องกันการหมดเวลา HTTP
  2. RPC Polling (อ่าน): เราใช้คำสั่งที่กำหนดเวลาไว้เพื่อตรวจสอบสถานะบนเชน
  3. สัญญาอัจฉริยะ: เราสมมติว่าเป็นสัญญา ERC-721 มาตรฐานที่ปรับใช้บนเชนที่เข้ากันได้กับ EVM (Ethereum, Polygon, Base)

ข้อกำหนดเบื้องต้นและสแต็ก

  • PHP: 8.3+
  • Symfony: 7.4 (LTS)
  • Blockchain Node: Infura, Alchemy หรือโหนด Hardhat ในเครื่อง

ไลบรารี PHP Web3 จำนวนมากถูกละทิ้งหรือมีการพิมพ์ที่ไม่ดี แม้ว่า web3p/web3.php จะมีชื่อเสียงที่สุด แต่การพึ่งพาอย่างเคร่งครัดอาจมีความเสี่ยงเนื่องจากช่องว่างในการบำรุงรักษา

สำหรับคู่มือนี้ เราจะใช้ web3p/web3.php (เวอร์ชัน ^0.3) สำหรับการเข้ารหัส ABI แต่จะใช้ประโยชน์จาก Symfony's native HttpClient สำหรับการส่งข้อมูล JSON-RPC จริง สิ่งนี้ให้การควบคุมอย่างเต็มที่เกี่ยวกับการหมดเวลา การลองใหม่ และการบันทึกข้อมูล — ซึ่งสำคัญสำหรับแอปพลิเคชันโปรดักชัน

การตั้งค่าโครงการ

ก่อนอื่น มาติดตั้งการพึ่งพากัน เราต้องการ Symfony runtime, HTTP client และไลบรารี Web3

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 ด้วย ID ที่มิ้นต์แล้วที่ทราบ หากคุณได้รับที่อยู่ 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 เพื่อลงนามธุรกรรมในเครื่อง

หมายเหตุ: ในสภาพแวดล้อมความปลอดภัยสูง คุณจะใช้ Key Management Service (KMS) หรือส่วนการลงนามแยกต่างหาก สำหรับบทความนี้ เราลงนามในเครื่อง

//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 ของคุณได้รับการกำหนดค่าสำหรับการส่งข้อมูลแบบอะซิงค์

#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"

ใช้งาน: เริ่มเวิร์กเกอร์

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"}'

คุณควรเห็นเวิร์กเกอร์ประมวลผลข้อความ และหากคุณใช้ตรรกะการลงนามธุรกรรมแบบดิบอย่างสมบูรณ์ แฮชของธุรกรรมจะปรากฏในคอนโซล Hardhat ของคุณ

บทสรุป

การสร้างแอปพลิเคชัน Web3 ใน PHP ต้องการ การเปลี่ยนแปลงความคิด คุณไม่ได้แค่สร้างแอป CRUD คุณกำลังสร้างตัวควบคุมสำหรับสถานะแบบกระจายศูนย์

โดยใช้ Symfony 7.4 เราได้ใช้ประโยชน์จาก:

  • HttpClient สำหรับการสื่อสาร RPC ที่เชื่อถือได้และควบคุมได้
  • Messenger เพื่อจัดการความเป็นจริงแบบอะซิงโครนัสของบล็อกเชน
  • PHP 8.3 Attributes สำหรับโค้ดที่สะอาดและอ่านง่าย

สถาปัตยกรรมนี้ปรับขนาดได้ ไม่ว่าคุณจะขายตั๋ว 10 ใบหรือ 10,000 ใบ คิวข้อความทำหน้าที่เป็นบัฟเฟอร์ เพื่อให้มั่นใจว่า nonce ของธุรกรรมของคุณไม่ชนกันและเซิร์ฟเวอร์ของคุณไม่แฮงค์

พร้อมที่จะปรับขนาดโครงสร้างพื้นฐาน Web3 ของคุณหรือไม่?

การผสานรวมบล็อกเชนต้องการความแม่นยำ หากคุณต้องการความช่วยเหลือในการตรวจสอบการโต้ตอบสัญญาอัจฉริยะของคุณหรือการปรับขนาดคอนซูเมอร์ข้อความ Symfony ของคุณ ติดต่อเรา

\

โอกาสทางการตลาด
4 โลโก้
ราคา 4(4)
$0.009769
$0.009769$0.009769
+1.48%
USD
4 (4) กราฟราคาสด
ข้อจำกัดความรับผิดชอบ: บทความที่โพสต์ซ้ำในไซต์นี้มาจากแพลตฟอร์มสาธารณะและมีไว้เพื่อจุดประสงค์ในการให้ข้อมูลเท่านั้น ซึ่งไม่ได้สะท้อนถึงมุมมองของ MEXC แต่อย่างใด ลิขสิทธิ์ทั้งหมดยังคงเป็นของผู้เขียนดั้งเดิม หากคุณเชื่อว่าเนื้อหาใดละเมิดสิทธิของบุคคลที่สาม โปรดติดต่อ service@mexc.com เพื่อลบออก MEXC ไม่รับประกันความถูกต้อง ความสมบูรณ์ หรือความทันเวลาของเนื้อหาใดๆ และไม่รับผิดชอบต่อการดำเนินการใดๆ ที่เกิดขึ้นตามข้อมูลที่ให้มา เนื้อหานี้ไม่ถือเป็นคำแนะนำทางการเงิน กฎหมาย หรือคำแนะนำจากผู้เชี่ยวชาญอื่นๆ และไม่ถือว่าเป็นคำแนะนำหรือการรับรองจาก MEXC

คุณอาจชอบเช่นกัน

การทำนายราคา Litecoin: LTC จะแตะ $300 ภายในปี 2030 หรือไม่?

การทำนายราคา Litecoin: LTC จะแตะ $300 ภายในปี 2030 หรือไม่?

ประเด็นสำคัญ Litecoin มีแนวโน้มที่จะซื้อขายในช่วง $95–$120 ในปี 2026 ภายใต้สถานการณ์พื้นฐาน การเติบโตอย่างแข็งแกร่งของคริปโตในปี 2027–2028 […] บทความ Litecoin Price Prediction
แชร์
Coindoo2026/02/18 01:42
ผู้สมัครตำแหน่งผู้พิพากษาเขต Kendall เน้นย้ำความสำคัญของการลงคะแนนเสียงล่วงหน้า 17–27 ก.พ.

ผู้สมัครตำแหน่งผู้พิพากษาเขต Kendall เน้นย้ำความสำคัญของการลงคะแนนเสียงล่วงหน้า 17–27 ก.พ.

ผู้สมัครผู้พิพากษาเคาน์ตี้เคนดัลล์ Ricky Gleason กำลังเน้นย้ำความสำคัญของการเลือกตั้งท้องถิ่นและกระตุ้นให้ผู้อยู่อาศัยเข้าร่วมการลงคะแนนเสียงล่วงหน้าตั้งแต่ F
แชร์
Citybuzz2026/02/18 00:05
รัฐมนตรีกระทรวงความมั่นคงแห่งมาตุภูมิของทรัมป์กล่าวอ้างการฉ้อโกงที่เธอไม่สามารถพิสูจน์ได้

รัฐมนตรีกระทรวงความมั่นคงแห่งมาตุภูมิของทรัมป์กล่าวอ้างการฉ้อโกงที่เธอไม่สามารถพิสูจน์ได้

เมื่อรัฐมนตรีว่าการกระทรวงความมั่นคงแห่งมาตุภูมิ Kristi Noem กล่าวในงานแถลงข่าวที่เมืองสก็อตส์เดล รัฐแอริโซนา เมื่อวันที่ 13 กุมภาพันธ์ เธอได้สนับสนุนคำกล่าวอ้างของประธานาธิบดี Donald Trump ที่ว่า
แชร์
Alternet2026/02/18 01:06