PHP-Klassen in Tool-Handlern
Welche Vendor- und Framework-Klassen du in eigenen Handlern nutzen darfst — und welche nicht.
In Tool-Handlern ('handler' => function (...) { ... }) hast du vollen PHP-Zugriff. Das ist mächtig — und braucht Leitplanken, damit dein Workspace nicht bricht, sobald sich die Plattform-Version ändert.
Grundsatz
- Native PHP-Funktionen und das PHP-Standardlib sind immer erlaubt (
array_*,str_*,preg_*,json_*,DateTime,DateTimeImmutable,SplStack,RecursiveDirectoryIteratorusw.) - Klassen aus der Liste unten sind freigegeben — die Plattform garantiert ihre Verfügbarkeit über Updates hinweg
- Alles andere — egal ob aus
vendor/oder dem Framework — kann jederzeit wegfallen oder sich verändern. Nutzung auf eigenes Risiko
Wenn du eine Klasse brauchst, die nicht in der Liste steht: frage den Betreiber, ob sie aufgenommen werden kann. Das hält die Plattform pflegbar.
Freigegebene Klassen
HTTP-Calls
Tool-Handler dürfen KEINE eigenen HTTP-Clients instanziieren — weder
Cake\Http\Client, GuzzleHttp\Client noch curl_*-Funktionen. Sie sind
vom Sandbox-Validator beim Sync blockiert. Der Grund: zentrale Auth-,
Retry-, Timeout-, Logging- und Rate-Limit-Konfiguration über die Plattform.
Statt dessen: API-Tools verwenden. Die externe API in apis.php registrieren,
das Tool referenziert sie per Name. Die Plattform baut + sendet den Request,
das Handler bekommt das geparste JSON-Response zurück.
// apis.php
return [
'apis.example' => [
'base_url' => 'https://api.example.com',
'headers' => ['Authorization' => 'Bearer ...'],
],
];
// tools/example/getFoo.php
return [
'tools' => [
'getFoo' => [
'api' => 'example',
'endpoint' => 'foo',
'method' => 'GET',
'query' => ['id' => '{{args.id}}'],
// Optional: handler nach API-Call zum Postprocessing
'handler' => function (array $results, array $args, array $ctx): array {
// $results enthaelt die geparste API-Antwort
return ['summary' => $results['name'] ?? 'unknown'];
},
],
],
];
Vollständige API-Tool-Doku: Tools über apis.php definieren.
Zeit & Datum
| Klasse | Zweck |
|---|---|
Cake\I18n\FrozenTime |
Zeitstempel mit Zeitzonen |
Cake\I18n\FrozenDate |
reine Datums-Werte |
DateTime, DateTimeImmutable, DateInterval, DateTimeZone |
PHP-Standard |
Caching
| Klasse | Zweck |
|---|---|
Cake\Cache\Cache |
Lese- und Schreibzugriff auf den (vom Betreiber konfigurierten) Cache |
Beispiel:
$value = \Cake\Cache\Cache::remember('mykey', function () use ($args) {
return expensiveLookup($args);
}, 'short');
PDF-Verarbeitung
| Klasse | Zweck |
|---|---|
Smalot\PdfParser\Parser |
Text aus PDFs extrahieren |
Plattform-eigene Helfer
| Klasse | Zweck |
|---|---|
App\Tooling\KpiTimeRanges |
Standardisierte Zeiträume für KPI-Tools |
App\Tooling\PortalAutomationTools |
Browser-/Portal-Automation-Helfer |
App\Tooling\PortalChain |
Portal-Workflow-Verkettung |
App\Service\AnthropicService |
Helper für direkte Claude-Calls aus Tool-Handlern |
Diese Klassen sind teil der Plattform und können sich versionieren — Änderungen werden vom Betreiber kommuniziert.
AnthropicService — Claude aus einem Tool-Handler aufrufen
Wenn dein Tool intern eine LLM-Antwort braucht (Klassifikation, JSON- Extraktion, Reformulierung), nutze diesen Helper.
Voraussetzung in apis.php:
return [
'apis.anthropic' => [
'api_key' => 'sk-ant-...',
'model' => 'claude-haiku-4-5-20251001', // optional, Default haiku
],
];
Im Tool-Handler:
'handler' => function (array $results, array $args, array $ctx): array {
$svc = \App\Service\AnthropicService::fromTenantConfig($ctx['config']);
// Positional args, NICHT named args verwenden — der Sandbox-Validator
// matcht 'system:' faelschlich als Aufruf der system()-PHP-Funktion
// (die er blockt) und lehnt den Sync ab.
$response = $svc->message(
$args['email_text'],
'Klassifiziere die Email als JSON: {kategorie, dringlichkeit}.',
['max_tokens' => 400, 'temperature' => 0.2],
);
// $response = ['success' => true, 'response' => '...JSON-text...', 'usage' => [...]]
return [
'classification' => json_decode($response['response'], true),
];
},
So müssen Secrets nicht im Tool-File stehen — der Key lebt zentral in
apis.anthropic.api_key.
Nicht freigegeben (typische Fragen)
| Klasse | Warum nicht |
|---|---|
Cake\Core\Configure |
Globale Konfiguration und Secrets — du bekommst alles, was du brauchst, über $ctx und apis.php |
Cake\ORM\TableRegistry, *Table |
Direkte DB-Zugriffe auf Plattform-Tabellen vermeiden — nutze Tools, die für deinen Use-Case gebaut sind, oder Supabase als eigene DB |
Cake\Mailer\Mailer |
Sende Mails über deine eigene Transactional-Mail-API als Tool |
Webklex\PHPIMAP\* |
IMAP-Zugriff sollte über vordefinierte Plattform-Tools laufen |
Wenn dein Use-Case einen dieser Bereiche braucht: das richtige Werkzeug ist meistens ein dediziertes Tool, das der Betreiber für dich baut/freigibt — nicht der direkte Klassenzugriff.
Verboten
Diese Funktionen / Patterns dürfen in Handlern nicht verwendet werden:
- Prozesse starten:
shell_exec,exec,system,passthru,proc_open,popen - Code ausführen:
eval,assert(string),create_function - Reflection auf Plattform-Code:
ReflectionClassauf Klassen unterApp\… - Unsicheres Deserialisieren:
unserializemit User-Input - Schreiben außerhalb erlaubter Pfade:
file_put_contents,fopen,mkdiretc. mit Pfaden außerhalb vontmp/oderwebroot/uploads/
Tools, die diese Muster enthalten, werden beim tm sync abgewiesen.
Standardlib ist genug für 80% der Fälle
Bevor du nach einer Vendor-Klasse suchst: prüfe, ob die PHP-Standardlibrary reicht.
- Strings:
str_replace,preg_match,mb_strtolower,sprintf - Arrays:
array_map,array_filter,array_reduce,usort - JSON:
json_encode,json_decode - Hashing:
md5,sha1,hash_hmac,password_hash - Datums-Arithmetik:
DateTimeImmutable::modify('+7 days') - CSV:
fputcsv,fgetcsv - URLs:
parse_url,http_build_query,urlencode
Wenn du eine neue Klasse brauchst
- Prüfe, ob sich dein Use-Case mit Standardlib oder freigegebenen Klassen lösen lässt
- Falls nicht, frage den Betreiber: welche Klasse, welcher Zweck, welcher Tool-Kontext
- Wird die Klasse aufgenommen, erscheint sie in dieser Liste
- Bis dahin: das Feature kann auf Plattform-Updates fragil reagieren — nicht in produktiven Tools verwenden