funstaff/tika
A Laravel wrapper for Apache Tika that extracts text and metadata from PDFs, Word documents, spreadsheets, and other file formats. Provides a simple, fluent API for parsing uploaded documents in your PHP applications, with support for Laravel's filesystem and configuration conventions.
funstaff/tika is a thin PHP client around an Apache Tika Server instance. It does not extract text itself — Tika is a Java application, so the first thing to understand is that you need two moving parts: the PHP wrapper in your Laravel app, and a running tika-server process reachable over HTTP.
Install the package
composer require funstaff/tika
Publish and inspect the config. This is the first place to look, since the wrapper is almost entirely configuration + HTTP calls.
php artisan vendor:publish --provider="Funstaff\Tika\TikaServiceProvider"
You are looking for the server endpoint (typically http://localhost:9998), a default timeout, and any endpoint paths (/tika, /meta, /rmeta).
Run Tika Server. Download tika-server-standard.jar from Apache and start it beside your app:
java -jar tika-server-standard.jar --port 9998
Put the URL in .env (TIKA_SERVER=http://127.0.0.1:9998) and make sure your config file reads from env().
First use case: extract text from an uploaded PDF.
use Funstaff\Tika\Tika; // adjust to the actual class/facade name
$text = app(Tika::class)->text($request->file('document')->getRealPath());
If you get connection refused, the wrapper is fine — your Tika server isn't running or the URL/port is wrong. Verify independently with curl -T file.pdf http://localhost:9998/tika before blaming the package.
Wrap extraction in a queued job. Tika extraction is I/O-bound and can take seconds for large PDFs or scanned documents. Never do it inline in a request that also needs to return quickly.
class ExtractDocumentText implements ShouldQueue
{
public function __construct(public int $documentId) {}
public function handle(Tika $tika): void
{
$doc = Document::findOrFail($this->documentId);
$doc->update([
'text' => $tika->text(Storage::path($doc->path)),
]);
}
}
Store the extracted text, not the file path alone. Tika results are not cheap to reproduce. Persist text (and metadata as JSON) on the model so search, previews, and exports don't re-hit Tika.
Metadata for SEO and filtering. Tika's /meta endpoint returns author, title, page count, content type, etc. A common pattern is to fill a metadata JSON column and surface title/author in an admin UI or use page_count to gate features.
Feed Laravel Scout. After extraction, push to a search index. Combine with searchable() on the model or dispatch an indexing job after text is saved. This is one of the highest-value integrations for a Tika wrapper.
Support multiple formats through one service. DOCX, XLSX, PPTX, PDF, HTML, and even some images (via OCR if Tika is configured with Tesseract) all flow through the same call. Build a DocumentExtractor service that checks getMimeType() first and decides whether to call Tika, skip, or fall back.
Validate and normalize before sending. Reject files above a size threshold and against an allowed MIME list in a FormRequest before the job runs. Tika will happily accept a 200MB file and tie up the server.
Interface the wrapper behind your own contract. Because this package has low stars and an unverified repository, define interface TextExtractor { public function text(string $path): string; } and bind a TikaExtractor implementation. Swapping to direct Guzzle calls or another wrapper later becomes a one-line change.
The Java dependency is the biggest friction point. Any "package doesn't work" report usually means the server isn't running, is on the wrong port, or isn't reachable from the container. In Docker, the Tika server needs its own service and a healthcheck.
Timeouts will bite you. Set an explicit HTTP timeout in the config (e.g. 30s) and a job $timeout slightly higher. Without it, a hung Tika call can exhaust PHP workers. On timeouts, retry with backoff and a tries limit.
Handle failures explicitly. The wrapper may throw on connection errors or return empty strings on unsupported formats. Catch and record extraction_failed on the record so you can retry or report. Don't let one bad file block a batch.
Trailing slashes and base URLs. Many endpoint mismatches are caused by http://host:9998/ vs http://host:9998. Normalize in config.
Tika Server is memory-hungry. Give the JVM -Xmx headroom, and watch container limits. For large PDFs, extraction can spike. Consider tika-server with --spawnChild for isolation.
Security: it's an SSRF and DoS surface if misused. Never pass user-supplied URLs into Tika without an allowlist, enforce upload size limits at the request layer, and run the Tika server on an internal network only.
Version pinning. Given the low star count and unknown repository, pin an exact version in composer.json and read the source (vendor/funstaff/tika/src) — it's small enough to audit in ten minutes. If it hasn't been updated for current Laravel versions, be prepared to fork or replace with ~50 lines of Guzzle.
Debugging checklist: curl http://localhost:9998/tika for a health check → curl -T file.pdf http://localhost:9998/tika for a raw extraction → then compare with the PHP call. Add a Log::debug of the endpoint and response time in a middleware or in your TikaExtractor wrapper.
Extension point: since the wrapper is thin, the cleanest customization is to bypass its high-level method and hit the endpoint directly via Http::withBody(...). This also gives you control over headers like Accept: text/plain vs application/json for metadata.
How can I help you explore Laravel packages today?