* * Ablauf: * 1. SMILES → MD5-Hash → sdf/{hash}.sdf prüfen * 2. Vorhanden → direkt ausliefern * 3. Nicht vorhanden → PubChem anfragen → speichern → ausliefern * 4. PubChem liefert kein 3D → JSON-Fehler zurückgeben */ header('Content-Type: text/plain; charset=utf-8'); header('Access-Control-Allow-Origin: *'); header('Cache-Control: public, max-age=86400'); // ---- Eingabe validieren ---- $smiles = isset($_GET['smiles']) ? trim($_GET['smiles']) : ''; if ($smiles === '') { http_response_code(400); echo json_encode(['error' => 'Parameter "smiles" fehlt']); exit; } // ---- Cache-Verzeichnis ---- $cacheDir = __DIR__ . '/sdf'; if (!is_dir($cacheDir)) { if (!mkdir($cacheDir, 0755, true)) { http_response_code(500); echo json_encode(['error' => 'Cache-Verzeichnis konnte nicht erstellt werden']); exit; } } // ---- Hash und Pfad ---- $hash = md5($smiles); $sdfPath = $cacheDir . '/' . $hash . '.sdf'; // ---- Cache-Treffer ---- if (file_exists($sdfPath)) { readfile($sdfPath); exit; } // ---- PubChem anfragen ---- $url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/smiles/' . rawurlencode($smiles) . '/SDF?record_type=3d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 10, 'ignore_errors' => true, 'header' => 'User-Agent: MolViewer/1.2 (php-proxy)' ] ]); $sdf = @file_get_contents($url, false, $ctx); // ---- Antwort prüfen ---- if ($sdf === false || $sdf === '') { http_response_code(502); echo json_encode(['error' => 'PubChem nicht erreichbar']); exit; } // PubChem gibt bei Fehler XML/JSON zurück, kein SDF if (strpos($sdf, 'V2000') === false && strpos($sdf, 'V3000') === false) { http_response_code(404); echo json_encode(['error' => '3D-Koordinaten nicht verfügbar', 'smiles' => $smiles]); exit; } // ---- Speichern und ausliefern ---- file_put_contents($sdfPath, $sdf); echo $sdf;