Cara menggunakan klien HTTP Symfony di PrestaShop 9

 – Beragampengetahuan
2 mins read

Cara menggunakan klien HTTP Symfony di PrestaShop 9 – Beragampengetahuan

PrestaShop 9 secara resmi menghapus Guzzle dari ketergantungan intinya, menandai perubahan arsitektur.

Guzzle telah menjadi standar komunikasi HTTP di ekosistem PHP selama bertahun-tahun. Namun, seiring berjalannya PrestaShop Symfony 6.4 LTSplatform sekarang distandarisasi pada versi asli Klien HTTP Symfony.

Meskipun meninggalkan alat yang sudah dikenal mungkin terasa membingungkan pada awalnya.

Ini sebenarnya merupakan peluang strategis untuk memodernisasi basis kode modul Anda, menjadikannya lebih ramping, lebih cepat, dan terintegrasi secara mendalam dengan wadah layanan Symfony.

Di blog ini, kami akan membangun modul lengkap yang dapat diinstal dari awal yang menunjukkan dengan tepat cara mengintegrasikan API eksternal”PrestaShop 9 Cara” menggunakan injeksi ketergantungan Dan Melayani.

Contents

Transformasi arsitektur: berorientasi proses → berorientasi layanan

Perubahan konseptual yang paling penting di PrestaShop 9 adalah dari Kode prosedural yang digabungkan secara erat kait bagian dalam Arsitektur berorientasi layanan yang bersih Didukung oleh injeksi ketergantungan.

Sebelum PrestaShop 9:

Pada versi sebelumnya, merupakan hal yang umum untuk membuat instance klien HTTP secara langsung dalam metode kait atau pengontrol. Hal ini membuat kode sulit untuk diuji, digunakan kembali, atau dipelihara:

// Old approach - Business logic, HTTP calls, and error handling all mixed together
public function hookActionValidateOrder(array $params): void

    $client = new GuzzleHttp\Client([
        'base_uri' => '
        'timeout'  => 10,
    ]);

    $response = $client->post('/shipments', [
        'json' => ['order_id' => $params['id_order']],
    ]);

    $data = json_decode($response->getBody(), true);
    // ... process $data

Toko Presta 9:

PrestaShop 9 Pelukan wadah layanan pola. Metode hook atau pengontrol Anda harus melakukan satu hal: mendelegasikan ke layanan. Logika HTTP berada dalam kelas layanan khusus, dapat disuntikkan, dan dapat diuji.

// Good: The hook delegates to a clean service
public function hookActionValidateOrder(array $params): void

    $container      = SymfonyContainer::getInstance();
    $shippingService = $container->get(ShippingApiService::class);

    try 
        $shipment = $shippingService->createShipment($params['id_order']);
        // Clean business logic only
     catch (ShippingException $e) 
        $this->handleShippingError($e);
    
proses arsitektur layanan

Membangun modul langkah demi langkah

mari kita membangun kutipan mingguan Modul lengkap yang dapat diinstal yang mengambil kutipan acak dari API eksternal dan menampilkannya di dasbor PrestaShop.

Mengikuti arsitektur PS 9 secara lengkap: DI, layanan, DTO, caching, dan penanganan kesalahan.

Lokasi modul:Buat file bernama kutipan mingguan Di dalam PrestaShop Anda /modul/ Daftar isi sebelum memulai.

Langkah 1: Tentukan autoloading Komposer

    "name": "wk/wkdailyquote",
    "type": "prestashop-module",
    "require": 
        "php": ">=8.1"
    ,
    "autoload": 
        "psr-4": 
            "WkDailyQuote\\": "src/"
        
    ,
    "config": 
        "prepend-autoloader": false
    

Sekarang, navigasikan ke /modules/wkdailyquote/ Jalankan di terminal Anda:

composer dump-autoload

Langkah 2: Buat objek transfer data (DTO)

