Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tea Xml Laravel Package

alibabacloud/tea-xml

XML helper for Alibaba Cloud Tea SDKs in PHP, offering utilities to parse XML responses and build XML request bodies. Lightweight and easy to integrate, it simplifies working with XML-based APIs alongside the Tea framework's request and response pipeline.

View on GitHub
Deep Wiki
Context7

Getting Started

alibabacloud/tea-xml is a very small single-class helper from the Alibaba Cloud Tea (Darabonba) PHP runtime. It does exactly two things: turn an XML string into a PHP array, and turn a PHP array back into an XML string. Everything lives in vendor/alibabacloud/tea-xml/src/XML.php — read that file first; it is a few dozen lines and is the entire package.

You will usually not install it directly. It is pulled in transitively by Alibaba Cloud SDK packages (alibabacloud/ecs, alibabacloud/oss, alibabacloud/tea-*) that were generated by the Tea compiler. Before adding it to composer.json, check whether it is already there:

composer why alibabacloud/tea-xml

If you do need it explicitly:

composer require alibabacloud/tea-xml

The package assumes ext-simplexml is available and expects the base Tea runtime (alibabacloud/tea) alongside it.

First use case: you have called an older Alibaba Cloud OpenAPI endpoint (ECS, RDS, SLB, DNS — the pre-JSON "RPC style" APIs) and the raw response body is XML. Instead of hand-rolling simplexml_load_string() conversion in every controller, let the SDK's own parser do it:

use AlibabaCloud\Tea\XML\XML;

$result = XML::parseXml($response->body);   // ['RequestId' => '...', 'Instances' => [...]]

For outbound XML (APIs that accept an XML request body), the reverse direction is:

$xmlBody = XML::toXml($payload);

That is 95% of what this package does in day-to-day work. Treat it as a serialization primitive, not a framework.

Implementation Patterns

1. Parsing SDK responses that return XML. The generated Tea clients hand you $response->body as a raw string. The canonical pattern is to feed it straight into parseXml() and then map into your own DTOs or Eloquent models:

$raw   = $client->describeInstances($request)->body;
$data  = XML::parseXml($raw);

$instances = collect($data['Instances']['Instance'] ?? [])
    ->map(fn (array $i) => new InstanceDto(
        id:    $i['InstanceId'],
        name:  $i['InstanceName'],
        state: $i['Status'],
    ));

2. Wrapping it behind your own adapter. Because the API surface is static methods, it is awkward to mock in tests. Put a thin interface in front of it once and inject that everywhere:

interface XmlCodec
{
    public function decode(string $xml): array;
    public function encode(array $data): string;
}

final class TeaXmlCodec implements XmlCodec
{
    public function decode(string $xml): array { return XML::parseXml($xml); }
    public function encode(array $data): string { return XML::toXml($data); }
}

This buys you testability and an exit hatch if Alibaba changes the runtime or you want to switch to symfony/serializer.

3. Normalizing list-shaped responses. XML has no concept of "array"; a repeated element collapses to a single associative array when there is one result and becomes a numerically indexed array when there are several. Normalize immediately after parsing so downstream code never has to branch:

$instances = $data['Instances']['Instance'] ?? [];
$instances = isset($instances[0]) ? $instances : [$instances];

4. Building fixtures from real traffic. The fastest way to write tests for an XML-backed integration is to capture a real response body once, drop it into tests/fixtures/, and assert on the parsed array. Golden-file tests catch the single-vs-list and empty-element quirks before your users do:

public function test_parses_describe_instances(): void
{
    $xml = file_get_contents(__DIR__.'/fixtures/describe-instances.xml');
    $this->assertSame('i-123', XML::parseXml($xml)['Instances']['Instance']['InstanceId']);
}

5. Mixing with Laravel's HTTP client. If you are calling Alibaba endpoints with Http:: rather than the SDK, keep the raw body and hand it to the codec — do not use ->json() or ->body() with manual string surgery:

$response = Http::get($endpoint, $params);
$data = app(XmlCodec::class)->decode($response->body());

6. Logging the round trip. When debugging a serializer, log both the raw string and the parsed array side by side. XML failures are almost always visible in the raw payload (extra namespace, unexpected wrapper element) and invisible in the array.

Gotchas and Tips

  • The package is essentially frozen. Last release was 2023-06-30, one star, zero direct dependents. That does not mean it is broken — it means nobody is fixing it. Pin the version in composer.json and keep your adapter layer so a future swap is a one-class change.

  • Empty or whitespace-only input is the classic crash. parseXml('') will not give you a friendly empty array; it will fail to load and throw. Always guard at the boundary:

    if (trim($response->body()) === '') { return []; }
    
  • Everything comes back as a string (or an object cast to string). 'Count' => '3', 'PublicIp' => 'true'. Cast at the DTO boundary, not deep inside business logic, or you will chase "0" === 0 bugs.

  • Namespaces and attributes are the weak spot. The parser is oriented at the flat, attribute-free XML that Alibaba's RPC APIs emit. XML that relies on namespaced elements or on attributes for the actual data (SOAP-style, WS-*, many third-party feeds) is a poor fit — reach for DOMDocument or symfony/serializer there instead.

  • Do not parse untrusted XML with it. It is a thin wrapper over SimpleXML with no explicit hardening flags exposed. On older PHP versions this leaves you open to entity-expansion attacks. If the XML source is user-supplied, run it through DOMDocument with LIBXML_NONET and entity loading disabled yourself.

  • Check toXml() against your target API before trusting it. Root element naming, how it renders booleans, and how it escapes special characters are all things the Tea-generated request builders already handle; hand-rolled calls can produce payloads the API silently rejects with a generic InvalidParameter. Diff your generated string against a known-good request from the Alibaba console.

  • Large documents will exhaust memory. The whole string is loaded and converted to a nested array. For files in the tens of megabytes, use XMLReader for streaming instead — this package is for API responses measured in kilobytes.

  • libxml errors are swallowed. When parsing fails you typically get a generic exception with no line number. Before concluding the XML is malformed, do:

    libxml_use_internal_errors(true);
    // ... attempt parse ...
    foreach (libxml_get_errors() as $e) { logger($e->message); }
    
  • Do not reach for this on JSON APIs. A surprising amount of confusion comes from grabbing the Tea XML helper when the endpoint actually speaks JSON — check the Accept/Content-Type the product documents before wiring the codec in.

  • Extension point, such as it is: the class is final-ish in spirit (static methods, no config). The only real seam is the adapter you write around it. Add your normalization, casting, and logging there — that file is where all the day-to-day leverage lives.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums