承接 enconvert/enconvert-php 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

enconvert/enconvert-php

Composer 安装命令:

composer require enconvert/enconvert-php

包简介

PHP SDK for the Enconvert file conversion API

README 文档

README

PHP SDK for the Enconvert file conversion API.

Convert URLs to PDFs, capture screenshots, extract Markdown, crawl whole websites, transform images, and convert documents — all with a single API call. PHP 8.1+.

Install

composer require enconvert/enconvert-php

Quick Start

use Enconvert\Client;

$client = new Client('sk_...');

URL to PDF

$result = $client->convertUrlToPdf('https://example.com', [
    'saveTo' => 'page.pdf',
]);
echo $result->presignedUrl;

URL to Screenshot

$result = $client->convertUrlToScreenshot('https://example.com', [
    'viewportWidth' => 1440,
    'saveTo' => 'screenshot.png',
]);

URL to Markdown

Extract clean GitHub-Flavored Markdown from any URL — strips nav/footer/ads/scripts, keeps the main article content, and adds YAML frontmatter (title, description, url, links, images).

$result = $client->convertUrlToMarkdown('https://example.com/article', [
    'saveTo' => 'article.md',
]);

Website to PDF / Screenshot (whole-site batch)

Discover every page of a website (via sitemap, or full crawl on Pro/Business plans), convert each one in the background, and receive a single ZIP. Requires a private API key with crawl access.

$batch = $client->convertWebsiteToPdf('https://example.com', [
    'crawlMode' => 'sitemap',            // "auto" (default) | "sitemap" | "full"
    'excludePatterns' => ['/blog/tag/'], // full crawl mode only
]);
echo $batch->batchId, ' ', $batch->urlCount, ' ', $batch->discoveryMethod;

// Block until done and save the ZIP:
$status = $client->waitForBatch($batch->batchId, ['saveTo' => 'site.zip']);
echo $status->completed, ' of ', $status->total, ' pages converted';

// Or poll yourself:
$s = $client->getBatchStatus($batch->batchId);
if ($s->status !== 'processing') {
    echo $s->zipDownloadUrl;
}

convertWebsiteToScreenshot works the same way and produces a ZIP of PNGs.

Image Conversion

$result = $client->convertImage('photo.heic', [
    'outputFormat' => 'webp',
    'saveTo' => 'photo.webp',
]);

Any pair among jpeg, png, svg, heic, webp — plus PDF rasterization:

$client->convertImage('scan.pdf', ['outputFormat' => 'jpeg', 'saveTo' => 'scan.jpeg']);

Raw bytes are also accepted, wrapped with an explicit filename (needed to resolve the input format and MIME type):

$client->convertImage(
    ['data' => $rawBytes, 'filename' => 'photo.heic'],
    ['outputFormat' => 'webp', 'saveTo' => 'photo.webp']
);

Document Conversion

$client->convertDocument('report.docx', ['saveTo' => 'report.pdf']);
$client->convertDocument('data.json', ['outputFormat' => 'yaml', 'saveTo' => 'data.yaml']);
$client->convertDocument('notes.md', ['outputFormat' => 'html', 'saveTo' => 'notes.html']);

Supported inputs: doc/docx, xls/xlsx, ppt/pptx, odt, ods, odp, ots, pages, numbers, epub, html, markdown, csv, json, xml, yaml, toml

The SDK validates every {input}-to-{output} pair against the conversions the API actually implements and throws immediately — with the list of valid outputs for that input — instead of sending a doomed request. Introspect programmatically:

use Enconvert\Formats;

Formats::validOutputsFor('json'); // ["csv", "toml", "xml", "yaml"]
Formats::validOutputsFor('pdf');  // ["jpeg"]
Formats::IMPLEMENTED_CONVERSIONS; // the full set of 44 "{input}-to-{output}" pairs

Supported conversions

Input Outputs
json csv, toml, xml, yaml
xml csv, json
yaml json
csv json, xml
toml json
markdown html, pdf
html pdf
doc, excel, ppt, odt, ods, odp, ots, pages, numbers, epub pdf
jpeg, png, svg, heic, webp each other (all 20 pairs)
pdf jpeg

Job Status (async polling)

$status = $client->getJobStatus('job_abc123');
if ($status->status === 'success') {
    echo $status->presignedUrl;
}

PDF Options

$result = $client->convertUrlToPdf('https://example.com', [
    'pdfOptions' => [
        'pageSize' => 'A4',              // or custom dimensions via pageWidth + pageHeight
        'orientation' => 'landscape',
        'margins' => ['top' => 10, 'bottom' => 10, 'left' => 15, 'right' => 15],
        'header' => ['content' => 'Quarterly Report', 'height' => 15],
        'footer' => ['content' => 'Confidential', 'height' => 12],
    ],
    'saveTo' => 'report.pdf',
]);

Authenticated Pages (plan-gated)

All URL and website conversions accept HTTP Basic Auth, cookies, and custom headers for pages behind a login:

$client->convertUrlToPdf('https://internal.example.com/report', [
    'auth' => ['username' => 'user', 'password' => 'pass'],
    // or cookies / headers:
    'cookies' => [['name' => 'session', 'value' => 'abc123', 'domain' => 'internal.example.com']],
    'headers' => ['X-Tenant' => 'acme'],
    'saveTo' => 'report.pdf',
]);

Do not combine auth with an Authorization header — the API rejects the conflict.

Error Handling

use Enconvert\Client;
use Enconvert\Exception\ApiException;
use Enconvert\Exception\AuthenticationException;
use Enconvert\Exception\RateLimitException;