DTO menyediakan Struktur data yang aman untuk mengetik dan tervalidasi Digunakan untuk respons API. Daripada menggunakan array mentah di seluruh basis kode Anda, Anda meneruskan objek yang diketik dengan kuat.

dokumen: /modules/wkdailyquote/src/DTO/Quote.php

<?php

namespace WkDailyQuote\DTO;

class Quote

    public function __construct(
        private int    $id,
        private string $quote,
        private string $author
    ) 
        if (empty($quote)) 
            throw new \InvalidArgumentException('Quote cannot be empty');
        
        if (empty($author)) 
            throw new \InvalidArgumentException('Author cannot be empty');
        
    
    public static function fromArray(array $data): self
    
        if (!isset($data['id'], $data['quote'], $data['author'])) 
            throw new \InvalidArgumentException('Invalid API response structure');
        
        return new self((int)$data['id'], $data['quote'], $data['author']);
    
    public function getId(): int
    
        return $this->id;
    
    public function getQuote(): string
    
        return $this->quote;
    
    public function getAuthor(): string
    
        return $this->author;
    
    public function toArray(): array
    
        return ['id' => $this->id, 'quote' => $this->quote, 'author' => $this->author];
    

Langkah 3: Buat kelas pengecualian khusus

Daripada menangkap yang generik \Exception Di mana pun Anda mau, buat kelas pengecualian khusus API Anda sendiri (atau hierarki pengecualian kecil).

Gunakan metode pabrik bernama (mis. ApiException::networkError() atau ApiException::invalidResponse()) juga buat milikmu throw Pernyataan lebih jelas dan mudah dipahami.

dokumen: /modules/wkdailyquote/src/Exception/ApiException.php

<?php

namespace WkDailyQuote\Exception;

class ApiException extends \Exception

    public static function networkError(string $message, ?\Throwable $prev = null): self
    
        return new self("Network error: $message", 0, $prev);
    

    public static function httpError(int $statusCode, string $url): self
    
        return new self("HTTP $statusCode error when accessing $url");
    

    public static function invalidResponse(string $message): self
    
        return new self("Invalid API response: $message");
    

Langkah 4: Bangun Layanan Manajer Cache

Memanggil API eksternal pada setiap pemuatan halaman lambat dan menghabiskan kuota batas kecepatan. QuoteCacheManager membungkus sistem caching bawaan PrestaShop dengan antarmuka yang bersih.

dokumen: /modules/wkdailyquote/src/Service/QuoteCacheManager.php

<?php

namespace WkDailyQuote\Service;

use WkDailyQuote\DTO\Quote;

class QuoteCacheManager

    private const CACHE_KEY = 'wkdailyquote_current';
    private const CACHE_TTL = 3600;

    public function get(): ?Quote
    
        $cached = \Cache::getInstance()->get(self::CACHE_KEY);

        return $cached ? Quote::fromArray($cached) : null;
    

    public function set(Quote $quote): void
    
        \Cache::getInstance()->set(self::CACHE_KEY, $quote->toArray(), self::CACHE_TTL);
    

    public function clear(): void
    
        \Cache::getInstance()->delete(self::CACHE_KEY);
    

Langkah 5: Bangun layanan API (inti modul)

Di Sini Klien HTTP Symfony sebenarnya digunakan. Layanan QuoteFetcher menerima klien melalui injeksi konstruktoritu tidak pernah membuat instance secara langsung. Inilah perbedaan utama dari metode lama.

Perhatikan bagaimana $response->toArray() Symfony secara otomatis menangani penguraian JSON, dan bagaimana setiap jenis kesalahan dipetakan dengan jelas ke kelas pengecualian tertentu melalui hierarki pengecualian Symfony.

dokumen: /modules/wkdailyquote/src/Service/QuoteFetcher.php

<?php

namespace WkDailyQuote\Service;

use WkDailyQuote\DTO\Quote;
use WkDailyQuote\Exception\ApiException;
use WkDailyQuote\Service\QuoteCacheManager;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

