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);

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:

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
jsonMasukkan opsi permintaan Anda untuk mengkodekan array secara otomatis dan mengaturnyaContent-Typetajuk. - 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