try {
    $client->convertUrlToPdf('https://example.com');
} catch (AuthenticationException $e) {
    echo 'Invalid API key';
} catch (RateLimitException $e) {
    echo 'Too many requests — slow down';
} catch (ApiException $e) {
    echo "API error [{$e->getStatusCode()}]: {$e->getMessage()}";
}

AuthenticationException, QuotaException, and RateLimitException all extend ApiException, which extends the base EnconvertException.

Configuration

$client = new Client('sk_...', [
    'timeout' => 300,   // seconds, default (idiomatic PHP/Guzzle unit; node-sdk uses milliseconds)
    'base_url' => 'https://api.enconvert.com', // override, e.g. for a self-hosted gateway
]);

V2 API ($client->v2)

The V2 namespace turns web pages into agent-ready data: render, search, extract, ingest, and monitor. All V2 endpoints require a private API key and are plan-gated — a disabled feature or exhausted monthly quota throws QuotaException (HTTP 402). $client->v2 is a public property; $client->v2() is an equivalent accessor method.

Perceive — render a URL into artifacts

$op = $client->v2->perceive('https://example.com', [
    'outputs' => ['markdown', 'screenshot', 'structured'],
    'extract' => ['tables', 'metadata'],
]);
echo $op->outputs['markdown']->url;   // 15-min signed URL
print_r($op->structured);

// Re-sign artifact URLs later:
$again = $client->v2->getPerceiveOperation($op->operationId);

// Batch (<=10 URLs runs inline; larger returns "queued" — poll):
$batch = $client->v2->perceiveBatch(['https://a.com', 'https://b.com'], [
    'outputs' => ['markdown'],
    'outputMode' => 'zip',
]);
$done = $client->v2->getPerceiveBatch($batch->jobId);

Discover — enumerate a site's URLs (no rendering)

$found = $client->v2->discover('https://example.com', [
    'mode' => 'hybrid',              // "sitemap" | "crawl" | "hybrid"
    'maxUrls' => 200,
    'excludePatterns' => ['/tag/'],
]);
echo $found->total;
print_r($found->urls);

Lookup — web search with optional auto-perceive

$search = $client->v2->lookup('best static site generators', [
    'category' => 'web',             // web | news | images | scholar | patents | maps
    'numResults' => 10,
    'perceiveTop' => 3,              // auto-render top 3 results (uses perceive quota)
]);
foreach ($search->results as $hit) {
    echo $hit->title, ' ', $hit->url, "\n";
    if ($hit->perceive !== null) {
        print_r($hit->perceive->outputs);
    }
}

Distill — schema-driven structured extraction

$extraction = $client->v2->distill([
    'urls' => ['https://example.com/pricing'],
    'schema' => ['plans' => 'list of plan names with monthly prices'],
    'cssSchema' => [                 // optional free CSS pass before the LLM tier
        '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;

// Or discover-then-distill:
$client->v2->distill([
    'discoverFrom' => ['url' => 'https://example.com', 'mode' => 'sitemap', 'maxPages' => 10],
    'schema' => ['title' => 'page title', 'summary' => 'one-line summary'],
]);

Ingest — site to RAG-ready JSONL (always async)

$job = $client->v2->ingest([
    'mode' => 'sitemap',
    'url' => 'https://docs.example.com',
    'maxPages' => 100,
    'chunk' => ['maxWords' => 512, 'sentenceOverlap' => 1],
    'webhookUrl' => 'https://my.app/hooks/enconvert',
]);

$status = $client->v2->getIngestJob($job->jobId);   // poll
if ($status->status === 'completed') {
    echo $status->outputUrl; // JSONL
}

$client->v2->listIngestJobs(['limit' => 20]);
$client->v2->cancelIngestJob($job->jobId);           // idempotent

// Webhook signing (HMAC):
$secretInfo = $client->v2->getWebhookSecret();
$client->v2->rotateWebhookSecret();                  // invalidates old secret
$client->v2->retryIngestWebhook($job->jobId);        // re-deliver

Watch — recurring change monitoring

$watcher = $client->v2->createWatcher('https://example.com/pricing', [
    'frequencyMinutes' => 60,        // hourly floor
    'diffMode' => 'auto',            // auto | text | structured | tables | metadata
    'webhookUrl' => 'https://my.app/hooks/changes',
    'notifyEmail' => true,
]);

$client->v2->listWatchers();
$client->v2->getWatcher($watcher->watcherId);
$client->v2->getWatcherSnapshots($watcher->watcherId, ['limit' => 10]);
$client->v2->updateWatcher($watcher->watcherId, ['status' => 'paused']);
$client->v2->updateWatcher($watcher->watcherId, ['webhookUrl' => '']); // clears webhook
$client->v2->deleteWatcher($watcher->watcherId);      // soft-delete, idempotent

V2 error handling

use Enconvert\Exception\QuotaException;

try {
    $client->v2->ingest(['urls' => ['https://example.com']]);
} catch (QuotaException $e) {
    echo 'Upgrade plan or wait for quota reset';
}

Get an API Key

Sign up at enconvert.com to get your API key.

License

MIT

enconvert/enconvert-php 适用场景与选型建议

enconvert/enconvert-php 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 07 月 15 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「api」 「pdf」 「sdk」 「conversion」 「screenshot」 「html-to-pdf」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 enconvert/enconvert-php 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 enconvert/enconvert-php 我们能提供哪些服务?
定制开发 / 二次开发

基于 enconvert/enconvert-php 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 8
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-07-15