class QuoteFetcher
{
    private const API_URL = '
    private const TIMEOUT = 5;
    private const MAX_RETRIES = 2;

    public function __construct(
        private readonly HttpClientInterface $httpClient,
        private readonly QuoteCacheManager   $cacheManager
    ) 
    

    public function getRandomQuote(): ?Quote
    
        if ($cached = $this->cacheManager->get()) 
            return $cached;
        

        try 
            $quote = $this->fetchWithRetry();
            $this->cacheManager->set($quote);
            return $quote;
         catch (ApiException $e) 
            \PrestaShopLogger::addLog("[WkDailyQuote] $e->getMessage()", 3);
            return null;
        
    

    private function fetchWithRetry(): Quote
    
        for ($attempt = 1; $attempt <= self::MAX_RETRIES; $attempt++) 
            try 
                return $this->makeRequest();
             catch (ApiException $e) 
                if ($attempt < self::MAX_RETRIES) 
                    usleep(pow(2, $attempt) * 100000);
                
                $last = $e;
            
        
        throw $last;
    

    private function makeRequest(): Quote
    
        try 
            $response = $this->httpClient->request('GET', self::API_URL, [
                'timeout' => self::TIMEOUT,
                'headers' => ['Accept' => 'application/json'],
            ]);

            if ($response->getStatusCode() !== 200) 
                throw ApiException::httpError($response->getStatusCode(), self::API_URL);
            

            return Quote::fromArray($response->toArray());
         catch (TransportExceptionInterface $e) 
            throw ApiException::networkError($e->getMessage(), $e);
         catch (\InvalidArgumentException $e) 
            throw ApiException::invalidResponse($e->getMessage());
        
    
}

Langkah 6: Konfigurasikan Injeksi Ketergantungan

File YAML inilah tempat keajaiban terjadi. Ini memberitahu wadah Symfony Bagaimana menghubungkan semuanya.

Penampung menemukan bahwa QuoteFetcher memerlukan HttpClientInterface, sehingga secara otomatis memasukkan layanan @http_client bawaan – Anda tidak perlu membuat instance sendiri.

dokumen: /modules/wkdailyquote/config/services.yml

services:
  _defaults:
    autowire: true
    autoconfigure: true
    public: false

  WkDailyQuote\:
    resource: '../src/*'
    exclude:  '../src/index.php,DTO'

  WkDailyQuote\Service\QuoteCacheManager:
    public: true

  WkDailyQuote\Service\QuoteFetcher:
    public: true
    arguments:
      $httpClient:   '@http_client'
      $cacheManager: '@WkDailyQuote\Service\QuoteCacheManager'

Langkah 7: Buat file modul utama

utama wkdailyquote.php File mendaftarkan kait, menyelesaikan layanan dalam wadah, dan mendelegasikan semua pekerjaan aktual kepada mereka.

Perhatikan bahwa tidak ada kode HTTP apa pun di sini; pemisahan kekhawatiran adalah tujuannya.

dokumen: /modules/wkdailyquote/wkdailyquote.php

<?php

require_once __DIR__ . '/vendor/autoload.php';

use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
use WkDailyQuote\Service\QuoteFetcher;
use WkDailyQuote\Service\QuoteCacheManager;

