SDK PHP de conversion de fichiers#
enconvert/enconvert-php est le client PHP officiel de l'API EnConvert. Installez-le avec Composer, donnez-lui une clé API, et vous obtenez deux choses : douze méthodes de conversion qui transforment des URL, des images et des documents en PDF, PNG, Markdown et formats de données, et un espace de noms $client->v2 qui lit le web en direct sous forme de Markdown, de captures d'écran et de JSON structuré prêts pour un agent. Il cible PHP 8.1+, s'appuie sur Guzzle 7, utilise partout des tableaux d'options en camelCase, et renvoie des objets de résultat typés en lecture seule plutôt que des tableaux flottants. Les conversions longues qui dépassent un timeout HTTP sont récupérées automatiquement par interrogation du job.
enconvert/enconvert-php · Source : conversionapi/php-sdk · PHP : 8.1+ · Requiert : guzzlehttp/guzzle ^7.8
Installation#
composer require enconvert/enconvert-php
Le package est autochargé sous l'espace de noms PSR-4 Enconvert\ et n'embarque ni CLI, ni fichier de configuration, ni service provider. Il fonctionne tel quel en PHP nu, sous Laravel, Symfony, WordPress, et dans n'importe quel projet PSR-4.
Démarrage rapide#
<?php
require __DIR__ . '/vendor/autoload.php';
use Enconvert\Client;
$client = new Client(getenv('ENCONVERT_API_KEY'));
// Convertir une page en direct en PDF et l'écrire directement sur le disque.
$result = $client->convertUrlToPdf('https://example.com', [
'saveTo' => 'page.pdf',
]);
echo $result->presignedUrl, ' ', $result->fileSize, ' bytes', PHP_EOL;
// Lire une page pour un agent passe par le même client et la même clé.
$op = $client->v2->perceive('https://example.com', ['outputs' => ['markdown', 'structured']]);
echo $op->renderQuality, PHP_EOL; // de 0.0 à 1.0, par ex. 0.93
echo $op->outputs['markdown']->url, PHP_EOL; // URL de téléchargement signée
Le SDK est côté serveur uniquement. Une clé privée (sk_live_...) ne doit jamais atteindre un navigateur ni une application mobile.
Ce que le client expose#
| Surface | Comment y accéder | Ce qu'elle fait |
|---|---|---|
| Conversion de fichiers et d'URL | $client->convert*() |
Douze méthodes sur POST /v1/convert/*, plus l'interrogation des jobs et des lots. |
| Web intelligence (V2) | $client->v2 (ou $client->v2()) |
Vingt-trois méthodes sur /v2/* : perceive, discover, lookup, distill, ingest, watch. |
| Introspection des formats | Enconvert\Formats |
Les 43 paires {input}-to-{output} implémentées, la résolution MIME, et les listes de sorties par entrée. |
| Erreurs | Enconvert\Exception\* |
La base EnconvertException plus ApiException, AuthenticationException, QuotaException, RateLimitException. |
| Résultats | Enconvert\Model\* |
Objets valeur en lecture seule, avec des propriétés en camelCase. |
$client->v2 est une propriété publique en lecture seule. $client->v2() est un accesseur identique pour ceux qui préfèrent la syntaxe méthode. Chaque endpoint V2 exige une clé API privée ; les clés publiques sont rejetées.
Conversion de fichiers#
Chaque méthode portant sur un fichier unique renvoie un ConversionResult porteur d'une URL de téléchargement présignée. Passez saveTo et le SDK écrit également les octets vers ce chemin local, en créant les répertoires parents au besoin.
convertUrlToPdf#
Rend en PDF n'importe quelle URL accessible.
$result = $client->convertUrlToPdf('https://example.com', [
'singlePage' => false,
'pdfOptions' => ['pageSize' => 'A4', 'orientation' => 'landscape'],
'viewportWidth' => 1440,
'saveTo' => 'report.pdf',
]);
| Option | Type | Par défaut | Description |
|---|---|---|---|
saveTo |
string |
aucun | Chemin local vers lequel écrire le PDF. Les répertoires parents sont créés. |
singlePage |
bool |
true |
true produit une seule page continue. false pagine en utilisant pdfOptions.pageSize. |
pdfOptions |
array |
aucun | Taille de page, orientation, marges, échelle, niveaux de gris, en-tête, pied de page. Voir Options PDF. |
viewportWidth, viewportHeight |
int |
1920, 1080 |
Taille de la fenêtre d'affichage du navigateur, en pixels. |
loadMedia |
bool |
true |
Attend les images et les vidéos avant la capture. |
enableScroll |
bool |
true |
Fait défiler la page de haut en bas pour déclencher les chargements différés. |
outputFilename |
string |
auto | Remplace le nom de fichier généré. |
auth, cookies, headers |
array |
aucun | Accès à la page : Basic Auth ['username' => ..., 'password' => ...], cookies injectés, en-têtes de requête personnalisés. |
auth avec un en-tête Authorization. L'API rejette ce conflit plutôt que de deviner quel identifiant vous vouliez utiliser.
convertUrlToScreenshot#
Capture un PNG de n'importe quelle URL.
$shot = $client->convertUrlToScreenshot('https://example.com', [
'viewportWidth' => 1440,
'saveTo' => 'shot.png',
]);
Accepte les mêmes options de fenêtre d'affichage, de médias, de défilement, de nom de fichier et d'accès à la page que convertUrlToPdf, à l'exception de singlePage et pdfOptions.
convertUrlToMarkdown#
Extrait du Markdown GitHub-Flavored propre à partir d'une URL. La navigation, les pieds de page, les publicités et les scripts sont supprimés, le corps principal de l'article est conservé, et un frontmatter YAML (title, description, url, links, images) est ajouté en tête.
$md = $client->convertUrlToMarkdown('https://example.com/article', [
'saveTo' => 'article.md',
]);
Même jeu d'options que convertUrlToScreenshot.
convertImage#
Convertit entre jpeg, png, svg, heic et webp, ou rastérise un PDF en JPEG.
// Depuis un chemin.
$client->convertImage('photo.heic', ['outputFormat' => 'webp', 'saveTo' => 'photo.webp']);
// Depuis des octets bruts. Le nom de fichier détermine le format d'entrée et le type MIME.
$client->convertImage(
['data' => file_get_contents('photo.heic'), 'filename' => 'photo.heic'],
['outputFormat' => 'webp', 'saveTo' => 'photo.webp']
);
$client->convertImage('scan.pdf', ['outputFormat' => 'jpeg', 'saveTo' => 'scan.jpeg']); // rastérisation
Le format d'entrée vient de l'extension du fichier : .jpg, .jpeg, .png, .svg, .heic, .webp et .pdf. Le format de sortie est obligatoire et normalisé pour vous, si bien que jpg se résout en jpeg.
| Option | Type | Requis | Description |
|---|---|---|---|
outputFormat |
string |
Oui | Une valeur parmi jpeg, png, svg, heic, webp. |
saveTo |
string |
Non | Chemin local vers lequel écrire le résultat. |
outputFilename |
string |
Non | Remplace le nom de fichier généré. |
convertDocument#
Convertit des documents et des formats de données. outputFormat vaut pdf par défaut.
// docx vers pdf, puis json vers yaml
$client->convertDocument('report.docx', ['saveTo' => 'report.pdf']);
$client->convertDocument('data.json', ['outputFormat' => 'yaml', 'saveTo' => 'data.yaml']);
// markdown vers pdf avec mise en page
$client->convertDocument('README.md', [
'outputFormat' => 'pdf',
'pdfOptions' => ['pageSize' => 'A4', 'margins' => ['top' => 20, 'bottom' => 20]],
'saveTo' => 'readme.pdf',
]);
Extensions d'entrée reconnues : .doc, .docx, .xls, .xlsx, .ppt, .pptx, .html, .htm, .odt, .ods, .odp, .ots, .pages, .numbers, .md, .markdown, .csv, .json, .xml, .yaml, .yml, .toml.
| Option | Type | Par défaut | Description |
|---|---|---|---|
outputFormat |
string |
"pdf" |
Format cible. Les alias jpg, yml, htm et md sont résolus. |
saveTo |
string |
aucun | Chemin local vers lequel écrire le résultat. |
outputFilename |
string |
aucun | Remplace le nom de fichier généré. |
pdfOptions |
array |
aucun | Mise en page. Prise en compte lorsque la sortie est un PDF. |
L'EPUB n'a pas de paire de conversion documentaire dédiée. Faites passer les fichiers .epub par convertToPdf ou convertToMarkdown.
Paires de conversion prises en charge#
| Entrée | Sorties |
|---|---|
json |
csv, toml, xml, yaml |
xml |
csv, json |
yaml, toml |
json |
csv |
json, xml |
markdown |
html, pdf |
html |
pdf |
doc, excel, ppt, odt, ods, odp, ots, pages, numbers |
pdf |
jpeg, png, svg, heic, webp |
les uns vers les autres (les 20 paires) |
pdf |
jpeg |
Le SDK valide la paire {input}-to-{output} contre ce tableau et lève une EnconvertException avant qu'aucune requête ne quitte votre processus, avec la liste des sorties valides pour cette entrée dans le message. Vous pouvez interroger le même tableau directement :
use Enconvert\Formats;
Formats::validOutputsFor('json'); // ["csv", "toml", "xml", "yaml"]
Formats::validOutputsFor('pdf'); // ["jpeg"]
Formats::normalizeOutputFormat('JPG'); // "jpeg"
Formats::mimeFor('deck.pptx'); // le type MIME du PPTX
count(Formats::IMPLEMENTED_CONVERSIONS); // 43
convertToMarkdown#
Détecte automatiquement le format d'un document côté serveur et renvoie du Markdown. C'est la brique d'ingestion RAG pour les fichiers que vous avez déjà sur le disque.
$client->convertToMarkdown('handbook.docx', ['saveTo' => 'handbook.md']);
Accepte les formats PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT/MD, ainsi que les fichiers bureautiques hérités ou ODF. Les images ne sont pas prises en charge. Les options sont saveTo et outputFilename ; cet endpoint n'accepte aucune option PDF.
convertToPdf#
Détecte automatiquement presque n'importe quelle entrée et renvoie un PDF.
$client->convertToPdf('slides.pptx', ['saveTo' => 'slides.pdf']);
// Une entrée PDF est transmise telle quelle : cela sert donc aussi de normalisation en niveaux de gris.
$client->convertToPdf('scan.pdf', ['pdfOptions' => ['grayscale' => true], 'saveTo' => 'gray.pdf']);
Accepte les formats bureautiques, ODF, Pages, Numbers, RTF, CSV, HTML, Markdown, texte brut, images matricielles, SVG, EPUB, ainsi qu'un PDF existant transmis tel quel.
pdfOptions.grayscale est pris en compte ici. Le format est détecté côté serveur, la géométrie de page vient donc du document source. Utilisez convertDocument ou convertUrlToPdf lorsque vous avez besoin d'une taille de page, de marges, d'une orientation, d'en-têtes ou de pieds de page.
convertWebsiteToPdf et convertWebsiteToScreenshot#
Découvrent chaque page d'un site, convertissent chacune d'elles en arrière-plan, et rassemblent le tout dans une seule archive ZIP. Les deux sont asynchrones et renvoient un BatchSubmission plutôt qu'un ConversionResult. Elles exigent une clé API privée disposant de l'accès au crawl.
$batch = $client->convertWebsiteToPdf('https://example.com', [
'crawlMode' => 'sitemap', // "auto" (par défaut) | "sitemap" | "full"
'excludePatterns' => ['/blog/tag/'], // mode full crawl uniquement
'notificationEmail' => '[email protected]',
]);
echo $batch->batchId, ' ', $batch->urlCount, ' ', $batch->discoveryMethod, PHP_EOL;
// Bloque jusqu'à ce que le lot quitte l'état "processing", puis enregistre le ZIP.
$status = $client->waitForBatch($batch->batchId, ['saveTo' => 'site.zip']);
echo $status->completed, ' of ', $status->total, ' pages converted', PHP_EOL;
// Ou interrogez-le vous-même avec getBatchStatus().
$s = $client->getBatchStatus($batch->batchId);
echo $s->status === 'processing' ? 'still working' : $s->zipDownloadUrl, PHP_EOL;
convertWebsiteToScreenshot prend les mêmes options, sans singlePage ni pdfOptions, et produit un ZIP de PNG.
| Option | Type | Par défaut | Description |
|---|---|---|---|
crawlMode |
string |
"auto" |
auto, sitemap ou full. |
includePatterns, excludePatterns |
string[] |
aucun | Conserve ou écarte des URL par motif. Les exclusions s'appliquent en mode full crawl. |
notificationEmail, callbackUrl |
string |
aucun | Adresse e-mail et webhook à notifier à la fin du traitement. |
viewportWidth, viewportHeight, loadMedia, enableScroll |
variable | valeur serveur | Options de rendu par page. Envoyées uniquement si vous les définissez. |
auth, cookies, headers |
array |
aucun | Accès aux pages des sites derrière une authentification. |
outputFilename |
string |
aucun | Remplace le nom de fichier du ZIP. |
waitForBatch accepte intervalMs (5000 par défaut), timeoutMs (1800000 par défaut, soit 30 minutes) et saveTo. Elle lève une ApiException avec le statut 504 si le délai expire alors que le lot est toujours en traitement.
getJobStatus#
Interroge un job de conversion unique, asynchrone ou récupéré.
$status = $client->getJobStatus('job_abc123');
if ($status->status === 'success') {
echo $status->presignedUrl, PHP_EOL;
} elseif ($status->status === 'failed') {
echo $status->error, PHP_EOL;
}
Renvoie un JobStatus avec status (processing, success ou failed), presignedUrl, objectKey et error. Vous en avez rarement besoin directement, puisque le SDK interroge pour vous. Voir Récupération des timeouts.
Web intelligence (V2)#
L'espace de noms $client->v2 transforme des pages web en direct en données prêtes pour un agent : rendre, rechercher, extraire, ingérer et surveiller. Chaque lecture porte renderQuality, un score de 0.0 à 1.0 qui distingue un vrai rendu d'un rendu raté. Une page de challenge, un mur de cookies, un écran de connexion ou une coquille SPA vide reviennent avec un score bas et des warnings renseignés : une mauvaise lecture n'entre donc jamais silencieusement dans le contexte d'un agent. Le contenu est tout de même renvoyé ; il est signalé, pas masqué. Les concepts sont détaillés dans la vue d'ensemble V2.
Perceive#
Rend une URL et matérialise, à partir de ce rendu unique, toutes les sorties que vous avez demandées. Voir la référence perceive.
$op = $client->v2->perceive('https://example.com/pricing', [
'outputs' => ['markdown', 'screenshot', 'structured'],
'extract' => ['tables', 'metadata'],
'onlyMainContent' => true,
'waitFor' => '.price',
]);
echo $op->renderQuality, ' ', $op->statusCode, PHP_EOL; // score, statut HTTP amont
print_r($op->deductions); // par ex. ["login_wall" => 0.65]
echo $op->outputs['markdown']->url, PHP_EOL; // URL signée, 15 minutes
print_r($op->structured);
// Les URL signées expirent. Resignez-les plus tard sans refaire le rendu.
$again = $client->v2->getPerceiveOperation($op->operationId);
| Option | Type | Description |
|---|---|---|
outputs |
string[] |
Une valeur parmi markdown, html_cleaned, html_raw, screenshot, screenshot_full_page, pdf, links, images, structured. |
extract |
string[] |
Champs structurés à extraire, par exemple metadata, structured_data, headings, tables, main_content, all. |
schema |
array |
Schéma pour l'extraction structurée assistée par LLM. |
onlyMainContent |
bool |
Supprime l'habillage du site de la sortie Markdown. |
waitFor, waitTimeoutMs |
string, int |
Attend un sélecteur CSS ou une expression JS après la navigation. |
jsCode |
string |
JavaScript à exécuter sur la page après la navigation. |
viewport, mobile, blockResources |
array, bool, string[] |
Géométrie de rendu, et types de ressources à abandonner avant leur chargement. |
cacheMode |
string |
enabled, bypass ou refresh. |
headers, cookies, auth |
array |
Accès aux pages authentifiées. |
respectRobots |
bool |
Rejette les URL interdites par robots.txt. |
pdfOptions |
array |
Mise en page pour la sortie pdf. |
directDownload |
bool |
Renvoie les octets bruts de l'artefact. Accepté par perceive() uniquement. |
proxyUrl, geolocation, actionChain |
variable | Sérialisés par le SDK, réservés par l'API. |
Perception par lot#
$batch = $client->v2->perceiveBatch(['https://a.com', 'https://b.com'], [
'outputs' => ['markdown'],
'outputMode' => 'zip',
]);
// Les petits lots se terminent en ligne. Les plus gros reviennent en file d'attente, interrogez-les.
if ($batch->status !== 'completed') {
$batch = $client->v2->getPerceiveBatch($batch->jobId);
}
foreach ($batch->items as $item) {
echo $item->url, ' ', $item->renderQuality, PHP_EOL;
}
echo $batch->zip?->url, PHP_EOL;
Jusqu'à 1000 URL partagent un seul bloc d'options. outputMode vaut manifest (par défaut) ou zip. directDownload n'est pas accepté ici.
Diffusion d'un artefact unique#
perceiveDirect() court-circuite l'enveloppe JSON et vous rend directement les octets. Exactement une sortie produisant un artefact doit être demandée, et le SDK le vérifie avant l'envoi : structured seul lève donc une erreur.
$direct = $client->v2->perceiveDirect('https://example.com', [
'outputs' => ['pdf'],
]);
file_put_contents($direct->filename ?? 'page.pdf', $direct->content);
echo $direct->renderQuality, ' ', $direct->contentType, PHP_EOL;
echo $direct->operationId, ' cache hit: ', var_export($direct->cacheHit, true), PHP_EOL;
// Retélécharger un artefact stocké plus tard. Omettez le nom de sortie lorsque
// l'opération n'a produit qu'un seul artefact.
$saved = $client->v2->downloadPerceiveArtifact($direct->operationId, 'pdf');
PerceiveDirectResult porte content, contentType, filename, operationId, objectKey, cacheHit, renderQuality, sourceStatusCode, contentHash et warningsCount. Une ApiException avec le statut 410 signifie que l'artefact stocké n'est plus disponible.
Discover#
Énumère les URL d'un site en HTTP uniquement. Aucun rendu navigateur, c'est donc rapide. Voir la référence discover.
$found = $client->v2->discover('https://example.com', [
'mode' => 'hybrid', // "sitemap" | "crawl" | "hybrid"
'maxUrls' => 200,
'maxDepth' => 3,
'excludePatterns' => ['/tag/'],
'sameDomainOnly' => true,
]);
echo $found->total, ' urls, truncated: ', var_export($found->truncated, true), PHP_EOL;
print_r($found->sources); // par ex. ["sitemap" => 42, "crawl" => 30]
Les options sont mode, maxUrls, maxDepth, includePatterns, excludePatterns, sameDomainOnly et respectRobots.
Lookup#
Lance une recherche web catégorisée et, si vous le souhaitez, rend automatiquement les meilleurs résultats. Voir la référence lookup.
$search = $client->v2->lookup('best static site generators', [
'category' => 'web', // web | news | images | scholar | patents | maps
'numResults' => 10,
'country' => 'us',
'timeFilter' => 'month',
'perceiveTop' => 3, // rend automatiquement les 3 premiers résultats
]);
foreach ($search->results as $hit) {
echo $hit->position, '. ', $hit->title, ' ', $hit->url, PHP_EOL;
echo ' quality ', $hit->perceive?->renderQuality ?? 'not perceived', PHP_EOL;
}
Les options sont category, country, locale, timeFilter, numResults, page, location, autocorrect et perceiveTop.
Distill#
Extraction structurée pilotée par schéma, sur une liste d'URL ou sur un site découvert. Voir la référence distill.
$extraction = $client->v2->distill([
'urls' => ['https://example.com/pricing'],
'schema' => ['plans' => 'list of plan names with monthly prices'],
'cssSchema' => [ // passe CSS gratuite facultative, avant le niveau LLM
'baseSelector' => '.plan-card',
'fields' => [
['name' => 'name', 'type' => 'text', 'selector' => 'h3'],
['name' => 'price', 'type' => 'text', 'selector' => '.price'],
],
],
]);
print_r($extraction->results[0]->data);
echo $extraction->results[0]->extractionTier, PHP_EOL; // css | llm | mixed | none
echo $extraction->results[0]->fieldsFromCss, '/', $extraction->results[0]->fieldsFromLlm, PHP_EOL;
// Ou découvrez d'abord l'ensemble des URL.
$client->v2->distill([
'discoverFrom' => ['url' => 'https://example.com', 'mode' => 'sitemap', 'maxPages' => 10],
'schema' => ['title' => 'page title', 'summary' => 'one-line summary'],
]);
schema est obligatoire, et exactement l'un de urls ou discoverFrom doit être présent. Enfreignez l'une de ces deux règles et le SDK lève une EnconvertException avant l'envoi. Les autres options sont waitFor, waitTimeoutMs, headers, cookies et respectRobots.
Ingest#
Transforme un site entier, ou une pile de documents envoyés, en JSONL découpé et prêt pour le RAG, à travers un seul pipeline. Ingest est toujours asynchrone. Voir la référence ingest.
// Depuis un site.
$job = $client->v2->ingest([
'mode' => 'sitemap', // "urls" (par défaut) | "sitemap" | "crawl"
'url' => 'https://docs.example.com',
'maxPages' => 100,
'chunk' => ['maxWords' => 512, 'sentenceOverlap' => 1],
'webhookUrl' => 'https://my.app/hooks/enconvert',
]);
// Ou depuis des fichiers envoyés : PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT/MD, bureautique hérité et ODF.
$fileJob = $client->v2->ingestFiles(['handbook.pdf', 'notes.docx'], [
'chunk' => ['maxWords' => 512, 'sentenceOverlap' => 1],
]);
// Interroger jusqu'à la fin du traitement.
do {
sleep(5);
$status = $client->v2->getIngestJob($job->jobId);
} while (in_array($status->status, ['queued', 'discovering', 'processing'], true));
if ($status->status === 'completed') {
echo $status->totalChunks, ' chunks: ', $status->outputUrl, PHP_EOL; // JSONL signé
}
mode vaut urls par défaut, ce qui exige un tableau urls non vide et rejette url. Les modes sitemap et crawl exigent une url de départ et rejettent urls. Le SDK applique les deux règles localement. Les autres options sont maxPages, maxDepth, sameDomainOnly, includePatterns, excludePatterns, respectRobots, waitFor, waitTimeoutMs, chunk et webhookUrl.
// Gestion des jobs.
$list = $client->v2->listIngestJobs(['limit' => 20, 'skip' => 0]);
foreach ($list->jobs as $summary) {
echo $summary->jobId, ' ', $summary->status, ' ', $summary->totalChunks, PHP_EOL;
}
$client->v2->cancelIngestJob($job->jobId); // idempotent
// Signature des webhooks.
$secret = $client->v2->getWebhookSecret();
echo $secret->signatureHeader, ' ', $secret->signatureScheme, PHP_EOL;
$client->v2->rotateWebhookSecret(); // les anciennes signatures cessent d'être valides
$client->v2->retryIngestWebhook($job->jobId); // relivrer un callback de fin de traitement
Watch#
Refait le rendu d'une URL à intervalle fixe et vous prévient quand elle change. Voir la référence watch.
$watcher = $client->v2->createWatcher('https://example.com/pricing', [
'frequencyMinutes' => 60, // plancher horaire
'diffMode' => 'auto', // auto | text | structured | tables | metadata
'webhookUrl' => 'https://my.app/hooks/changes',
'notifyEmail' => true,
]);
echo $watcher->watcherId, ' next check ', $watcher->nextCheckAt, PHP_EOL;
$snapshots = $client->v2->getWatcherSnapshots($watcher->watcherId, ['limit' => 10]);
foreach ($snapshots->snapshots as $snap) {
if ($snap->hasChanges) {
echo $snap->checkedAt, ' similarity ', $snap->similarity,
' changes ', $snap->changeCount, PHP_EOL;
}
}
$client->v2->updateWatcher($watcher->watcherId, ['status' => 'paused']);
$client->v2->updateWatcher($watcher->watcherId, ['webhookUrl' => '']); // efface le webhook
$client->v2->deleteWatcher($watcher->watcherId); // suppression logique, idempotente
createWatcher accepte frequencyMinutes, diffMode, trackFields, webhookUrl et notifyEmail. updateWatcher accepte ces cinq options plus status, et exige au moins un champ, sans quoi elle lève une EnconvertException. listWatchers accepte skip et limit.
Options PDF#
Passées via le tableau pdfOptions de convertUrlToPdf, convertDocument, convertToPdf (niveaux de gris uniquement), convertWebsiteToPdf, et de perceive en V2 avec une sortie pdf. Le SDK sérialise les clés camelCase vers le format attendu par l'API, et n'envoie que les clés que vous définissez.
$client->convertUrlToPdf('https://example.com', [
'pdfOptions' => [
'pageSize' => 'A4',
'orientation' => 'landscape',
'margins' => ['top' => 10, 'bottom' => 10, 'left' => 15, 'right' => 15],
'scale' => 0.9,
'header' => ['content' => 'Quarterly Report', 'height' => 15],
'footer' => ['content' => 'Page {{page}} of {{total_pages}}', 'height' => 12],
],
'singlePage' => false,
'saveTo' => 'report.pdf',
]);
| Champ | Type | Description |
|---|---|---|
pageSize |
string |
De A0 à A6, de B0 à B5, Letter, Legal, Tabloid, Ledger. Ignoré lorsque pageWidth et pageHeight sont tous deux définis. |
pageWidth, pageHeight |
float |
Taille de page personnalisée, en millimètres. À définir ensemble. |
orientation |
string |
portrait ou landscape. |
margins |
array |
['top' => ..., 'bottom' => ..., 'left' => ..., 'right' => ...] en millimètres. |
scale |
float |
Échelle de rendu, de 0.1 à 2.0. Sortie paginée uniquement. |
grayscale |
bool |
Post-traite le PDF en niveaux de gris. |
header |
array |
['content' => '<html>', 'height' => 15]. Hauteur en millimètres. |
footer |
array |
Même forme que header. |
Le contenu des en-têtes et pieds de page prend en charge les variables de gabarit {{page}}, {{total_pages}}, {{date}}, {{title}} et {{url}}. La référence complète des paramètres se trouve dans paramètres et options.
Gestion des erreurs#
Tout ce que lève le SDK descend de Enconvert\Exception\EnconvertException : un seul bloc catch peut donc borner toute la surface.
use Enconvert\Exception\{
ApiException, AuthenticationException, EnconvertException, QuotaException, RateLimitException
};
try {
$client->convertUrlToPdf('https://example.com', ['saveTo' => 'page.pdf']);
} catch (AuthenticationException $e) {
error_log('Check ENCONVERT_API_KEY: ' . $e->getMessage());
} catch (RateLimitException $e) {
error_log('Too many requests, back off and retry.');
} catch (QuotaException $e) {
error_log($e->getMessage());
} catch (ApiException $e) {
error_log(sprintf('API error [%d]: %s', $e->getStatusCode(), $e->getMessage()));
} catch (EnconvertException $e) {
error_log('Client-side or transport failure: ' . $e->getMessage());
}
| Classe | Déclenchée sur | Code de statut |
|---|---|---|
AuthenticationException |
Clé API invalide, manquante ou révoquée | réponses 401 et 403 |
QuotaException |
HTTP 402 | 402 |
RateLimitException |
Trop de requêtes | 429 |
ApiException |
Toute autre réponse 4xx ou 5xx | le code réel |
EnconvertException |
Classe de base, et tout échec côté client | aucun |
ApiException::getStatusCode() renvoie le statut numérique ; le message est préfixé par [code]. Une réponse 403 est mappée sur AuthenticationException, dont le getStatusCode() indique 401 : branchez donc sur la classe plutôt que sur le nombre lorsque vous devez distinguer les deux.
EnconvertException est également levée sans aucun aller-retour réseau lorsque le SDK peut établir que la requête est vouée à l'échec : clé API vide, chemin de fichier manquant, extension de fichier non reconnue, paire de conversion non implémentée, appel distill sans schéma ou avec à la fois urls et discoverFrom, incohérence entre le mode ingest et la charge utile, liste ingestFiles vide, appel perceiveDirect qui ne nomme pas exactement une sortie d'artefact, appel updateWatcher sans aucun champ, et tout échec de transport Guzzle (remonté sous la forme HTTP request failed: ...).
La table complète des messages se trouve dans la référence des codes d'erreur.
Récupération des timeouts#
Les conversions de documents volumineux et les pages lentes peuvent dépasser un timeout de reverse proxy même quand la conversion finit par réussir sur le serveur. Le SDK s'en remet tout seul :
- Avant chaque requête de conversion, il génère un identifiant de job hexadécimal de 32 caractères et l'envoie comme
job_iddans le corps ou dans le formulaire multipart. - Si cette requête revient en 5xx, le SDK cesse de lever une erreur et se met à interroger
GET /v1/convert/status/{job_id}toutes les 3 secondes. - Dès que le job affiche
success, le SDK renvoie le résultat. S'il affichefailed, il lève uneApiExceptionportant le message d'erreur du serveur. - Un
404pendant l'interrogation signifie « pas encore enregistré » et l'interrogation continue. Le délai maximal est de 5 minutes, au-delà duquel le SDK lèveApiException(504, 'Conversion timed out').
Vous n'avez aucun code à écrire pour cela. Deux exceptions volontaires : les soumissions de lots de site entier (convertWebsiteToPdf, convertWebsiteToScreenshot) n'ont pas de ligne de job, si bien qu'un 5xx y remonte immédiatement, et les méthodes V2 n'utilisent pas du tout le polling de job.
Les réponses réussies qui omettent job_id reçoivent l'identifiant généré par le client, si bien que $result->jobId reste toujours utilisable avec getJobStatus().
Configuration#
use Enconvert\Client;
$client = new Client(getenv('ENCONVERT_API_KEY'), [
'timeout' => 300, // secondes
'base_url' => 'https://api.enconvert.com', // à remplacer pour une passerelle auto-hébergée
]);
| Option | Type | Par défaut | Description |
|---|---|---|---|
$apiKey (premier argument) |
string |
obligatoire | Clé API privée (sk_live_...). Une chaîne vide lève une EnconvertException. |
timeout |
int\|float |
300 |
Timeout de requête en secondes, l'unité idiomatique de Guzzle. S'applique à chaque requête HTTP émise par le client. Le délai d'interrogation des jobs est distinct et fixé à 300 secondes. |
base_url |
string |
https://api.enconvert.com |
Hôte de l'API. Les barres obliques finales sont supprimées. |
Notez que la clé d'option est en snake_case (base_url) alors que toutes les autres options de requête du SDK sont en camelCase. Les requêtes sont authentifiées par un en-tête X-API-Key ; les téléchargements déclenchés par saveTo vont directement au stockage et n'envoient volontairement aucune clé, puisque l'URL est déjà signée.
Structure du résultat#
Chaque conversion de fichier unique renvoie un Enconvert\Model\ConversionResult doté de propriétés publiques en lecture seule :
final class ConversionResult
{
public readonly string $presignedUrl; // URL de téléchargement signée
public readonly string $objectKey; // clé de l'objet de stockage
public readonly string $filename; // nom de fichier côté serveur
public readonly int|float|null $fileSize; // octets
public readonly int|float|null $conversionTimeSeconds;
public readonly ?string $jobId; // l'id utilisé pour la récupération des timeouts
}
Les URL présignées expirent au bout de 15 minutes et peuvent être utilisées plusieurs fois avant cela. Pour un accès permanent, téléchargez les octets (passez saveTo, ou récupérez l'URL vous-même) et stockez-les dans votre propre bucket.
Les autres types de résultats suivent le même schéma : JobStatus, BatchSubmission, BatchStatus avec ses BatchItem[], et, sous Enconvert\Model\V2, PerceiveResult, PerceiveDirectResult, PerceiveBatchResult, OutputArtifact, DiscoverResult, LookupResult, LookupItem, DistillResult, DistillItem, IngestJob, IngestJobList, IngestJobSummary, Watcher, WatcherList, WatcherSummary, WatcherSnapshot, WatcherSnapshotList, WebhookSecret, WebhookRetryResult et Tokens. Les champs arrivent en snake_case sur le réseau et sont mappés vers des propriétés camelCase ; les charges utiles fournies par l'utilisateur, comme les schémas, les données extraites, les champs suivis et les entrées de diff, passent sans modification.
Source et problèmes#
- Packagist : enconvert/enconvert-php
- GitHub : conversionapi/php-sdk · ouvrir un ticket
- Licence : MIT
- Autres clients : tous les SDK · endpoints REST
Questions fréquentes#
Comment convertir des fichiers en PHP avec Composer ?#
Exécutez composer require enconvert/enconvert-php, construisez new Enconvert\Client($apiKey), et appelez une méthode comme convertUrlToPdf, convertImage, convertDocument, convertToPdf ou convertToMarkdown. Ajoutez saveTo à n'importe laquelle d'entre elles et le SDK écrit pour vous les octets convertis vers ce chemin local, en créant les répertoires parents au passage.
Comment convertir un DOCX en PDF en PHP ?#
Appelez $client->convertDocument('report.docx', ['saveTo' => 'report.pdf']). Le format de sortie vaut pdf par défaut, aucun outputFormat n'est donc nécessaire. Le format d'entrée est lu depuis l'extension du fichier, et le SDK vérifie la paire doc-to-pdf contre sa table des 43 conversions implémentées avant d'envoyer quoi que ce soit : une paire non prise en charge échoue donc instantanément, avec un message listant ce qui est valide pour cette entrée.
Comment convertir une URL en PDF en PHP ?#
Appelez $client->convertUrlToPdf('https://example.com', ['saveTo' => 'page.pdf']). Par défaut, la page est rendue en une seule page continue, dans une fenêtre d'affichage de 1920x1080, avec le chargement des médias et le défilement activés. Passez singlePage à false et fournissez pdfOptions lorsque vous voulez une vraie pagination avec une taille de page, des marges, des en-têtes et des pieds de page.
Comment récupérer une page web en PHP et obtenir du Markdown propre ?#
Utilisez l'espace de noms V2 : $client->v2->perceive($url, ['outputs' => ['markdown', 'structured']]). Il rend la page dans un vrai navigateur, les sites très chargés en JavaScript fonctionnent donc, et il renvoie une URL Markdown signée plus des données structurées en ligne. Vérifiez renderQuality sur le résultat avant de faire confiance au contenu : un score bas avec des deductions renseignées signifie que le rendu est tombé sur une page anti-bot, un mur de connexion ou une coquille vide. Pour un chemin plus léger et ponctuel, sans les fonctionnalités V2, convertUrlToMarkdown fonctionne aussi.
Comment convertir du HEIC en WebP en PHP ?#
Appelez $client->convertImage('photo.heic', ['outputFormat' => 'webp', 'saveTo' => 'photo.webp']). Toute paire parmi jpeg, png, svg, heic et webp est prise en charge, ainsi que la rastérisation pdf vers jpeg. Vous pouvez aussi passer des octets bruts sous la forme ['data' => $bytes, 'filename' => 'photo.heic'], où c'est le nom de fichier qui détermine le format d'entrée et le type MIME.
Le SDK PHP EnConvert fonctionne-t-il avec Laravel ou Symfony ?#
Oui. Le package est une simple bibliothèque PSR-4 avec Guzzle 7 pour seule dépendance et aucun couplage à un framework : il s'intègre donc tel quel dans Laravel, Symfony, WordPress ou un script nu. Enregistrez Enconvert\Client dans votre conteneur avec la clé issue de votre configuration d'environnement, et injectez-le partout où vous en avez besoin.
Que se passe-t-il quand une conversion dure plus longtemps que le timeout HTTP ?#
Le SDK s'en remet tout seul. Il envoie un job_id généré côté client avec chaque requête de conversion, et si la requête renvoie un 5xx il interroge silencieusement GET /v1/convert/status/{job_id} toutes les 3 secondes pendant 5 minutes au maximum, en renvoyant le résultat dès que le job enregistre success. Passé ce délai, il lève ApiException(504, 'Conversion timed out'). Les soumissions de lots de site entier ne sont pas concernées, puisqu'elles n'ont pas de ligne de job.
Combien de temps l'URL de téléchargement présignée est-elle valide ?#
Les URL de téléchargement présignées expirent au bout de 15 minutes et peuvent être utilisées plusieurs fois avant cela. Les URL d'artefacts V2 portent un expiresIn de 900 secondes pour la même raison, et getPerceiveOperation($operationId) les resigne à partir des clés d'objets stockées, sans refaire le rendu de la page. Pour quoi que ce soit de permanent, téléchargez les octets et conservez-les dans votre propre stockage.
Quelle version de PHP le SDK exige-t-il ?#
PHP 8.1 ou plus récent. Le SDK utilise partout des propriétés en lecture seule, des types union façon énumération, des arguments nommés et des expressions match : les versions 8.0 et antérieures ne sont donc pas prises en charge. Sa seule dépendance à l'exécution est guzzlehttp/guzzle ^7.8.