class WkDailyQuote extends Module

    public function __construct()
    
        $this->name = 'wkdailyquote';
        $this->tab = 'administration';
        $this->version = '1.0.0';
        $this->author = 'wk';
        $this->need_instance = 0;
        $this->ps_versions_compliancy = [
            'min' => '9.0.0',
            'max' => _PS_VERSION_
        ];
        $this->bootstrap = true;

        parent::__construct();

        $this->displayName = $this->l('Daily Quote');
        $this->description = $this->l('Displays inspirational quotes on your dashboard using Symfony HTTP Client with caching.');
        $this->confirmUninstall = $this->l('Are you sure you want to uninstall this module?');
    

    public function install(): bool
    
        return parent::install()  && $this->registerHook('displayDashboardTop');
    

    public function uninstall(): bool
    
        $this->clearModuleCache();

        return parent::uninstall();
    

    public function hookDisplayDashboardTop(array $params)
    
        if ($this->context->controller->controller_name != 'AdminDashboard') return;

        $container = SymfonyContainer::getInstance();

        if (!$container->has(QuoteFetcher::class)) 
            return '';
        

        $quote = $container->get(QuoteFetcher::class)->getRandomQuote();

        if (!$quote) 
            return $this->renderErrorMessage();
        

        $this->context->smarty->assign([
            'quote_text'   => $quote->getQuote(),
            'quote_author' => $quote->getAuthor(),
            'quote_id'     => $quote->getId(),
        ]);

        return $this->display(__FILE__, 'views/templates/hook/dashboard_quote.tpl');
    

    private function clearModuleCache(): void
    
        $container = SymfonyContainer::getInstance();

        if ($container->has(QuoteCacheManager::class)) 
            /** @var QuoteCacheManager $cacheManager */
            $cacheManager = $container->get(QuoteCacheManager::class);
            $cacheManager->clear();
        
    

Langkah 8: Buat templat tampilan

dokumen: /modules/wkdailyquote/views/templates/hook/dashboard_quote.tpl

<section id="wkdailyquote" class="panel widget wkdailyquote-container">
  <div class="panel-heading">
    <i class="icon-quote-left"></i>
    l s='Quote of the Moment' mod='wkdailyquote'
  </div>
  <div class="panel-body">
    <blockquote class="wkdailyquote-quote">
      <p>escape:'html':'UTF-8'</p>
      <footer><cite>$quote_author</cite></footer>
    </blockquote>
  </div>
</section>

Dalam contoh ini, kami menggunakan hook PrestaShop untuk menampilkan kutipan di dashboard.

Meskipun sederhana, modul ini akan menunjukkan arsitektur tepat yang diperlukan untuk integrasi kompleks seperti ERP, perusahaan pelayaran, atau gateway pembayaran.

Hasilnya adalah sebagai berikut:

kutipan mingguan

Arsitektur yang Anda bangun dirancang agar dapat diskalakan. Setelah fondasinya terbentuk, berikut empat cara ampuh untuk memperluas kemampuannya:

  • Otentikasi untuk permintaan API: Amankan koneksi Anda dengan menerapkan token Bearer, kunci API, atau header OAuth2 secara langsung dalam konfigurasi klien tercakup.
  • Tangani permintaan POST dengan payload JSON: Melampaui permintaan GET sederhana. Klien dapat dengan mudah mengirim data; gunakan saja json Masukkan opsi permintaan Anda untuk mengkodekan array secara otomatis dan mengaturnya Content-Type tajuk.
  • Menerapkan pembatasan tarif: Gunakan komponen pembatas tarif untuk mencegah pelarangan API. Hal ini memastikan modul Anda tetap berada dalam batas penggunaan penyedia Anda, bahkan selama periode lalu lintas tinggi.
  • Permintaan asinkron dan paralel: Meningkatkan kinerja secara dramatis saat mengambil data dari berbagai sumber. Klien HTTP Symfony bersifat non-pemblokiran, memungkinkan Anda mengaktifkan beberapa permintaan secara bersamaan dan hanya menunggu ketika data benar-benar dibutuhkan.

Itulah isi blog ini.

Jika Anda memiliki pertanyaan atau pertanyaan, silakan bertanya di bagian komentar.

Atau hubungi kami: [email protected]

Saya senang membantu.

Selain itu, Anda dapat menjelajahi layanan pengembangan PrestaShop kami dan beragam modul PrestaShop premium.

rencana pengembangan website



metode pengembangan website

jelaskan beberapa rencana untuk pengembangan website, proses pengembangan website, kekuatan dan kelemahan bisnis pengembangan website
, jasa pengembangan website, tahap pengembangan website, biaya pengembangan website

#Cara #menggunakan #klien #HTTP #Symfony #PrestaShop

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *